图像的二值化
(英文: Binarization)
意将非二值图像经过计算变成二值图像,它进行图像分割(Segmentation)最简单的一种方法,即后续图像处理技术的基础(简化后期的处理,提高处理速度),可以将灰度图像转化成二值图像。一般用它将感兴趣的目标和背景分离,比如:将人脸图像分为皮肤区域和非皮肤区域,将图像文字转换成PDF文字(黑/白)等等。因此,图像二值化可以看做是聚类或者分类。
二值图像即为每个像素只有两个可能值的数字图像,常出现在图像掩码,图像分割,二值化和dithering。
其将大于某个临界灰度值的像素灰度设为灰度极大值,小于这个值的为灰度极小值,从而实现二值化。
根据域值,二值化分为固定阈值和自适应阈值。比较常用的二值化方法有:双峰法,P参数法,迭代法和OTSU法等。
首先,介绍一种比较简单的方法。将图片灰度化后,我们选择127(灰度值范围的一半)作为阈值,即将像素值大于127的像素值全部设为255,小于127的全部设为0.
def easy_binarization(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_gray[img_gray>127] = 255
img_gray[img_gray<=127] = 0
plt.imshow(img_gray, cmap='gray')
plt.show()
return img_gray
通过这种方法我们得到一张这样的图片:
严谨一点,为了应对每张灰度值大不相同,我们将阈值取为图像本身的平均值。
def mean_binarization(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
threshold = np.mean(img_gray)
img_gray[img_gray>threshold] = 255
img_gray[img_gray<=threshold] = 0
plt.imshow(img_gray, cmap='gray')
plt.show()
return img_gray
这样得到的图片有一点区别。我们知道直方图是图像的重要特质,它可以帮助我们分析图像中的灰度变化。因此,如果物体与背景的灰度值对比明显,直方图就会包含双峰(bimodal histogram),它们分别为图像的前景和背景。而它们之间的谷底即为边缘附近相对较少数目的像素点,一般来讲,这个最小值就为最优二值化的分界点,通过这个点可以把前景和背景很好地分开。
def hist_binarization(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
hist = img_gray.flatten()
plt.subplot(121)
plt.hist(hist, 256)
cnt_hist = collections.Counter(hist)
begin, end = cnt_hist.most_common(2)[0][0], cnt_hist.most_common(2)[1][0]
cnt = np.iinfo(np.int16).max
threshold = 0
for i in range(begin, end+1):
if cnt_hist[i] < cnt:
cnt = cnt_hist[i]
threshold = i
print(f'{threshold}: {cnt}')
img_gray[img_gray>threshold] = 255
img_gray[img_gray<=threshold] = 0
plt.subplot(122)
plt.imshow(img_gray, cmap='gray')
plt.show()
return img_gray
我们通过这种方式所寻找的阈值为148,其区于(143,153)双峰之间,得到了一张与上两种方法大不相同的图像。可以看出,阈值的选取就是二值化实现的关键。
1979年,日本人大津提出了名为OSTU的一种算法(<–<>),也称最大类间差法。取使得前景和背景两类的类间方差最大时的阈值,btw,matlab中的graythresh便基于这个算法。此外,它可进行多级阈值处理,即OSTU扩展算法,称为多大津算法(Multi OTSU Method)。
我们先将阈值设为t, 将原图转换成转化成灰度图后,将其高与宽存于h,w。通过magic的numpy算法我们直接将小于阈值的灰度值存储在前景front中,大于等于阈值的存在背景back中。即,
# 阈值:t
h, w = img.shape[:2]
front = img[img < t]
back = img[img >= t]
显然,<