一、介绍
图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。 在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。 图像的二值化处理就是将图像上的点的灰度值为0或255,也就是将整个图像呈现出明显的黑白效果。即将256个亮度等级的灰度图像通过适当的阈值选取而获得仍然可以反映图像整体和局部特征的二值化图像。
(摘自百度百科)
二、实现原理
一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。
Python-OpenCV中提供了阈值(threshold)函数:
threshold(src, thresh, maxval, type[, dst]) -> retval, dst
函数:
- src 指原图像,原图像应该是灰度图。
- thresh 阈值
- maxval 表示与THRESH_BINARY和THRESH_BINARY_INV阈值类型一起使用设置的最大值
- type 表示阈值类型
- retval参数表示返回的阈值。若是全局固定阈值算法,则返回thresh参数值。若是全局自适应阈值算法,则返回自适应计算得出的合适阈值。
- dst参数表示输出与src相同大小和类型以及相同通道数的图像。
cv2.thresh_otsu类型
- 第一返回值,得到图像的阈值,
- 第二个返回值,也就是阈值处理后的图像,
adaptiveThreshold方法
def adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None): # real signature unknown; restored from __doc__
OpenCV的adaptiveThreshold函数进行局部阈值。函数原型为:adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst
- src参数表示输入图像(8位单通道图像)。
- maxValue参数表示使用 THRESH_BINARY 和 THRESH_BINARY_INV 的最大值.
- adaptiveMethod参数表示自适应阈值算法,平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)。
- thresholdType参数表示阈值类型,必须为THRESH_BINARY或THRESH_BINARY_INV的阈值类型。
- blockSize参数表示块大小(奇数且大于1,比如3,5,7........ )。
C参数是常数,表示从平均值或加权平均值中减去的数。 通常情况下,这是正值,但也可能为零或负值。
三、OpenCV代码实现
1. OpenCV 阈值函数DEMO
# -*- coding: utf-8 -*- import cv2 image = cv2.imread('test.jpg') image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) cv2.threshold(image, 140, 255, 0, image) cv2.imshow("Image", image) cv2.waitKey(0)
2. 全局阈值使用THRESH_OTSU
# -*- coding: utf-8 -*- import cv2 image = cv2.imread('test.jpg') image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) ret, binary = cv2.threshold(image, 140, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU, image) print("threshold value: %s" % ret) # 打印阈值,前面先进行了灰度处理0-255,我们使用该阈值进行处理,低于该阈值的图像部分全为黑,高于该阈值则为白色 cv2.imshow("Image", binary) cv2.waitKey(0)
3. 全局阈值使用THRESH_TRIANGLE 三角形算法
ret, binary = cv.threshold(gray,0,255,cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
4. 全局阈值,指定阈值,大于指定阈值都为0
ret, binary = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)
5. 全局阈值,指定阈值,大于127都为127
ret, binary = cv2.threshold(image, 127, 255, cv2.THRESH_TRUNC)
6. 全局阈值,小于阈值的都为0
ret, binary = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO)
7. 局部阈值 ADAPTIVE_THRESH_MEAN_C
# -*- coding: utf-8 -*- import cv2 image = cv2.imread('test.jpg') image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) dst = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 25, 10) cv2.imshow("Image", dst) cv2.waitKey(0)
8. 局部阈值ADAPTIVE_THRESH_GAUSSIAN_C
# -*- coding: utf-8 -*- import cv2 image = cv2.imread('test.jpg') image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) dst = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10) cv2.imshow("Image", dst) cv2.waitKey(0)
四、numpy运算
1. 使用中间阈值127
# -*- coding: utf-8 -*- from PIL import Image import matplotlib.pyplot as plt import numpy as np # 显示图片 def showimg(img, isgray=False): plt.axis("off") if isgray == True: plt.imshow(img, cmap='gray') else: plt.imshow(img) plt.show() im = Image.open("test.jpg") im = np.array(im.convert('L')) im = np.where(im[..., :] < 127, 0, 255) showimg(Image.fromarray(im), True)
2. 取所有像素点灰度的平均值
# -*- coding: utf-8 -*- from PIL import Image import matplotlib.pyplot as plt import numpy as np # 显示图片 def showimg(img, isgray=False): plt.axis("off") if isgray: plt.imshow(img, cmap='gray') else: plt.imshow(img) plt.show() im = Image.open("test.jpg") im = np.array(im.convert('L')) im = np.array(im) avg_gray = np.average(im) im = np.where(im[..., :] < avg_gray, 0, 255) showimg(Image.fromarray(im), True)