有哪些不同的图像阈值处理技术以及如何实现这些技术?

144 阅读9分钟

图像阈值处理是图像分割的一个子模块,其中某些像素值会根据特定的阈值进行改变,其中像素值为0被认为是黑色,像素值为255被认为是白色。因此,OpenCV模块被用来相应地验证阈值,即下层像素值为0,上层像素值为255,并相应地按要求促进图像分割。本文简要介绍了不同类型的图像阈值处理技术,并使用 OpenCV 模块来实现。

目录

  1. 图像阈值处理简介
  2. 使用OpenCV的简单阈值处理
  3. 使用OpenCV的自适应阈值处理
  4. 使用OpenCV的Ostu阈值处理
  5. 摘要

图像阈值处理简介

图像阈值化是一种技术,用于促进各种图像预处理任务的图像分割。在考虑图像处理时,OpenCV模块有各种内置的功能,可以用于相关的任务。因此,这里利用OpenCV模块进行图像阈值处理,其中OpenCV提供的不同的图像阈值处理技术如下:----。

  • 简单的阈值处理
  • 自适应阈值处理
  • 奥斯图的阈值处理

所以在这里,OpenCV包被用作中间人,用于执行所需的阈值,以比较像素值,并从图像中分割任何所需的边界。因此,在文章的下一部分,让我们看看如何使用OpenCV进行各种类型的阈值处理。

使用OpenCV进行简单的阈值处理

OpenCV中的简单阈值处理技术也被称为 二进制阈值处理。在简单的阈值处理技术中,设置了一个标准的阈值,每个像素的值都与阈值进行比较。如果像素值小于提到的阈值,那么该值就被设置为0,否则就被设置为最大值。

因此,让我们来探索不同的简单阈值处理技术。

将图像加载到工作环境中

通过使用OpenCV包的imread() 函数,图像可以被加载到工作环境中,如下图所示。

img=cv2.imread('/content/drive/MyDrive/Colab notebooks/Image thresholding techniques in opencv/img_thresh.jpeg')

现在可以使用matplotlib的imshow() 函数将加载的图像可视化,如下图所示。

plt.imshow(img)
plt.show()

但是imshow()函数默认加载的是灰度图像,原始图像可以通过使用名为cv2.COLOR_BGR2RGB()的函数将BGR图像转换成RGB图像来获得,如下图所示。

orig_img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(orig_img)
plt.show()

简单图像阈值处理的一般语法

cv2.threshold(source, thresholdValue, maxVal, thresholdingTechnique)

cv2.THRESH_BINARY

这是一种简单的阈值处理技术,如果像素强度大于所述的阈值,那么图像将被分割成白色区域,即上限为255,否则如果强度低于,图像将被分割成下限为0,或者图像将被分割成较黑的区域。

采用OpenCV模块的阈值二进制函数的步骤如下所示。

rect,thresh=cv2.threshold(orig_img,127,255,cv2.THRESH_BINARY)

后来得到的阈值可以用来获得图谱和可视化的功能,如下图所示。

plt.imshow(thresh)
plt.show()

所以在这里我们可以比较原始图像和OpenCV模块的二进制阈值分割的图像。所以现在让我们进入下一个技术。

cv2.THRESH_BINARY_INV

它只是二进制阈值的逆函数,大于阈值的像素将被分割到黑色区域或0值,而低于阈值的像素将被分配到较高的像素值或255像素的值。

让我们看看如何使用函数来可视化反阈值二进制图像分割的函数。

rect,thresh1=cv2.threshold(orig_img,127,255,cv2.THRESH_BINARY_INV)

所以现在让我们用阈值来获得图谱,并直观地看到反阈值函数是如何分割像素的。

plt.imshow(thresh1)
plt.show()

所以现在我们可以清楚地比较OpenCV的二进制和反二进制阈值函数是如何根据阈值来分割图像的。为了更好地理解,得到一个子图来清楚地了解分割的差异,如下图所示。

plt.figure(figsize=(20,5))
plt_title=['Original Image','Binary thresholding of original image','Inverse Binary thresholding of original image']
image_list=[orig_img,thresh,thresh1]
 
for i in range(3):
 plt.subplot(1,3,i+1)
 plt.imshow(image_list[i])
 plt.title(plt_title[i])
 #plt.tight_layout()
plt.show()

cv2.THRESH_TRUNC

OpenCV模块的这个函数是这样操作的:如果每个像素的强度值大于阈值,它就被截断到阈值,否则就被截断到像素的最低值或向黑色区域分割。利用该函数的步骤如下。

rect,thresh2=cv2.threshold(orig_img,127,255,cv2.THRESH_TRUNC)

现在我们可以使用阈值来获得图形,以可视化分割后的图像。

plt.imshow(thresh2)
plt.show()

cv2.THRESH_TOZERO

OpenCV的这个函数的功能是,如果像素的强度小于阈值,那么像素值就会被设置为0,或者图像被分割到较暗的一面或黑色区域。我们可以按照下面提到的步骤来使用这个功能。

rect,thresh3 = cv2.threshold(orig_img,127,255,cv2.THRESH_TOZERO)

现在可以用阈值来获得如下图所示的图,以直观地看到该函数是如何根据像素强度来分割图像的。

plt.imshow(thresh3)
plt.show()

cv2.THRESH_TOZERO_INV

这个函数只是上述函数的反义词,如果像素的强度小于像素值,将被设置为最高值或被分割为较白的区域,而如果像素值高于阈值,将被分割为较低的像素值,图像将被分割为较暗的区域。

rect,thresh4 = cv2.threshold(orig_img,127,255,cv2.THRESH_TOZERO_INV)

现在,阈值可以用来直观地看到原始图像是如何根据像素强度来分割图像的,如下所示。

plt.imshow(thresh4)
plt.show()

为了更好地理解图像,分割让我们获得一个子图来比较原始图像上的各个阈值处理技术。

plt.figure(figsize=(20,5))
plt_title=['Original Image','Zero thresholding of original image','Inverse Zero thresholding of original image']
image_list=[orig_img,thresh3,thresh4]
 
for i in range(3):
 plt.subplot(1,3,i+1)
 plt.imshow(image_list[i])
 plt.title(plt_title[i])
 #plt.tight_layout()
plt.show()

plt.figure(figsize=(20,5))

所以现在让我们来看看下一个图像阈值技术,名为自适应阈值。

使用OpenCV的自适应阈值处理

自适应阈值处理或多或少与简单阈值处理相似,但如果仔细观察,在简单阈值处理中,阈值的全局值被用来比较像素的强度,但在自适应阈值处理技术中,阈值被计算为较小的区域,这说明不同区域有不同的阈值,并倾向于在恶劣的照明条件下获得惊人的性能。

因此,让我们看看自适应阈值技术提供的不同图像阈值技术。但首先,我们来看看自适应阈值处理技术的一般语法。

自适应阈值处理的语法

cv2.adaptiveThreshold(source, maxVal, adaptiveMethod, thresholdType, blocksize, constant)

因此,自适应阈值技术有两种类型的内置函数。它们是

  • 平均自适应阈值处理
  • 高斯阈值

但在应用自适应阈值技术之前,必须将图像转换为灰度,以实现自适应阈值技术。将原始图像转换为灰度图像的步骤如下所示。

img_grey = cv2.cvtColor(orig_img, cv2.COLOR_BGR2GRAY)

现在让我们使用转换后的灰度图像来应用自适应阈值技术。

cv2.ADAPTIVE_THRESH_MEAN_C

这种阈值技术计算像素值块相对于一个常数的平均值,其中常数值从像素的平均值中减去。实现这一功能的步骤如下。

thresh5 = cv2.adaptiveThreshold(img_grey,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)

因此,得到的阈值可以通过如下图所示的图示进行可视化。

plt.imshow(thresh5)
plt.show()

plt.imshow(thresh5)

plt.show()

cv2.ADAPTIVE_THRESH_GAUSSIAN_C

与平均阈值技术类似,这种阈值技术计算相邻像素相对于一个常数的高斯权重,其中常数将从高斯权重中减去,用于图像分割。实现这一技术的步骤如下。

thresh6 = cv2.adaptiveThreshold(img_grey,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
The threshold values obtained can be visualized using plots as shown below for a better understanding of how the gaussian weights have segmented each of the pixel values.
plt.imshow(thresh6)
plt.show()

为了更好地理解,我们得到了一个子图,以了解图像分割是如何在原始图像上进行自适应图像阈值处理的。

plt.figure(figsize=(20,5))
plt_titles=['Original Image','Adaptive Mean Thresholding Image','Gaussian Thresholding Image']
imgs=[orig_img,thresh5,thresh6]
 
for i in range(3):
 plt.subplot(1,3,i+1)
 plt.imshow(imgs[i])
 plt.title(plt_titles[i])
 plt.tight_layout()
 
plt.show()

使用OpenCV的Ostu阈值处理技术

Ostu的阈值技术是一种图像阈值技术,其中阈值是自动确定的,用于分割的图像。这就避免了在各种光照条件下与错误的图像分割有关的问题。奥斯图的二进制技术最适合并可解释为嘈杂的图像,因为对于嘈杂的图像,手动选择阈值有时会出错。因此,首先,为了实现Ostu的阈值技术,必须将其转换为灰度图像,如下所示。

noise_img_grey = cv2.cvtColor(orig_nosie_img, cv2.COLOR_BGR2GRAY)

普通奥斯特阈值处理

普通奥斯特阈值处理技术在灰度转换后的图像上工作,并为灰度转换后的噪声图像自动选择阈值。实现这一技术的步骤如下。

rect1,thresh7=cv2.threshold(noise_img_grey,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

之后,这些阈值可用于根据自动选择的阈值对噪声图像进行可视化分割。

plt.imshow(thresh7)
plt.show()

基于高斯滤波的Ostu阈值法

为了实现这一技术,必须使用高斯滤波器对灰度图像进行主要的模糊处理,如下所示。

blur_noise_img=cv2.GaussianBlur(noise_img_grey,ksize=(7,7),sigmaX=0)

注:-

ksize参数应该总是奇数,因为它指定了图像的高度和宽度,sigmaX是沿x轴的标准偏差,可以声明为0。 所以现在让我们看看如何使用高斯滤波器获得Ostu阈值。

rect,thresh8 = cv2.threshold(blur_noise_img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

现在让我们使用获得的这个阈值,并获得一个图来可视化。

plt.imshow(thresh8)
plt.show()

让我们获得一个子图,以便更好地理解奥斯特的阈值处理技术如何用于图像阈值处理。

plt.figure(figsize=(20,5))
plt_titles=['Original Noisy Image','Grayscale image','Ostus threshold image','Guassian blurred image','Ostus thresholding image with gaussian filtering']
img_list=[orig_nosie_img,noise_img_grey,thresh7,blur_noise_img,thresh8]
 
for i in range(5):
 plt.subplot(1,5,i+1)
 plt.imshow(img_list[i])
 plt.title(plt_titles[i])
 plt.tight_layout()
 
plt.show()
image','Ostus thresholding image with gaussian filtering']

img_list=[orig_nosie_img,noise_img_grey,thresh7,blur_noise_img,thresh8]

for i in range(5):

plt.subplot(1,5,i+1)

plt.imshow(img_list[i])

plt.title(plt_titles[i])

plt.tight_layout()

plt.show()

总结

简而言之,图像阈值处理技术是图像分割的一个组成部分,图像根据像素强度值和考虑的阈值被分割。阈值的选择因技术而异,相应的图像分割技术将负责适当的图像分割。因此,这篇文章为我们提供了一个完整的概述,即如何使用OpenCV应用不同的图像阈值技术,以及如何根据像素强度值和所考虑的阈值对图像进行分割。