opencv 形态学变换

形态学变换

  • [1. 核](#1. 核)
  • 2.腐蚀(cv2.erode)
  • [3. 膨胀(cv2.dilate)](#3. 膨胀(cv2.dilate))
  • [4. 开运算(cv.MORPH_OPEN)](#4. 开运算(cv.MORPH_OPEN))
  • [5. 闭运算(cv2.MORPH_CLOSE)](#5. 闭运算(cv2.MORPH_CLOSE))
  • [6. 礼帽运算(找出增多的白色区域)](#6. 礼帽运算(找出增多的白色区域))
  • [7. 黑帽运算](#7. 黑帽运算)
  • [8. 形态学梯度](#8. 形态学梯度)

形态学变换(Morphological Transformations)是一种 基于形状的简单变换,它的处理对象通常是二值化图像 。形态学变换有两个输入,一个输出:输入为 原图像、核 (结构化元素),输出为形态学**变换后的图像。**其基本操作有腐蚀和膨胀,这两种操作是相反的,即较亮的像素会被腐蚀和膨胀。下面我们来说一下核、腐蚀与膨胀的概念。

1. 核

其实在上一章节自适应二值化中,我们已经接触过核了,还记得吗?就是那个在原图中不断滑动计算的3*3的小区域,那其实就是一个3*3的核。

核(kernel)其实就是一个小区域,通常为3*3、5*5、7*7大小,有着其自己的结构,比如矩形结构、椭圆结构、十字形结构,如下图所示。通过不同的结构可以对不同特征的图像进行形态学操作的处理。

2.腐蚀(cv2.erode)

腐蚀操作 就是使用核在原图(二值化图)上进行从左到右、从上到下的滑动(也就是从图像的左上角开始,滑动到图像的右下角)。在滑动过程中,令核值为1的区域与被核覆盖的对应区域进行相乘,得到其最小值,该最小值就是卷积核覆盖区域的中心像素点的新像素值 ,接着继续滑动。由于操作图像为二值图,所以不是黑就是白,这就意味着,在被核值为1覆盖的区域内,只要有黑色(像素值为0),那么该区域的中心像素点必定为黑色(0)。这样做的结果就是会将二值化图像中的白色部分尽可能的压缩,如下图所示,该图经过腐蚀之后,"变瘦"了。

腐蚀操作的详细流程

腐蚀原理的代码:

python 复制代码
 '''腐蚀操作------原理'''
    img=np.zeros((10,10),dtype=np.uint8)
    img[3:7,3:7]=255
    img[2,2]=10
    print(img)
    print("="*20)
    kernel=np.ones((3,3),dtype=np.uint8)#填充了一个全1的核
    img2=cv2.erode(img,kernel=kernel)#第一个填入一个二值图,
    print(img2)
    '''
     [  0   0  10   0   0   0   0   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]]
====================
[[  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0 255 255   0   0   0   0]
 [  0   0   0   0 255 255   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]]
    '''

由上面代码可以知道腐蚀是以每个元素为中心做一个3*3的全1的核找到最小值填充到核的中心

腐蚀操作代码部分:

python 复制代码
 '''腐蚀操作'''
    img=cv2.imread(r'../15day4.10\src\long.png',cv2.IMREAD_GRAYSCALE)
    kernel=np.ones((3,3),dtype=np.uint8)#填充了一个全1的核
    img_erode=cv2.erode(img,kernel=kernel,iterations=2)#表示进行腐蚀两次
    cv2.imshow('img',img)
    cv2.imshow("img_erode",img_erode)
    cv2.waitKey(0)

注意:

  • 腐蚀的本质是输出将一个以一个像素点为中心的核的最小值,若是上图则是白色被腐蚀了(白色变少了)
  • 腐蚀可以去除图像中的白色噪点

3. 膨胀(cv2.dilate)

膨胀与腐蚀刚好相反,膨胀操作就是使用核在原图(二值化图)上进行从左到右、从上到下的滑动(也就是从图像的左上角开始,滑动到图像的右下角),在滑动过程中,令核值为1的区域与被核覆盖的对应区域进行相乘,得到其最大值 ,该最大值就是核覆盖区域的中心像素点的新像素值,接着继续滑动。由于操作图像为二值图,所以不是黑就是白,这就意味着,在卷积核覆盖的区域内,只要有白色(像素值为255),那么该区域的中心像素点必定为白色(255)。这样做的结果就是会将二值化图像中的白色部分尽可能的扩张,如下图所示,该图经过膨胀之后,"变胖"了。

膨胀的详细操作

膨胀原理代码:

python 复制代码
 '''膨胀操作------原理'''
    img=np.zeros((10,10),dtype=np.uint8)
    img[3:7,3:7]=255
    img[2,2]=10
    img[2,4]=100
    print(img)
    print("="*20)
    kernel=np.ones((3,3),dtype=np.uint8)#填充了一个全1的核
    img2=cv2.dilate(img,kernel=kernel)#第一个填入一个二值图,
    print(img2)
    '''
    [[  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0  10   0 100   0   0   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0 255 255 255 255   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]]
====================
[[  0   0   0   0   0   0   0   0   0   0]
 [  0  10  10 100 100 100   0   0   0   0]
 [  0  10 255 255 255 255 255 255   0   0]
 [  0  10 255 255 255 255 255 255   0   0]
 [  0   0 255 255 255 255 255 255   0   0]
 [  0   0 255 255 255 255 255 255   0   0]
 [  0   0 255 255 255 255 255 255   0   0]
 [  0   0 255 255 255 255 255 255   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]]
    '''

由上面代码可以知道腐蚀是以每个元素为中心做一个3*3的全1的核找到最大值填充到核的中心

膨胀的操作的代码:

python 复制代码
'''膨胀操作'''
    img=cv2.imread(r'../15day4.10\src\long.png',cv2.IMREAD_GRAYSCALE)
    kernel=np.ones((3,3),dtype=np.uint8)
    img_dilate=cv2.dilate(img,kernel=kernel,iterations=3)
    cv2.imshow('img',img)
    cv2.imshow("img_dilate",img_dilate)
    cv2.waitKey(0)


注意:

  • 膨胀的本质是输出将一个以一个像素点为中心的核的最大值,若是上图则是白色扩大了
  • 膨胀可以去除图像中的黑色噪点

4. 开运算(cv.MORPH_OPEN)

开运算是先腐蚀后膨胀 ,其作用 是:分离物体,消除小区域。特点 :消除噪点,去除小的干扰块,而不影响原来的图像

代码如下:

python 复制代码
 '''开运算:先腐蚀后膨胀'''
    img=cv2.imread(r'../15day4.10\src\open.png',cv2.IMREAD_GRAYSCALE)
    kernel=np.ones((3,3),dtype=np.uint8)
    img_open=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel=kernel)
    cv2.imshow('img',img)
    cv2.imshow("img_open",img_open)
    cv2.waitKey(0)

5. 闭运算(cv2.MORPH_CLOSE)

闭运算与开运算相反,是先膨胀后腐蚀作用 是消除/"闭合"物体里面的孔洞,特点:可以填充闭合区域

代码如下:

python 复制代码
'''闭运算:先膨胀后腐蚀'''
    img=cv2.imread(r'../15day4.10\src\car.png',cv2.IMREAD_GRAYSCALE)
    kernel=np.ones((3,3),dtype=np.uint8)
    img_close=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel=kernel)
    cv2.imshow('img',img)
    cv2.imshow("img_close",img_close)
    cv2.waitKey(0)    

6. 礼帽运算(找出增多的白色区域)

cv2.MORPH_TOPHAT

原图像与"开运算"的结果图之差,因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

礼帽运算用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用礼帽运算进行背景提取(找到原图中的白色噪点

代码如下:

python 复制代码
'''礼帽运算'''   
    img=cv2.imread(r'../15day4.10\src\open.png',cv2.IMREAD_GRAYSCALE)
    kernel=np.ones((5,5),np.uint8)
    img2=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel=kernel)
    cv2.imshow('img',img)
    cv2.imshow('img2',img2)
    cv2.waitKey(0) 

7. 黑帽运算

cv2.MORPH_BLACKHAT

黑帽运算为"闭运算"的结果图与原图像之差,

黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。

黑帽运算用来分离比邻近点暗一些的斑块

代码如下:

python 复制代码
'''黑帽运算'''
    img=cv2.imread(r'../15day4.10\src\car.png',cv2.IMREAD_GRAYSCALE)
    kernel=np.ones((3,3),np.uint8)
    img2=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel=kernel)
    cv2.imshow('img',img)
    cv2.imshow('img2',img2)
    cv2.waitKey(0) 

8. 形态学梯度

cv2.MORPH_GRADIENT

形态学梯度是一个基于结构元素的图像处理方法,它通过比较原图像与膨胀图和腐蚀图之间的差异来突出图像边缘特征。具体来说,对于图像中的每个像素点,其形态学梯度值是该像素点在膨胀后的图像值与其在腐蚀后的图像值之差 。这样得到的结果通常能够强化图像的边缘信息,并且对噪声有一定的抑制作用

代码如下:

python 复制代码
  '''形态学梯度'''   
    img=cv2.imread(r'../15day4.10\src\car.png',cv2.IMREAD_GRAYSCALE)
    kernel=np.ones((3,3),np.uint8)
    img2=cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel=kernel) #gradient
    cv2.imshow('img',img)
    cv2.imshow('img2',img2)
    cv2.waitKey(0) 

形态学梯度是图像膨胀后与腐蚀后的差值,这样可以得到原图像的轮廓

相关推荐
微刻时光27 分钟前
影刀RPA网页自动化总结
运维·人工智能·python·低代码·自动化·rpa·影刀rpa
三天不学习40 分钟前
浅析AI大模型为何需要向量数据库?【入门基础】
数据库·人工智能·欧氏距离·向量数据库·余弦相似度
WenGyyyL1 小时前
研读论文——《用于3D工业异常检测的自监督特征自适应》
人工智能·python·深度学习·机器学习·计算机视觉·3d
fydw_7151 小时前
音频生成技术的前沿探索:从语音合成到智能Podcast
人工智能·音视频·语音识别
选型宝1 小时前
腾讯怎样基于DeepSeek搭建企业应用?怎样私有化部署满血版DS?直播:腾讯云X DeepSeek!
人工智能·ai·云计算·腾讯云·选型宝
多巴胺与内啡肽.1 小时前
OpenCV进阶操作:人脸检测、微笑检测
人工智能·opencv·计算机视觉
Wnq100721 小时前
基于 NanoDet 的工厂巡检机器人目标识别系统研究与实现
人工智能·机器学习·计算机视觉·目标跟踪·机器人·巡检机器人
一年春又来2 小时前
AI-02a5a6.神经网络-与学习相关的技巧-批量归一化
人工智能·神经网络·学习
kovlistudio2 小时前
机器学习第十讲:异常值检测 → 发现身高填3米的不合理数据
人工智能·机器学习
马拉AI2 小时前
解锁Nature发文小Tips:LSTM、CNN与Attention的创新融合之路
人工智能·cnn·lstm