就是剔除图像内像数值高于或低于一定值的像素点。可以获得一个二值图,有效的实现的前景和背景的分离。。
OpenCV 提供了函数 cv2.threshold()和函数 cv2.adaptiveThreshold(),用于实现阈值处理。
retval, dst = cv2.threshold( src, thresh, maxval, type )
就是处理成二值图。灰度值大于阈值设为最大值,小于就是0.,,虽然都是灰度图,也可以看看彩图啊。
img=cv2.imread('5.jpg',0)
t,rst=cv2.threshold(img,127,255,cv2.THRESH_BINARY) # 8位图像最大值就是255,阈值设置为127
cv2.imshow("img",img)
cv2.imshow("rst",rst)
cv2.waitKey()
cv2.destroyAllWindows()
就是跟上面倒过来。。
img=cv2.imread('5.jpg',0)
t,rst=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
cv2.imshow("img",img)
cv2.imshow("rst",rst)
cv2.waitKey()
cv2.destroyAllWindows()
将大于阈值的像素设为阈值,小于或等于阈值的不变
img=cv2.imread('5.jpg',0)
t,rst=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
cv2.imshow("img",img)
cv2.imshow("rst",rst)
cv2.waitKey()
cv2.destroyAllWindows()
对于色彩均匀的图像,一个阈值就可以完成。但是色彩不均匀,只有一个阈值无法清晰有效的得到阈值分割后的图像
自适应阈值处理可以使用变换的阈值。它通过计算每个像素点周围邻近区域的加权平均值获得阈值,然后处理。这个方式可以更好的处理明暗差异较大的图像。。人类就是厉害。。
dst = cv.adaptiveThreshold( src, maxValue, adaptiveMethod, thresholdType, blockSize, C )
自适应阈值等于每个像素由参数 blockSize 所指定邻域的加权平均值减去常量 C,自适应方法不同计算方式也不同。
img=cv2.imread("5.jpg",0)
t1,thd=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
athdMEAN=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,3)
athdGAUS=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,3)
cv2.imshow("img",img)
cv2.imshow("thd",thd)
cv2.imshow("athdMEAN",athdMEAN)
cv2.imshow("athdGAUS",athdGAUS)
cv2.waitKey()
cv2.destroyAllWindows()
可以看到,自适应阈值处理保留了更多的细节。。。感觉 athdMEAN 轮廓提取的挺好的。
使用 cv2.threshold() 处理时,一般处理的时色彩均匀的,阈值设置为127就比较合适。但是当灰度级分别不均匀,阈值设置为127就会失败。比如一个图的像数值全是126.。。一处理全是0.。。
Otsu 方法可以根据当前图像给出最佳的分割阈值,就是他会历遍所有阈值,然后找出最佳。cv2.threshold()中对参数 type 给个cv2.THRESH_OTSU 就可以了。需要注意,使用Otsu 方法时,阈值设置为0.并且会返回计算得到的最佳阈值(普通的就返回设定的阈值)。
img = np.zeros((5,5),dtype=np.uint8)
img[0:6,0:6]=123
img[2:6,2:6]=126
print("img=\n",img)
t1,thd=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
print("thd=\n",thd)
t2,otsu=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print("otsu=\n",otsu)
img=
[[123 123 123 123 123]
[123 123 123 123 123]
[123 123 126 126 126]
[123 123 126 126 126]
[123 123 126 126 126]]
thd=
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]]
otsu=
[[ 0 0 0 0 0]
[ 0 0 0 0 0]
[ 0 0 255 255 255]
[ 0 0 255 255 255]
[ 0 0 255 255 255]]
保留图像原有信息,过滤掉图像内部的噪声,这就是平滑处理。平滑处理会对图像中与周围像素点差异较大的像素点进行处理,调整为近似值。平滑处理通常伴随着图像模糊。我们使用均值滤波,方框滤波,高斯滤波,中值滤波,双边滤波, 2D 卷积(自定义滤波),
图像滤波时图像处理和计算机视觉中最常用最基本的操作。。芜湖。图像滤波允许在图像上进行各种操作。有时也把图像平滑处理称为图像滤波,图像模糊处理啥的。。
是指使用像素点周围N X N 个像素值的均值来替换当前像数值。使用这个方法遍历处理图像每个点就可以完成均值滤波。如果N越大,参与运算的像素点越多,图像失真越严重。
dst = cv2.blur( src, ksize, anchor, borderType )
归一化的卷积核,,别不认识。。。M,N 表示邻域的行列大小。意会意会。。
o=cv2.imread("5.jpg")
r=cv2.blur(o,(5,5))
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()
这个不会计算像素平均值,这个可以自由旋转是否对均值滤波的结果归一化,就是可以选择滤波结果时领域像素值之和的凭自己,还是领域像素值之和。。。
dst = cv2.boxFilter( src, ddepth, ksize, anchor, normalize, borderType )
o=cv2.imread("5.jpg")
r=cv2.boxFilter(o,-1,(2,2),normalize=0)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()
啥也看不到了。。。
均值和方波滤波,邻域每个像素的权重都是相等的,高斯滤波中,中心点权重加大,各个像素有不同的权重。
卷积核的值不再都是1,dst = cv2.GaussianBlur( src, ksize, sigmaX, sigmaY, borderType )
sigmaX 是必选的,但是可以设置为0,让函数自己去算。
o=cv2.imread("5.jpg")
r=cv2.GaussianBlur(o,(5,5),0,0)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows() # 反正就是模糊,,PS里不就常用高斯模糊嘛。。。
这个不用加权求均值的方法了,使用所有像素的中间值来替代
dst = cv2.medianBlur( src, ksize)
o=cv2.imread("image\\lenaNoise.png")
r=cv2.medianBlur(o,3)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()
中值滤波不存在均值滤波等方式带来的细节模糊问题,可以几乎不影响原图的情况下去除噪声,但运算量大。