13、图像阈值
简单的阈值操作
ret,dst = threshold(src,thresh,maxval,type,dst=None)
dst:输出图
ret:设置的阈值
作用:将图像的每个像素点进行二值化
参数:
src:输入图,只能输入单通道图像,通常来说为灰度图
thresh:阈值(最小值)
maxval:二值化的最大取值
type:二值化类型,一般设为0,也可以取以下的值:
img = cv.imread('3.jpg',1) gray = cv.cvtColor(img,cv2.COLOR_RGB2GRAY) ret, thresh = cv.threshold(gray,127,255,cv.THRESH_BINARY)
自适应阈值操作
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
参数:
maxValue:阈值的最大值;
adaptiveMethod:指定自适应阈值算法;具体参数可选择如下两种:
ADAPTIVE_THRESH_MEAN_C:为局部邻域块的平均值。该算法是先求出块中的均值,再减去常数C。 ADAPTIVE_THRESH_GAUSSIAN_C:为局部邻域块的高斯加权和。该算法是在区域中(x,y)周围的像素根 据高斯函数按照他们离中心点的距离进行加权计算, 再减去常数C。
thresholdType:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
blockSize:表示邻域块大小,用来计算区域阈值,奇数,一般选择为3、5、7…等。
C:表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。
# 局部二值化 def local_threshold_demo(): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 25, 10) #print("threshold value : %s\n" % ret) cv2.imshow("binary_local", binary)
14、图像直方图
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) 绘制直方图
cv2.equalizeHist(img)直方图均衡化
参数:
images:(输入图像)参数必须用方括号括起来。
channels:计算直方图的通道。
Mask:(掩膜),一般用None,表示处理整幅图像。
histSize:表示这个直方图分成多少份(即多少个直方柱)。
ranges:直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。
最后是两个可选参数,由于直方图作为函数结果返回了,所以第六个hist就没有意义了(待确定) 最后一个accumulate是一个布尔值,用来表示直方图是否叠加。
cv2.createCLAHE(clipLimit,tileGridSize)
参数:
ClipLimit:对比度限制,默认为40
tileGridSize:分块的大小,默认为8*8
img = cv.imread('3.jpg', 0) hist = cv.calcHist([img], [0], None, [256], [0, 256]) # 绘制直方图 equ = cv.equalizeHist(img) #直方图均衡化
15、模板匹配
matchTemplate(image, templ, method, result=None, mask=None)
参数:
image:源图像S;
templ:模板图像T,一般是源图像S中的一小块;
method:
平方差匹配(CV_TM_SQDIFF):利用模板与图像之间的平方差进行匹配,最好的匹配是0,匹配越差,匹配的值越大。
相关匹配(CV_TM_CCORR):利用模板与图像间的乘法进行匹配,数值越大表示匹配程度较高,越小表示匹配效果差。
利用相关系数匹配(CV_TM_CCOEFF):利用模板与图像间的相关系数匹配,1表示完美的匹配,-1表示最差的匹配。
完成匹配后,使用cv.minMaxLoc()方法查找最大值所在的位置即可。
如果使用平方差作为比较方法,则最小值位置是最佳匹配位置。
# 1 图像和模板读取 img = cv.imread('1.jpg') template = cv.imread('1_1.jpg') h,w,l = template.shape # 2 模板匹配 # 2.1 模板匹配 res = cv.matchTemplate(img, template, cv.TM_CCOEFF) # 2.2 返回图像中最匹配的位置,确定左上角的坐标,并将匹配位置绘制在图像上 min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res) top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv.rectangle(img, top_left, bottom_right, (0,255,0), 2) # 3 图像显示 plt.ims![请添加图片描述](https://ucc.alicdn.com/images/user-upload-01/ed1d880cf7344b85a935e5edffc83d64.jpg) how(img[:,:,::-1]) plt.title('匹配结果'), plt.xticks([]), plt.yticks([]) plt.show()
16、图像金字塔(上采样和下采样)
下采样图像缩小(先高斯模糊,再降采样,需要一次次重复,不能一次到底)
上采样图像扩大(先扩大,再卷积或者使用拉普拉斯金字塔)
cv.pyrUP(img) #对图像进行上采样
cv.pyrDown(img)#对图像进行下采样
17、Soble&scharr&Laplacian&canny
cv2.Sobel()
原型: Sobel(src,ddepth,dx,dy,dst=None,ksize=None,scale=None,delta=None,borderType=None)
作用:对图像进行Sobel算子计算。检测出其边缘。
参数:
dx:x方向上的导数阶数;
dy:y方向上的导数阶数。
#-------------------------Soble算子-------------------------- # 1 读取图像 img = cv.imread('2.jpg',0) # 2 计算Sobel卷积结果 x = cv.Sobel(img, cv.CV_16S, 1, 0) y = cv.Sobel(img, cv.CV_16S, 0, 1) # 3 将数据进行转换 Scale_absX = cv.convertScaleAbs(x) # convert 转换 scale 缩放 Scale_absY = cv.convertScaleAbs(y) # 4 结果合成 result = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
cv2.scharr()
原型:Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None, /)
参数:
src:原始图像
ddepth:处理结果图像深度
dx:x轴方向
dy:y轴方向
cv2.Laplacian()
原型:Laplacian(src,ddepth,dst=None,ksize=None,scale=None,delta=None,borderType=None)
作用:检测图像边缘。
参数:
ddepth:图像位深度,对于灰度图来说,其值为:cv2.CV_8U。ksize,希望使用的卷积核的大小。scale:是缩放导数的比例常数。
#-------------------------Laplacian算子-------------------------- # 1 读取图像 img2 = cv.imread('2.jpg',0) # 2 laplacian转换 result = cv.Laplacian(img2,cv.CV_16S) Scale_abs = cv.convertScaleAbs(result) # 3 图像展示
canny = cv2.Canny(image, threshold1, threshold2)
参数:
image:灰度图
threshold1: minval,较小的阈值将间断的边缘连接起来
threshold2: maxval,较大的阈值检测图像中明显的边缘
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # 1 图像读取 img = cv.imread('./image/horse.jpg',0) # 2 Canny边缘检测 lowThreshold = 0 max_lowThreshold = 100 canny = cv.Canny(img, lowThreshold, max_lowThreshold) # 3 图像展示 plt.figure(figsize=(10,8),dpi=100) plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(canny,cmap = plt.cm.gray),plt.title('Canny检测后结果') plt.xticks([]), plt.yticks([]) plt.show()
总结
边缘检测的原理
基于搜索:利用一阶导数的最大值获取边界
基于零穿越:利用二阶导数为0获取边界
Sobel算子
基于搜索的方法获取边界
cv.sobel()
cv.convertScaleAbs()
cv.addweights()
Laplacian算子
基于零穿越获取边界
cv.Laplacian()
Canny算法
流程:
噪声去除:高斯滤波
计算图像梯度:sobel算子,计算梯度大小和方向
非极大值抑制:利用梯度方向像素来判断当前像素是否为边界点
滞后阈值:设置两个阈值,确定最终的边界