《OpenCv视觉之眼》Python图像处理八 :Opencv图像处理之图像阈值化处理原理及函数

140
0
2021年2月20日 09时25分

本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的、不同方法的处理,以达到对图像进行去噪、锐化等一系列的操作。同时,希望观看本专栏的小伙伴可以理解到OpenCv进行图像处理的强大哦,如有转载,请注明出处(原文链接和作者署名),感谢各位小伙伴啦!

 

前文参考:
《OpenCv视觉之眼》Python图像处理一 :Opencv-python的简介及Python环境搭建
《OpenCv视觉之眼》Python图像处理二 :Opencv图像读取、显示、保存基本函数原型及使用
《OpenCv视觉之眼》Python图像处理三 :Opencv图像属性、ROI区域获取及通道处理
《OpenCv视觉之眼》Python图像处理四 :Opencv图像灰度处理的四种方法及原理
《OpenCv视觉之眼》Python图像处理五 :Opencv图像去噪处理之均值滤波、方框滤波、中值滤波和高斯滤波
《OpenCv视觉之眼》Python图像处理六 :Opencv图像傅里叶变换和傅里叶逆变换原理及实现
《OpenCv视觉之眼》Python图像处理七 :Opencv图像处理之高通滤波和低通滤波原理及构造

 

上次博客介绍通过高通滤波和低通滤波对图像进行处理,包括轮廓提取和去噪,该系列教程其实是按照对图像的基本处理进行过程的讲解,包括读取图像、图像灰度处理、图像去噪、图像阈值化、图像形态学处理、然后才是图像轮廓提取,但由于高通滤波和低通滤波的原理是基于傅里叶变换的原理实现的,因此,放在一起进行讲解,同时也希望大家理解高通和低通滤波各自对应的作用,对于图像的轮廓提取的其他方法,在后面的博客也会讲到哦,大家记得收看!

 

对于图像去噪处理就先告一段落,接下来,是对图像处理的下一个阶段讲解了–图像阈值化处理,在OpenCV中,图像阈值化是图像轮廓提取的一个重要步骤,而且不同场景需要不同的阈值化方法进行处理,本次博客,林君学长主要带大家理解OpenCV常用的几种图像阈值化处理原理和不同阈值化方法库函数的使用方法,同样的,我们需要通过原理自己编写对应的图像阈值化函数,完成图像阈值化功能!

 

在介绍原理之前,首先我们应该清楚,图像阈值化处理一般是在图像去噪之后进行处理,阈值化处理的原因是因为图像轮廓提取对噪声比较敏感,因此,我们需要通过阈值化处理将噪声与需要的轮廓分开,达到我们需要的目的,图像处理的一般步骤如下所示,同时这也是学长对OpenCV图像处理教程讲解的步骤:

 

  1. 读取图像
  2. 图像灰度处理
  3. 图像去噪
  4. 图像阈值化
  5. 图像形态学处理
  6. 图像轮廓提取
  7. 目的操作

 

而本次博客,主要讲解的是OpenCV图像处理第四步,前面过程请参考之前博客哦!

 

[Python图像处理八] :Opencv图像处理之图像阈值化处理原理及函数

 

  • 一、图像阈值化原理及功能函数编写
    • 1、图像阈值化简介
    • 2、二进制阈值化
    • 3、反二进制阈值化
    • 4、截断阈值化
    • 5、阈值化为0
    • 6、反阈值化为0
  • 二、OpenCV图像阈值化库函数使用方法
    • 1、OpenCV库函数原型
    • 2、OpenCV库函数使用

 

图像二值化处理广泛应用于各行各业,比如生物学中的细胞图分割、交通领域的车牌设别等。在文化应用领域中,通过二值化处理将所需民族文物图像转换为黑白两色图,从而为后面的图像识别提供更好的支撑作用。下图表示图像经过各种二值化处理算法后的结果,其中“二进制阈值化”是最常见的黑白两色处理:

 

微信图片_20210218123719

 

一、图像阈值化原理及功能函数编写

 

1、图像阈值化简介

 

图像阈值化又称为图像二值化,主要用来提取图像中的目标图像,例如图像的整体轮廓,通过人为设定一个值,将大于该值得的像素通过不同的原理设置为不同的值,小于该值的像素同样设定为不同的值,例如二进制阈值化,将大于阈值的像素设置为255白色,将小于阈值的像素设定为0黑色,将一张灰度图像变为只有两种颜色的过程,就称为阈值化过程,通常会设定一个阈值T,通过T将图像的像素划分为两类:大于T的像素群和小于T的像素群。如下公式:

 

1613623061(1)

 

接下来,林君学长带大家了解不同阈值化处理的原理,并通过编写对于的阈值化函数吧!

 

2、二进制阈值化

 

1)、原理
通过人为设定阈值,然后遍历整张图的像素点,将大于阈值的像素点设置为255白色,将小于阈值的像素点设置为0黑色,达到对灰度图二值化的目的,公式如下:

 

1613623091(1)

 

2)、构造二进制阈值化函数

 

#导入库
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#定义二进制阈值化函数
def thresh_binary(gray,threshold):#传递灰度图像和阈值
    h,w=gray.shape[0:2]#获取图像属性
    #设计一张空白图像,同于存放二进制阈值化后的图像,防止对原图像进行修改
    threshold1= np.zeros((h,w), dtype=gray.dtype)
    for i in range(h):
        for j in range(w):
            if gray[i,j]>=threshold:#判断大于阈值,设置为255
                threshold1[i,j]=255
            else:
                threshold1[i,j]=0
    return threshold1

 

3)、读取图像添加噪声、灰度处理后调用二进制阈值化函数进行处理并显示

 

#读取图像
img=cv2.imread("my.jpg")
h,w=img.shape[0:2]
#加噪声
for i in range(3000):    #添加3000个噪声点
    x = np.random.randint(0, h) 
    y = np.random.randint(0, w)    
    img[x,y,:] = 255
#图像灰度处理
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#调用二进制阈值函数
threshold=thresh_binary(gray,127)#传递灰度图像,并设置阈值为127
#图像显示
plt.subplot(121), plt.imshow(gray,'gray'), plt.title('原灰度图像')
plt.axis('off')
plt.subplot(122), plt.imshow(threshold,'gray'), plt.title('二进制阈值化')
plt.axis('off')

 

微信图片_20210218123837

 

可以看到,在进行二进制阈值化之后,灰度图像的椒盐噪声被我们很好的消除,设置椒盐噪声的时候,一般为255白色,因此,将阈值设置合理,低于噪声像素,我们就可以消除轮廓之外的噪声点,但不是消除噪声的主要方法哦,这只是为了降低后续图像轮廓提取步骤对噪声的敏感程度!接下来的步骤讲解,将不添加噪声了哦,大家明白原理就好,简化一下代码。

 

3、反二进制阈值化

 

1)、原理
反二进制阈值化原理和二进制阈值化原理刚好相反,它的原理的将大于阈值的像素点的像素设置为0黑色,将小于阈值的像素点的像素设置为255黑色,原理公式如下所示:

 

1613623139(1)

 

2)、反二进制阈值化功能函数构造

 

'''
图像反二进制阈值化
'''
#导入库
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#定义反二进制阈值化函数
def thresh_binary_inv(gray,threshold):#传递灰度图像和阈值
    h,w=gray.shape[0:2]#获取图像属性
    #设计一张空白图像,同于存放反二进制阈值化后的图像,防止对原图像进行修改
    threshold1= np.zeros((h,w), dtype=gray.dtype)
    for i in range(h):
        for j in range(w):
            if gray[i,j]>=threshold:#判断大于阈值,设置为0
                threshold1[i,j]=0
            else:
                threshold1[i,j]=255
    return threshold1

 

3)、读取图像灰度化,然后调用反二进制阈值化函数处理,并观察图像

 

#读取图像
img=cv2.imread("my.jpg")
h,w=img.shape[0:2]
#图像灰度处理
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#调用反二进制阈值函数
threshold=thresh_binary_inv(gray,127)#传递灰度图像,并设置阈值为127
#图像显示
plt.subplot(121), plt.imshow(gray,'gray'), plt.title('原灰度图像')
plt.axis('off')
plt.subplot(122), plt.imshow(threshold,'gray'), plt.title('反二进制阈值化')
plt.axis('off')

 

微信图片_20210218123930

 

由图像可观察出,反二进制阈值化处理后的图像与二进制阈值化处理后的图像颜色刚好相反,根据不同的图像可选择不同的阈值化处理哦!

 

4、截断阈值化

 

1)、原理
截断阈值化原理是设定一个阈值,将像素点中像素值与阈值进行比较,当像素值大于阈值时,将该点像素值设置为阈值;当像素值小于阈值时,该像素点像素值不改变,原理公式如下所示:

 

1613623189(1)

 

2)、截断阈值化功能函数构造

 

'''
图像截断阈值化
'''
#导入库
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#定义截断阈值化函数
def thresh_trunc(gray,threshold):#传递灰度图像和阈值
    h,w=gray.shape[0:2]#获取图像属性
    #设计一张空白图像,同于存放截断阈值化后的图像,防止对原图像进行修改
    threshold1= np.zeros((h,w), dtype=gray.dtype)
    for i in range(h):
        for j in range(w):
            if gray[i,j]>=threshold:#判断大于阈值,设置为阈值
                threshold1[i,j]=threshold
            else:
                threshold1[i,j]=gray[i,j]
    return threshold1

 

3)、读取图像灰度化,并调用截断阈值化函数,显示结果

 

#读取图像
img=cv2.imread("my.jpg")
h,w=img.shape[0:2]
#图像灰度处理
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#调用截断阈值函数
threshold=thresh_trunc(gray,127)#传递灰度图像,并设置阈值为127
#图像显示
plt.subplot(121), plt.imshow(gray,'gray'), plt.title('原灰度图像')
plt.axis('off')
plt.subplot(122), plt.imshow(threshold,'gray'), plt.title('截断阈值化')
plt.axis('off')

 

微信图片_20210218124016

 

5、阈值化为0

 

1)、原理
设定阈值,遍历图像像素,如果像素点对应像素值大于阈值,该像素值保持不变;如果小于阈值,将该像素值设为0,原理公式如下所示:

 

1613623240(1)

 

2)、阈值化为0功能函数构造

 

'''
图像阈值化为0
'''
#导入库
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#定义阈值化为0函数
def thresh_tozero(gray,threshold):#传递灰度图像和阈值
    h,w=gray.shape[0:2]#获取图像属性
    #设计一张空白图像,同于存放阈值化后为0的图像,防止对原图像进行修改
    threshold1= np.zeros((h,w), dtype=gray.dtype)
    for i in range(h):
        for j in range(w):
            if gray[i,j]>=threshold:#判断大于阈值,保持不变
                threshold1[i,j]=gray[i,j]
            else:
                threshold1[i,j]=0
    return threshold1

 

3)、调用阈值化为0函数进行阈值化处理并显示

 

#读取图像
img=cv2.imread("my.jpg")
h,w=img.shape[0:2]
#图像灰度处理
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#调用阈值化为0函数
threshold=thresh_tozero(gray,127)#传递灰度图像,并设置阈值为127
#图像显示
plt.subplot(121), plt.imshow(gray,'gray'), plt.title('原灰度图像')
plt.axis('off')
plt.subplot(122), plt.imshow(threshold,'gray'), plt.title('值化为0')
plt.axis('off')

 

微信图片_20210218124109

 

6、反阈值化为0

 

1)、原理
反阈值为0同样的,遍历图像,像素点像素值大于阈值,将像素值设置为0;小于阈值,则像素值保持不变,原理公式如下所示:

 

1613623290(1)

 

2)、反阈值化为0功能函数构造

 

'''
反图像阈值化为0
'''
#导入库
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#定义阈值化为0函数
def thresh_tozero_inv(gray,threshold):#传递灰度图像和阈值
    h,w=gray.shape[0:2]#获取图像属性
    #设计一张空白图像,同于存放反阈值化后为0的图像,防止对原图像进行修改
    threshold1= np.zeros((h,w), dtype=gray.dtype)
    for i in range(h):
        for j in range(w):
            if gray[i,j]>=threshold:#判断大于阈值,设置为0
                threshold1[i,j]=0
            else: #判断小于阈值,保持不变
                threshold1[i,j]=gray[i,j]
    return threshold1

 

3)、调用反阈值化为0函数进行阈值化处理,并显示处理结果

 

#读取图像
img=cv2.imread("my.jpg")
h,w=img.shape[0:2]
#图像灰度处理
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#调用反阈值化为0函数
threshold=thresh_tozero_inv(gray,127)#传递灰度图像,并设置阈值为127
#图像显示
plt.subplot(121), plt.imshow(gray,'gray'), plt.title('原灰度图像')
plt.axis('off')
plt.subplot(122), plt.imshow(threshold,'gray'), plt.title('值化为0')
plt.axis('off')

 

微信图片_20210218124200

 

以上就是OpenCV中图像阈值化处理的方法原理,接下来,林君学长将介绍OpenCV中对图像阈值化处理的库函数的介绍及使用,一起来看吧!

 

二、OpenCV图像阈值化库函数使用方法

 

在OpenCV图像处理中,将上诉所写的5中方法集成到一个函数中进行使用,通过传递每种方法对应的参数进行不同阈值化方法的调用

 

1、OpenCV库函数原型

 

1)、函数原型:ret,threshold1=cv2.threshold(gray,threshold,MaxP,type)

  • threshold1:阈值化处理的结果图像
  • gray:需要阈值化处理的灰度图像
  • threshold:需要设定的阈值
  • MaxP:像素最大值(默认填写255)
  • type:参数类型,通过输入不同的参数确定不同的阈值化处理方法(掌握该函数使用的重点)

 

其中type参数对应不同的阈值处理方法,具体参数对于方法如下所示:

  • cv2.THRESH_BINARY ————-对应二进制阈值化
  • cv2.THRESH_BINARY_INV ——对应反二进制阈值化
  • cv2.THRESH_TRUNC ————-对应截断阈值化
  • cv2.THRESH_TOZERO ———–对应阈值化为0
  • cv2.THRESH_TOZERO_INV —-对应反阈值化0

 

接下来,通过OpneCV阈值化库函数进行不同阈值化的处理吧!

 

2、OpenCV库函数使用

 

#opencv阈值化库函数使用
#导入函数库
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread('my.jpg')
#图像灰度处理
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  
#OpenCV阈值化库函数中不同阈值化方法处理
ret,thresh1=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  #二进制阈值化
ret,thresh2=cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)  #反二进制阈值化
ret,thresh3=cv2.threshold(gray,127,255,cv2.THRESH_TRUNC)  #截止阈值化
ret,thresh4=cv2.threshold(gray,127,255,cv2.THRESH_TOZERO)  #阈值化为0
ret,thresh5=cv2.threshold(gray,127,255,cv2.THRESH_TOZERO_INV) #反阈值化为0
#显示结果
titles = ['灰度图像','二进制阈值化','反二进制阈值化','截止阈值化','阈值化为0','反阈值化为0']  
images = [gray, thresh1, thresh2, thresh3, thresh4, thresh5]  
for i in range(len(titles)):  
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')  #2行3列进行图像显示
    plt.title(titles[i])  #图像标题
    plt.axis('off')  #关闭坐标轴
plt.show()

 

微信图片_20210218124221

 

以上就是图像阈值化处理的不同处理方法及原理,希望通过理解原理了解如何对OpenCV图像库进行使用,并且,针对不同的图像选择不同的图像阈值化方法可以达到更好的效果哦,对于一张图像,根据他去噪后的灰度图选择不同的阈值化处理,可以在图像轮廓提取中得到更好的结果,这种更好的结果得益于我们选择阈值化处理的方法,从而降低轮廓提取算法对噪声的敏感程度!

 

以上就是本次博客的全部内容,遇到问题的小伙伴记得留言评论,学长看到会为大家进行解答的,这个学长不太冷!

 

一个人的记忆就是一座城市,时间腐蚀着一切建筑,把高楼和道路全部沙化。如果你不往前走,就会被沙子掩埋。所以我们泪流满面,步步回头,可是只能往前走 ——从你的全世界路过

 

陈一月的又一天编程岁月^ _ ^

发表评论

后才能评论