OpenCV 算法解析
- 1 图像增强
- 1.1 含义
- 1.2 方法
- 1.2.1 直方图均衡
- 1.2.2 gamma变换
- 2 除噪
- 2.1 含义
- 2.2 方法
- 2.2.1 高斯滤波
- 2.2.2 均值滤波
- 2.2.3 中值滤波
- 3 边缘检测
- 3.1 canny
- 4 HOG特征提取
- 4.1 含义
- 4.2 流程
- 4.3 案例
- 6 两个比赛
- 6.1 三个功能整合
- 6.2 目标检测
- 6.3 yolov5代码详解
1 图像增强
1.1 含义
突出图像细节,让图像更加清晰。
1.2 方法
直方图均衡
1.2.1 直方图均衡
直方图均衡
import cv2
import numpy as np
import matplotlib.pyplot as pltdef histequal(img_gray):# 1 计算各个像素的频数、累积频数、归一化h,w = img_gray.shapecum_freq = np.array([(img_gray==i).sum() for i in range(255)]).cumsum()cum_freq = (cum_freq/cum_freq[-1]*255).astype(np.uint8)tmp = img_gray.copy()for i in range(255):tmp[img_gray == i] = cum_freq[i]return tmpimg = cv2.imread('opencv/features/cat0.jpg', 0)
out = histequal(img)
plt.subplot(121)
plt.title('org')
plt.imshow( img,cmap='gray')
plt.subplot(122)
plt.title('histequal')
plt.imshow( out,cmap='gray')
plt.show()
1.2.2 gamma变换
import cv2
import numpy as np
import matplotlib.pyplot as pltdef gamma(img,c=2,r=2):return np.array(c*img**r,dtype=np.uint8).clip(0,255)img = cv2.imread('/Users/liushuang/Desktop/LearnGit/项目实战/鱼苗检测/yolov5-master/opencv/features/cat.jpg')
out = gamma(img)
plt.subplot(121)
plt.title('org')
plt.imshow( img,cmap='gray')
plt.subplot(122)
plt.title('gamma')
plt.imshow( out,cmap='gray')
plt.show()
2 除噪
2.1 含义
除去图片上的噪声
2.2 方法
空间滤波法(均值滤波、高斯滤波、中值滤波、双边滤波),变换滤波(傅立叶,小波变换)、形态学等
2.2.1 高斯滤波
高斯滤波
高斯滤波适合处理呈正态分布的噪声。滤波器的特点是权值成正态分布。方差越大,滤波效果越明显;反之,效果越差。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef guassian_filter(img, k_size=3, sigma=2):# 获取通道if len(img.shape) == 3:h, w, c = img.shapeelse:img = np.expand_dims(img, axis=-1)h, w, c = img.shape# img padiingpad = (k_size - 1) // 2out_put = np.zeros((h + pad * 2, w + pad * 2,3), dtype=np.float32)out_put[pad:pad + h, pad:pad + w] = img.copy().astype(np.float32)# generate kernelk = np.zeros((k_size, k_size), dtype = np.float32)for i in range(-pad, k_size - pad):for j in range(-pad, k_size - pad):k[j + pad, i + pad] = np.exp(-(i ** 2 + j ** 2) / (2 * sigma ** 2))k /= (2 * np.pi * sigma ** 2)k /= k.sum()tmp = out_put.copy()# Gaussian filterfor i in range(h):for j in range(w):for cc in range(c):out_put[pad + i, pad + j, cc] = np.sum(k * tmp[i:i + k_size, j:j + k_size, cc])out_put = np.clip(out_put, 0, 255)return out_put[pad:pad + h, pad:pad + w].astype(np.uint8)#
img = cv2.imread('opencv/features/dogGauss.jpeg')
out = guassian_filter(img, k_size=3, sigma=2)
plt.subplot(121)
plt.title('org')
plt.imshow( img[...,::-1])
plt.subplot(122)
plt.title('out')
plt.imshow( out[...,::-1])
plt.show()# sigma = 1 ,高斯核
'''
array([[0.07511362, 0.12384141, 0.07511362],[0.12384141, 0.20417996, 0.12384141],[0.07511362, 0.12384141, 0.07511362]], dtype=float32)# sigma = 3
array([[0.10699731, 0.11310981, 0.10699731],[0.11310981, 0.11957153, 0.11310981],[0.10699731, 0.11310981, 0.10699731]], dtype=float32)
'''
2.2.2 均值滤波
### 2.2.2 mean+filter
import cv2
import numpy as np
import matplotlib.pyplot as pltdef mean_filter(img, k_size=3):# shapeif len(img.shape) != 3:img = img[..., None]h, w, c = img.shape# 1 kernelk = np.ones((k_size, k_size), np.float32) / (k_size * k_size)# 2 out_Putpad = (k_size - 1) // 2out_put = np.zeros((h + 2*pad, w + 2*pad, c), np.float32)out_put[pad:pad + h, pad:pad + w] = img.copy().astype(np.float32)# 3 filtetmp = out_put.copy()for i in range(h):for j in range(w):for cc in range(c):out_put[pad + i:, pad + j, cc] = (tmp[i:i + k_size, j:j + k_size, cc] * k).sum()out_put = np.clip(out_put, 0, 255)return out_put[pad:pad + h, pad:pad + w].astype(np.uint8)# filteimg = cv2.imread('opencv/features/dogGauss.jpeg')
out = mean_filter(img, k_size=3)
plt.subplot(121)
plt.title('org')
plt.imshow(img[..., ::-1])
plt.subplot(122)
plt.title('out_mean_filter')
plt.imshow(out[..., ::-1])
plt.show()
2.2.3 中值滤波
取窗口的中位数作为中心点的值,如果效果不好,可以增大核的尺寸,或者多循环几次。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef median_filter(img, k_size=10):# shapeif len(img.shape) != 3:img = img[..., None]h, w, c = img.shape# 2 out_Putpad = (k_size - 1) // 2out_put = np.ones((h + 2 * pad, w + 2 * pad, c), np.float32) * (-1)out_put[pad:pad + h, pad:pad + w] = img.copy().astype(np.float32)# 3 filtetmp = out_put.copy()for i in range(h):for j in range(w):for cc in range(c):t = tmp[i:i + k_size, j:j + k_size, cc]out_put[pad + i:, pad + j, cc] = np.median(t[t > 0])return out_put[pad:pad + h, pad:pad + w].astype(np.uint8)# filteimg = cv2.imread('opencv/features/letteropen.png')
out = median_filter(img, k_size=20)
plt.subplot(121)
plt.title('org')
plt.imshow(img[..., ::-1])
plt.subplot(122)
plt.title('median_filter')
plt.imshow(out[..., ::-1])
plt.show()
3 边缘检测
3.1 canny
canny 边缘检测流程
- 平滑处理
- 梯度检测
- 非极大值抑制
- 滞后阈值处理
import cv2 as cv
import numpy as np
import matplotlib.pyplot as pltdef canny(img):# 1. 平滑img_blur = cv.GaussianBlur(img, (5, 5), 2)# 2. 梯度gradx = cv.Sobel(img_blur, cv.CV_64F, 1, 0) # xgrady = cv.Sobel(img_blur, cv.CV_64F, 0, 1) # yR = np.abs(gradx) + np.abs(grady)T = np.arctan(grady / (gradx + 1e-3))# 3. 非极大值抑制,细化边缘h, w = R.shapeimg_thin = np.zeros_like(R)for i in range(1, h - 1):for j in range(1, w - 1):theta = T[i, j]if -np.pi / 8 <= theta < np.pi / 8: # (-22,22)if R[i, j] == max([R[i, j], R[i, j - 1], R[i, j + 1]]): # 上下img_thin[i, j] = R[i, j]elif -3 * np.pi / 8 <= theta < -np.pi / 8: # (-66,-22)if R[i, j] == max([R[i, j], R[i - 1, j + 1], R[i + 1, j - 1]]): # 斜线img_thin[i, j] = R[i, j]elif np.pi / 8 <= theta < 3 * np.pi / 8: # (22,66)if R[i, j] == max([R[i, j], R[i - 1, j - 1], R[i + 1, j + 1]]): # 反斜线img_thin[i, j] = R[i, j]else: # (66,110)if R[i, j] == max([R[i, j], R[i - 1, j], R[i + 1, j]]): # 左右img_thin[i, j] = R[i, j]# 4 双阈值抑制th1 = 5th2 = 30maxv = 255img_edge = np.zeros_like(img_thin)h, w = img_thin.shapefor i in range(1, h - 1):for j in range(1, w - 1):if img_thin[i, j] >= th2:img_edge[i, j] = maxvelif img_thin[i, j] > th1:around = img_thin[i - 1:i + 2, j - 1:j + 2]if around.max() >= th2:img_edge[i, j] = maxvreturn img_edgeimg = cv2.imread('opencv/features/letteropen.png', 0)
out = canny(img)
plt.subplot(121)
plt.title('org')
plt.imshow( img,cmap='gray')
plt.subplot(122)
plt.title('canny')
plt.imshow( out,cmap='gray')
plt.show()
4 HOG特征提取
4.1 含义
通过提取图像局部区域梯度直方图构成特征,进而获取整个图像的特征。HOG对几何和光学形变都能保持不变形。通过局部归一化,忽略细节的变化,提取共哦那个特性。
4.2 流程
img --> cells,blocks --> 计算每个cell的梯度直方图