图像阈值
在Opencv中调用 threshold() 函数:
ret, dst = thresshould(src, thresh, maxval, typr)
四个参数分别是:
- src 输入的原图
- thresh 阈值 # 一般是127
- maxval 指定最大阈值 #一般为255
- type 指定二值化操作类型
二值化的类型有:
- THRESH_BINARY # 超过阈值取最大值,否则取0
- THRESH_BINARY_INV
- THRESH_TRUNC # 大于阈值设为阈值,否则不变
- THRESH_TOZERO # 大于阈值部分不变, 否则取0
- THRESH_TOZERO_INV
利用这张图片分别演示效果
var4 = cv2.imread('cat.jpg')
ret1, change1 = cv2.threshold(var4, 127, 255, cv2.THRESH_BINARY)
ret2, change2 = cv2.threshold(var4, 127, 255, cv2.THRESH_BINARY_INV)
ret3, change3 = cv2.threshold(var4, 127, 255, cv2.THRESH_TRUNC)
ret4, change4 = cv2.threshold(var4, 127, 255, cv2.THRESH_TOZERO)
ret5, change5 = cv2.threshold(var4, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'THRESH_TRUNC', 'THRESH_TOZERO', 'THRESH_TOZERO_INV']
images = [var4, change1, change2, change3, change4, change5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
效果为:
图像平滑去噪
分别采用四种滤波器去噪点:
- blur() # 均值滤波 对图像进行卷积操作
- boxFilter() # 方框滤波 当其normalize(归一化)参数设为一时,效果与blur一样
- GaussianBlur # 高斯滤波
- medianBlur # 中值滤波
使用lena图像试验操作效果为:
其中 1 为blur ;2 为高斯滤波 ;3 为平均滤波
img1 = cv2.imread('lenaNoise.png')
blur1 = cv2.blur(img1, (3, 3))
blur2 = cv2.boxFilter(img1, -1, (3, 3), normalize=True) # 方框滤波 (当normalize(归一)的参数给True时结果和均值滤波一样,为False时取255)
blur3 = cv2.GaussianBlur(img1, (3, 3), 1)
blur4 = cv2.medianBlur(img1, 3)
res = np.hstack((blur1, blur3, blur4))
print(res)
cv2.imshow('median vs average', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
形态学操作
腐蚀操作
使用Opencv中的 erode() 函数可以实现图像的腐蚀操作;
erode(src, kernel, iterations)
- src 为原图
- kernel 为卷积核
- iterations 为腐蚀次数
腐蚀前:
进行腐蚀操作:
img = cv2.imread('dige.png')
kernel = np.ones((5, 5), np.uint8) #
res = cv2.erode(img, kernel, iterations=1) # 1 为腐蚀次数
tegether = np.hstack((img, res))
cv2.imshow('tegether', tegether)
cv2.waitKey(0)
cv2.destroyAllWindows()
膨胀操作为腐蚀的逆运算
调用 dilate函数即可
开运算与闭运算
- 开运算 = 先腐蚀再膨胀
- 闭运算 = 先膨胀再腐蚀
调用 morphologyEx函数中的 MORPH_OPEN 和 MORPH_CLOSE 模块可实现;
顶帽和黑帽
- 顶帽:原始输入-开运算 # MORPH_TOPHAT
- 黑帽:闭运算-原始输入 # MORPH_BLAKHAT
tophat =cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel=np.ones((3, 3), np.uint8))
blackhat =cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel=np.ones((3, 3), np.uint8))
tegether = np.hstack((tophat, blackhat))
cv2.imshow('tegether', tegether)
cv2.waitKey(0)
cv2.destroyAllWindows()
左为TOPCAT运算,右为BLACKCAT运算
图像梯度
进行梯度计算时,我们常常读取图像的灰度图像。
介绍三种算子:
- Soble算子 调用时:
Sobel算子 参数 (src,ddepth(图像深度), dx(水平计算), dy(竖直), ksize(算子大小))
利用sobel算子的效果为:
sobel = cv2.Sobel(pie, cv2.CV_64F, 0, 1, ksize=3) # cv2.CV_64F 设定算子计算相减后可为负值
tegether = np.hstack((pie, sobel))
cv_show(tegether, 'tegether')
只对 x 方向进行计算
此处建议使用sobel算子的时候不要同时对 x y 方向进行计算,而要两次计算后再将两次计算完成后的结果相加,效果明显要好很多
pie = cv2.imread('pie.png', cv2.IMREAD_GRAYSCALE)
sobelX = cv2.Sobel(pie, cv2.CV_64F, 1, 0, ksize=3)
X = cv2.convertScaleAbs(sobelX)
sobelY = cv2.Sobel(pie, cv2.CV_64F, 0, 1, ksize=3)
Y = cv2.convertScaleAbs(sobelY)
sobelXY = cv2.addWeighted(X, 0.5, Y, 0.5, 0)
res = np.hstack((pie, sobelXY))
cv_show(res, 'res')
此处分别对 x 和 y 计算后我们需要对结果取绝对值处理,因为未处理前为负数。
调用 cv2.convertScaleAbs 实现
效果为:
- Scharr算子
相对于sobel算子来说,scharr算子更加敏感,因此再进行梯度运算的时候往往能体现出更多细微的轮廓;
- laplacian算子 (一般不单独使用)
展示三种算子的处理区别
mf = cv2.imread('mf.jpg', cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(mf, cv2.CV_64F, 1, 0, ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(mf, cv2.CV_64F, 0, 1, ksize=3)
sobely = cv2.convertScaleAbs(sobely)
mfxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
scharrx = cv2.Scharr(mf, cv2.CV_64F, 1, 0)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.Scharr(mf, cv2.CV_64F, 0, 1)
scharry = cv2.convertScaleAbs(scharry)
mfxy1 = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
lap = cv2.Laplacian(mf, cv2.CV_64F)
lap = cv2.convertScaleAbs(lap)
res = np.hstack((mfxy, mfxy1, lap))
cv_show(res, 'res')
从左往右依次为: sobel算子,Scharr算子,Laplacian算子
(博主以身试法)
————————————————————————————————————————————