opencv 阈值处理
在使用opencv进行滤波时会考虑到中值滤波,全局虑波,局部滤波,ostu滤波等。
一 全局阈值
函数:threshold(src, thresh, maxval, type, dst=None),返回两个值retVal(阈值) 和 threshImg(处理后的图像)
函数中四个参数分别是原图像、阈值、最大值、阈值类型
阈值类型一般分为五种:
cv2.THRESH_BINARY:大于阈值的部分像素值变为maxval,其他变为0
cv2.THRESH_BINARY_INV:大于阈值的部分变为0,其他部分变为最大值
cv2.THRESH_TRUNC:大于阈值的部分变为阈值,其余部分不变
cv2.THRESH_TOZERO:大于阈值的部分不变,其余部分变为0
cv2.THRESH_TOZERO_INV:大于阈值的部分变为0,其余部分不变
二 局部阈值
在前面的部分我们使用是全局阈值,整幅图像采用同一个数作为阈值。当时这种方法并不适应与所有情况,尤其是当同一幅图像上的不同部分的具有不同亮度时。这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。
adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
这种方法需要我们指定六个参数,返回值只有一个。
• Adaptive Method- 指定计算阈值的方法。
– cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值
– cv2.ADPTIVE_THRESH_GAUSSIAN_C:阈值取值相邻区域的加权和,权重为一个高斯窗口。
• Block Size - 邻域大小(用来计算阈值的区域大小)。
• C - 这就是是一个常数,阈值就等于的平均值或者加权平均值减去这个常数。
C的常用计算方法有两种:
1.平均值减去差值delta(使用盒过滤boxfilter,性能会非常不错)
2.高斯分布加权和减去差值delta (使用高斯滤波GaussionBlur)
python中源码
import cv2 import numpy as np # 全局阈值 def threshold_demo(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # ret, binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU) # ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE) # ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_TRUNC) ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) print("阈值:", ret) cv2.imshow("binary", binary) # 局部阈值 def local_threshold(image): gray = cv2.cvtColor(image,cv2.COLOR_BGRA2GRAY) #binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10) binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10) cv2.imshow("binary ", binary) def custom_threshold(image): gray = cv2.cvtColor(image,cv2.COLOR_BGRA2GRAY) h, w = gray.shape[:2] m = np.reshape(gray, [1, w*h]) mean = m.sum()/(w*h) # binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10) ret, binary = cv2.threshold(gray, mean, 255, cv2.THRESH_BINARY) cv2.imshow("binary ", binary) if __name__ == "__main__": img = cv2.imread("h.jpg") cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE) cv2.imshow("input image", img) local_threshold(img) cv2.waitKey(0) cv2.destroyAllWindows()
总结 :在图像分割中,目标和背景对比度较强的时候,使用自适应阈值效果不错。