《OpenCv视觉之眼》Python图像处理九 :Opencv图像形态学处理之图像腐蚀与膨胀原理及方法

47
0
6天前

本专栏主要介绍如果通过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视觉之眼》Python图像处理八 :Opencv图像处理之图像阈值化处理原理及函数

 

上次博客我们讲到图像的阈值化处理的原理及函数构造,同时介绍了OpenCV中库函数的使用方法及参数,阈值化处理的目的就是降低图像轮廓提取对噪声的敏感程度,同时也对下一步图像形态学处理提供了完整性。

 

本次博客,林君学长将带大家了解图像形态学处理的基础形态学处理——图像的膨胀与腐蚀,了解原理,通过原理编写图像腐蚀与膨胀的功能算法,并为大家介绍OpenCV中图像膨胀与腐蚀的库函数的使用方法,一起学习吧!

 

  • 图像腐蚀膨胀主要是为了去除阈值化图像周围不需要的噪声,通过形态学处理,值保留完整的轮廓
  • 对腐蚀过的图像,进行膨胀处理,可以去除图像轮廓内部噪声,并且保持原有形状。
  • 对膨胀过的图像,进行腐蚀处理,可以去除图像轮廓外部噪声,并且保持原有形状。

 

[Python图像处理九] :Opencv图像形态学处理之图像腐蚀与膨胀原理及方法

 

  • 一、图像膨胀
    • 1、图像膨胀原理
    • 2、图像膨胀功能函数构造
    • 3、OpenCV图像膨胀库函数使用
  • 二、图像腐蚀
    • 1、图像腐蚀原理
    • 2、图像腐蚀功能函数构造
    • 3、OpenCV图像腐蚀库函数使用

 

一、图像膨胀

 

1、图像膨胀原理

 

1)、原理

 

图像膨胀主要针对的是阈值化后的图像(0或255)。图像膨胀类似于“领域被扩张”,将图像中的高亮区域或白色部分进行扩增粗化,其运行结果图比原图的高亮区域更大。其原理是:将核在原始图像中进行遍历,然后将原始图像遍历到的像素点的值与自定义卷积核(全为1的二维矩阵)得值进行与运算,像素点与对应核一 一对应进行与,当卷积核对应的元素值只要有一个为1时,设置卷积核中心值的像素点为1,如果全为0,,则其值设置为0,原理图如下所示:

 

2)、原理图

 

微信图片_20210220192332

 

微信图片_20210220192334

 

2、图像膨胀功能函数构造

 

1)、图像膨胀功能函数构造

 

'''
图像膨胀
'''
#整体显示
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
def dilate(img,size):
    #获取图像尺寸及通道数
    h,w=img.shape[:2]
    num=int((size-1)/2)
    #自定义空白图像,用于显示膨胀之后的图像
    img1=np.zeros((h,w),dtype=img.dtype)
    #图像灰度处理
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #图像阈值化
    ret, Binary = cv2.threshold(gray , 127, 255, cv2.THRESH_BINARY)
    for i in range(num,h-num):
        for j in range(num,w-num):
            sum=np.array([])
            for k in range(i-num,i+num+1):
                for l in range(j-num,j+num+1):
                    a=Binary[k,l] and 1  #每一个都与1进行与运算,也就是核函数进行与  255与1是1  0与1为0
                    sum=np.insert(sum,len(sum),a)  #将与的结果写入数组sum
            if (sum == 1).any()==True: #判断数组是否有1,如果是,则写255,如果不是,将0写入该点像素值
                img1[i,j]=255
            else:
                img1[i,j]=0
    return img1

 

2)、读取图像,调用图像膨胀函数进行图像膨胀处理,并显示结果

 

#读取图像
img=cv2.imread("g1.jpg")
#调用膨胀函数
img1=dilate(img,5)
#显示图像
titles = ['原图', '膨胀']  #标题
images = [img, img1]   #图像对比显示
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i],"gray")  
    plt.title(titles[i])    
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

微信图片_20210220192413

 

通过调整核大小和膨胀次数,可以增大膨胀区域,如下所示:
5×5核尺寸膨胀3次:

 

微信图片_20210220192425

 

7×7核尺寸,膨胀1次:

 

微信图片_20210220192439

 

在实际的图像处理中,自己通过调整参数进行图像膨胀处理,直到达到对图像处理的最终目的,例如如下轮廓提取,通过图像膨胀或者图像腐蚀找到最佳轮廓,然后通过轮廓提取算法进行图像轮廓提取!

 

3、OpenCV图像膨胀库函数使用

 

OpenCV中提供了图像膨胀的库函数,原型如下所示:

 

1)、库函数原型:dilate=cv2.dilate(img, kernel,num)

 

  • img:需要进行腐蚀操作的阈值图像
  • kernel:卷积核尺寸,例如输入(3,3)全为1的核kernel = np.ones((3,3), np.uint8)
  • num:需要进行膨胀的次数

 

2)、图像膨胀库函数使用

 

'''
图像膨胀opencv库函数
'''
#整体显示
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("g1.jpg")
#设置卷积核
kernel = np.ones((5,5), np.uint8)
#调用opencv库膨胀函数
img1=cv2.dilate(img,kernel,2)#5x5卷积核,膨胀2次
#显示图像
titles = ['原图', '膨胀']  #标题
images = [img, img1]   #图像对比显示
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i],"gray")  
    plt.title(titles[i])    
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

微信图片_20210220192458

 

我们可以你看到,函数膨胀将图像轮廓边粗,这可以填充图像内部空余部分,对图后续的轮廓提取有积极作用,可以理解为图像去噪的一种,但只针对小部分噪声,主要还得前面滤波去噪。

 

对于图像膨胀,可以在通过增加核尺寸大小和膨胀次数来扩大膨胀区域,下面讲解图像腐蚀原理及函数构造吧!

 

二、图像腐蚀

 

1、图像腐蚀原理

 

1)、原理

 

图像腐蚀主要针对的是阈值化后的图像(0或255)。图像腐蚀类似于“领域被蚕食”,将图像中的高亮区域或白色部分进行缩减细化,其运行结果图比原图的高亮区域更小。其原理是:将核在原始图像中进行遍历,然后将原始图像遍历到的像素点的值与自定义卷积核(全为1的二维矩阵)得值进行与运算,像素点与对应核一 一对应进行与,当卷积核对应的元素值均为1时,设置卷积核中心值的像素点为1,否则其值设置为0,原理图如下所示:

 

2)、原理图

 

微信图片_20210220192513

 

微信图片_20210220192516

 

2、图像腐蚀功能函数构造

 

1)、定义图像腐蚀函数

 

'''
图像腐蚀
'''
#整体显示
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
def erode(img,size):
    #获取图像尺寸及通道数
    h,w=img.shape[:2]
    num=int((size-1)/2)
    #自定义空白图像,用于显示腐蚀之后的图像
    img1=np.zeros((h,w),dtype=img.dtype)
    #图像灰度处理
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #图像阈值化
    ret, Binary = cv2.threshold(gray , 127, 255, cv2.THRESH_BINARY)
    for i in range(num,h-num):
        for j in range(num,w-num):
            sum=np.array([])
            for k in range(i-num,i+num+1):
                for l in range(j-num,j+num+1):
                    a=Binary[k,l] and 1  #每一个都与1进行与,也就是核函数进行与  255与1是1  0与1为0
                    sum=np.insert(sum,len(sum),a)  #将与的结果写入数组sum
            #print(sum)
            if (sum == 1).all()==True: #判断数组是否全为1,如果是,则将1写入255,如果不是,写0
                img1[i,j]=255
            else:
                img1[i,j]=0
    return img1

 

2)、读取图像,调用腐蚀函数进行图像腐蚀处理,并显示结果

 

#读取图像
img=cv2.imread("g1.jpg")
#调用腐蚀函数
img1=erode(img,5)
#显示图像
titles = ['原图', '腐蚀']  #标题
images = [img, img1]   #图像对比显示
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i],"gray")  
    plt.title(titles[i])    
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

微信图片_20210220192551

 

上面我们可以看出,经过腐蚀之后的图像,图像轮廓中细的部分我们认为噪声点,将会被腐蚀掉,达到去噪的效果!如果进行多次腐蚀或者增加核尺寸,轮廓部分也会被腐蚀掉,但由于通过原理编写算法,代码运行时间较久,就直接给出多次腐蚀后的结果,如下所示:

 

微信图片_20210220192609

 

3、OpenCV图像腐蚀库函数使用

 

在OpneCV中当然也会给出图像腐蚀的库函数啦,用法如下所示

 

1)、图像腐蚀函数原型:erode=cv2.erode(img, kernel,num)

 

  • img:需要进行腐蚀操作的阈值图像
  • kernel:卷积核尺寸,例如输入(3,3)全为1的核kernel = np.ones((3,3), np.uint8)
  • num:需要进行腐蚀的次数

 

2)、图像腐蚀库函数使用方法如下所示:

 

'''
图像腐蚀opencv库函数
'''
#整体显示
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("g1.jpg")
#设置卷积核
kernel = np.ones((5,5), np.uint8)
#调用opencv库腐蚀函数
img1=cv2.erode(img,kernel,2)#5x5卷积核,腐蚀2次
#显示图像
titles = ['原图', '腐蚀']  #标题
images = [img, img1]   #图像对比显示
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i],"gray")  
    plt.title(titles[i])    
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

微信图片_20210220192635

 

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

 

我希望在平淡如水的日子里,我依然是你鲜活而快乐的源泉,微笑的理由。
我希望在人烟嘈杂的时候,我能伸开双臂保护你为你圈出一个安静的世界。
我希望我们都是彼此的刻骨铭心,不管之前有过多少错过的感情,都不怕。
我希望我们都是彼此朝朝暮暮的相濡以沫,我希望能成为别人羡慕的对象。
我希望从此以后都不用在努力寻找,我希望真的到你为止,我希望就是你

 

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

发表评论

后才能评论