图像阈值,即图像二值化,包括
简单阈值
自适应阈值
Otsu 阈值
局部阈值
全局阈值
熵算法
等多种方式,本文收集整理一下
简单阈值
对所有像素使用 统一固定 的阈值
def threshold(src, thresh, maxval, type, dst=None):
- src:单通道图像,通常是灰度图
- thresh:阈值
- maxval:该参数与 type 有关,如果type=THRESH_BINARY,小于阈值置0,大于阈值置maxval,type=THRESH_BINARY_INV时刚好相反
- type:取值见下面代码,通常用 THRESH_BINARY
该方法返回两个输出。第一个是使用的阈值,第二个输出是**阈值后的图像**
示例
img = cv.imread('imgs/2.png', 0) # 0灰度,1彩色 ret, img_binary = cv.threshold(img, 127, 200, type=cv.THRESH_BINARY) # 小于阈值127置0,否则置200 ret, img_binary_inv = cv.threshold(img, 127, 210, type=cv.THRESH_BINARY_INV)# 小于阈值127置210,否则置0,和上面相反,故 inv print(ret) # 127.0 ret, thresh3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC) ret, thresh4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO) ret, thresh5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV) titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV'] images = [img, img_binary, img_binary_inv, thresh3, thresh4, thresh5] 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()
效果图
自适应阈值
同一图像的不同区域有不同光照,针对不同光照区域自动计算不同的阈值
def adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None):
- adaptiveMethod:取值cv.ADAPTIVE_THRESH_MEAN_C,代表均值滤波,即阈值是邻近区域的平均值减去C;
- 取值cv.ADAPTIVE_THRESH_GAUSSIAN_C,代表高斯滤波,即阈值是邻近区域的加权和减去C
- blockSize: 邻近区域大小
- C: 常数,计算阈值时会用到
返回二值化后的图像
示例
img = cv.imread('imgs/2.png', 0) # p1 # p2 img = cv.imread('imgs/gz.jpg', 0) img = cv.resize(img, None, fx=0.3, fy=0.3, interpolation=cv.INTER_LINEAR) img_adaptive_thresh = cv.adaptiveThreshold(img, 255, adaptiveMethod=cv.ADAPTIVE_THRESH_MEAN_C, thresholdType=cv.THRESH_BINARY, blockSize=11, C=2) cv.imshow('org', img) cv.imshow('adaptiveThreshold', img_adaptive_thresh) cv.waitKey(0)
效果图
Otsu 阈值
Otsu 方法也是 自动计算阈值 的一种方法;
原理先不讲了,先看用法吧
img = cv.imread('imgs/2.png', 0) # 全局阈值 ret1, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY) # Otsu阈值 ret2, th2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU) # 高斯滤波后再采用Otsu阈值 blur = cv.GaussianBlur(img, (5, 5), 0) ret3, th3 = cv.threshold(blur, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU) # 绘制所有图像及其直方图 images = [img, 0, th1, img, 0, th2, blur, 0, th3] titles = ['Original Noisy Img', 'Histogram', 'Global Thresh(v=127)', 'Original Noisy Img', 'Histogram', "Otsu's Thresh", 'Gaussian filtered Img', 'Histogram', "Otsu's Thresh"] for i in range(3): plt.subplot(3, 3, i * 3 + 1) plt.imshow(images[i * 3], 'gray') plt.title(titles[i * 3]) plt.subplot(3, 3, i * 3 + 2) plt.hist(images[i * 3].ravel(), 256) plt.title(titles[i * 3 + 1]) plt.subplot(3, 3, i * 3 + 3) plt.imshow(images[i * 3 + 2], 'gray') plt.title(titles[i * 3 + 2]) plt.show()
未完待续...
参考资料:
https://www.cnblogs.com/angle6-liu/p/10673585.html#top 图像二值化,阈值处理(十)
https://wenku.baidu.com/view/acc24dcf680203d8ce2f2469.html 图像二值化阈值选取常用方法汇总
https://blog.csdn.net/sinat_21258931/article/details/61418681 python-opencv函数总结之(一)threshold、adaptiveThreshold、Otsu 二值化
https://blog.csdn.net/u010128736/article/details/52801310 阈值化分割(二)OTSU法-附Python实现
https://zhuanlan.zhihu.com/p/143492231 基于Python的阈值分割算法实现(一)
https://www.cnblogs.com/gezhuangzhuang/p/10295181.html OpenCV-Python入门教程6-Otsu阈值法
https://blog.csdn.net/shawroad88/article/details/87965784 python-opencv3教程:阈值分割(全阈值分割,局部阈值分割,直方图技术法,熵算法,自适应算法,Otsu算法)