opencv图像处理-图像形态学

数学形态学是图像处理的重要工具,可用于获取图像边界提取骨架去除噪声检测角点,其应用覆盖
文字识别视觉检测医学图像处理等领域。

形态变换是一些基于图像形状的简单操作。形态学处理主要针对的是二值图像(在图像中任何像素点的灰度值只有 0 或 255)

两种基本的形态学算子是腐蚀膨胀

结构元素(内核)

在考察目标图像各部分之间的关系时,需要设计一种收集信息的“探针”,即结构元素。

  • 在图像中不断移动结构元素,就可以考察图像中各部间的关系。

  • 结构元素的形状包括矩形十字形椭圆形和菱形等,如果结构元素长宽相等,矩形和椭圆形将退化为正方形圆形

  • 一般来说,结构元素尺寸要明显小于目标图像的尺寸,选择不同形状和尺寸的结构元素可提取图像中的不同特征。

  • 结构元素本身也是一个图像集合,对于结构元素可以指定一个原点,将其作为结构元素参与形态学运算的参考点。原点可包含在结构元素中,也可不包含在结构元素中。

腐蚀操作

原理:

腐蚀是一种最基本的数学形态学运算,对给定的目标图像 X 和结构元素 S,将 S 在图像上移动,则对于每一个当前位置 x 有

opencv图像处理-图像形态学

即 S 对 X 腐蚀的结果是S 完全包含在 X 中时 S 的原点位置的集合

原始图像中的一个像素(无论是 1 还是 0)只有当内核下的所有像素都是 1 时才被认为是 1,否则它就会被侵蚀(变成 0)。
根据内核的大小,边界附近的所有像素都会被丢弃。
因此,前景物体的厚度或大小减小,或只是图像中的白色区域减小。它有助于去除小的白色噪声,分离两个连接的对象。


代码:

OpenCV 中采用 getStructuringElement()erode()函数实现结构元素的设定和图像腐蚀操作

cv2.getStructuringElement(eleType,ksize,point)

  • eleType: 结构元素类型,OpenCV 中定义了 3 种基本结构元素形状

     · MORPH_RECT  矩形
     . MORPH_CROSS  十字形
     . MORPH_ELLIPSE 椭圆形
    
  • ksize: 结构元素大小

  • point: 锚点(结构元素中心点)位置

dst=cv2.erode(src,kernel,iterations)

  • kernel: 卷积核
  • iterations: 迭代次数,默认为 1

import cv2 as cv
import numpy as np
img=cv.imread('pic.png',0)
# 通过getStructuringElement()设置结构元素
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3),(1,1))
# 还可以通过np.ones()函数设置卷积核
# kernel=np.ones((3,3),np.uint8)
# 腐蚀
erosion=cv.erode(img,kernel,iterations=2)
cv.imshow('original',img)
cv.imshow('erosion',erosion)
cv.waitKey(0)
cv.destroyAllWindows()

处理结果:

opencv图像处理-图像形态学

对比处理结果我们发现原图像中的白色噪声被腐蚀掉了。


膨胀操作

原理:

对给定的目标图像 X 和结构元素 S,将 S 在图像上移动,则对于每一个当前位置 x 有

opencv图像处理-图像形态学

即用 S 来膨胀 X 得到的集合是 S v S^{v} Sv的平移与 X 至少有一个公共的非零元素相交时,S 的原点位置的集合

( S v S^{v} Sv指 S 关于原点的映射)

与腐蚀操作相反(腐蚀虽然消除了白噪声,但也会压缩图像),但并不是互为逆运算
如果内核下至少有一个像素为“ 1”,则像素元素为“ 1”,图像就会膨胀。因此,它会增加图像中的白色区域或增加前景对象的大小。


代码:

dst=cv.dilate(src,kernel,iterations)

  • kernel: 卷积核
  • iterations: 迭代次数,默认为 1,进行一次膨胀
import cv2 as cv
import numpy as np
img=cv.imread('pic.png',0)
# 使用numpy库生成卷积核
kernel=np.ones((5,5),np.uint8)
erosion=cv.erode(img,kernel,iterations=2)# 腐蚀
cv.imshow('erosion',erosion)
# 膨胀
k=np.ones((3,3),np.uint8) # 使用3*3的卷积核
dliate=cv.dilate(erosion,k)
cv.imshow('dilate',dliate)
cv.waitKey(0)
cv.destroyAllWindows()

处理结果:

opencv图像处理-图像形态学

这里我们将腐蚀过后的二值图像进行膨胀操作


由于腐蚀和膨胀并不是互为逆运算,所以它们可以结合使用。在腐蚀和膨胀两个基本运算的基础上,可以构造出形态学运算簇

开运算

先对图像进行腐蚀然后膨胀其结果,称为开运算。对于消除噪音很有用

代码:

import cv2 as cv
import numpy as np
pic2=cv.imread('pic2.png',0)
# 开运算
k=np.ones((5,5),np.uint8)
erode1=cv.erode(pic2,k,iterations=1)
dilate1=cv.dilate(erode1,k)
cv.imshow('original',pic2)
cv.imshow('open',dilate1)
cv.waitKey(0)
cv.destroyAllWindows()

open= cv.morphologyEx(img, cv.MORPH_OPEN, kernel)


处理结果:
opencv图像处理-图像形态学


闭运算

先对图像进行膨胀然后腐蚀其结果,称为闭运算。

在关闭前景对象内部的小孔或对象上的小黑点时很有用。


代码:

import cv2 as cv
import numpy as np
pic1=cv.imread('pic1.png',0)
k=np.ones((5,5),np.uint8)
# 闭运算
dilate2=cv.dilate(pic1,k)
erode2=cv.erode(dilate2,k,iterations=1)
cv.imshow('original',pic1)
cv.imshow('close',erode2)
cv.waitKey(0)
cv.destroyAllWindows()

close = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)


处理结果:

opencv图像处理-图像形态学


形态学梯度

图像膨胀与腐蚀运算之差

可以用形态学梯度来突出边缘,保留物体的边缘轮廓


gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)

opencv图像处理-图像形态学

顶帽

原图与开运算之差

tophat = cv.morphologyEx(src, cv.MORPH_TOPHAT, kernel)

opencv图像处理-图像形态学

黑帽

闭运算与原图之差

blackhat = cv.morphologyEx(src, cv.MORPH_BLACKHAT, kernel)

opencv图像处理-图像形态学

上一篇:Linux /usr/src/kernels 目录为空的解决方法


下一篇:操作系统真相还原 第七章 中断