• 前言

    环境搭建好之后,就可以上手opencv的一些基本功能了。它不仅是一个计算机视觉库,同时也是一个非常强大的图像处理库,可以完成图像处理和图像识别。

1.视频抽帧转图像

  • 这是进行训练模型的第一步——样本处理
    示例代码:
# -*- coding: UTF-8 -*-
import cv2
import os
#待提取视频的路径
video_path=r"./neg.mp4"
#生成图片的路径
img_path=r'./neg_images'

 
#cv2.VideoCapture可以提取视频的第一帧,返回两个值:
#第一个是bool值,表示有没有提取到;第二个是对应的帧
vidcap = cv2.VideoCapture(video_path)
(cap,frame)= vidcap.read()
 
if cap==False:
	print('cannot open video file')
count = 0
 
#将读取的帧对应的图片按顺序重命名为000000.jpg六位整数的格式,并写入img_path路径
#因为相邻帧可能过于相似,可以每隔几帧取一帧,由for循环完成
while cap:
	cv2.imwrite(os.path.join(img_path,'%.6d.jpg'%count),frame)
	print('%.6d.jpg'%count)
	count += 1
	for i in range(10):
		(cap,frame)= vidcap.read()

2.对图像批量旋转

  • 这一操作不仅可以把正样本旋转到你期望的方向,同样可以用来增强负样本数据,比如将负样本旋转一定角度加入训练集中。
    示例代码:
import os
import cv2
from glob import glob
import numpy as np

cnt =0

def rotate_bound(image, angle):
    # grab the dimensions of the image and then determine the
    # center
    (h, w) = image.shape[:2]
    (cX, cY) = (w // 2, h // 2)
 
    # grab the rotation matrix (applying the negative of the
    # angle to rotate clockwise), then grab the sine and cosine
    # (i.e., the rotation components of the matrix)
    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
 
    # compute the new bounding dimensions of the image
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))
 
    # adjust the rotation matrix to take into account translation
    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY
 
    # perform the actual rotation and return the image
    return cv2.warpAffine(image, M, (nW, nH))

for fn in glob('./neg_images/*.jpg'):
    img = cv2.imread(fn)
    ro = rotate_bound(img,90)
    cv2.imwrite(os.path.join('./flip_neg','%.6d.jpg'%cnt),ro)
    cnt += 1

3.切割图像

  • 如果样本在图像中的位置比较集中,可以对图像切割处理,只保留正样本的区域,提高训练精度。
    示例代码:
# -*-coding:utf-8-*-
from PIL import Image
from glob import glob
import os
import numpy as np

cnt = 0
for fn in glob('./pos/*.jpg'):
    im = Image.open(fn)
    # 图片的宽度和高度
    img_size = im.size
    print("图片宽度和高度分别是{}".format(img_size))
    '''
    裁剪:传入一个元组作为参数
    元组里的元素分别是:(距离图片左边界距离x, 距离图片上边界距离y,距离图片左边界距离+裁剪框宽度x+w,距离图片上边界距离+裁剪框高度y+h)
    '''
    # 截取图片中一块宽和高都是250的
    x = 150
    y = 150
    w = 650
    h = 650
    region = im.crop((x, y, x+w, y+h))
    region.save(os.path.join('./cut_canny/','%.6d.jpg'%cnt))
    cnt += 1

4.形状检测

  • 这是一个opencv自带的类,官方教程也很详细,在此就不赘述。

5. 其他的一些常用方法

1. 图像二值化

import cv2 as cv
import numpy as np

#全局阈值
def threshold_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)  #把输入图像灰度化
    #直接阈值化是对输入的单通道矩阵逐像素进行阈值分割。
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
    print("threshold value %s"%ret)
    cv.namedWindow("binary0", cv.WINDOW_NORMAL)
    cv.imshow("binary0", binary)

#局部阈值
def local_threshold(image):
    gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)  #把输入图像灰度化
    #自适应阈值化能够根据图像不同区域亮度分布,改变阈值
    binary =  cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY, 25, 10)
    cv.namedWindow("binary1", cv.WINDOW_NORMAL)
    cv.imshow("binary1", binary)

#用户自己计算阈值
def custom_threshold(image):
    gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)  #把输入图像灰度化
    h, w =gray.shape[:2]
    m = np.reshape(gray, [1,w*h])
    mean = m.sum()/(w*h)
    print("mean:",mean)
    ret, binary =  cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
    cv.namedWindow("binary2", cv.WINDOW_NORMAL)
    cv.imshow("binary2", binary)

src = cv.imread('E:/imageload/kobe.jpg')
cv.namedWindow('input_image', cv.WINDOW_NORMAL) #设置为WINDOW_NORMAL可以任意缩放
cv.imshow('input_image', src)
threshold_demo(src)
local_threshold(src)
custom_threshold(src)
cv.waitKey(0)
cv.destroyAllWindows()

2. 图像腐蚀

import cv2
import numpy as np
img=cv2.imread("2.png",cv2.IMREAD_UNCHANGED)
k=np.ones((5,5),np.uint8) #卷积核
result1=cv2.erode(img,k,5)
result2=cv2.dilate(img,k,5)
cv2.imshow("original",img)
cv2.imshow("result1",result1)
cv2.imshow("result2",result2)
cv2.waitKey()
cv2.destroyAllWindows()

3. 滤波和模糊

  • 常用于去除噪声
  1. 均值滤波
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('test.jpg',0) #直接读为灰度图像
blur = cv2.blur(img,(3,5))#模板大小3*5
plt.subplot(1,2,1),plt.imshow(img,'gray')#默认彩色,另一种彩色bgr
plt.subplot(1,2,2),plt.imshow(blur,'gray')
plt.show()
  1. 中值滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('flower.jpg',0) #直接读为灰度图像
for i in range(2000): #添加点噪声
    temp_x = np.random.randint(0,img.shape[0])
    temp_y = np.random.randint(0,img.shape[1])
    img[temp_x][temp_y] = 255

blur = cv2.medianBlur(img,5)
plt.subplot(1,2,1),plt.imshow(img,'gray')#默认彩色,另一种彩色bgr
plt.subplot(1,2,2),plt.imshow(blur,'gray') 
plt.show()

4. canny边缘检测

import os
import cv2
from glob import glob
import numpy as np

cnt = 1
for fn in glob('./flip_pos/*.jpg'):
    img = cv2.imread(fn)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cy = cv2.Canny(gray, 50, 250)
    cv2.imwrite(os.path.join('./pos_canny/','%.6d.jpg'%cnt),cy)
    cnt += 1

What is broken can be reforged.