【OpenCV】形态学操作 - 图像平滑 - 边缘检测 - Laplacian算子

发布时间:2025-12-10 11:31:17 浏览次数:3


Ⅰ. 形态学操作

0x00 腐蚀和膨胀

腐蚀和膨胀是最基本的形态学操作,腐蚀和膨胀都是针对白色部分(高亮部分)而言的。

膨胀就是使图像中的高亮部分扩张,效果图拥有比原图更大的高亮区域;腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。膨胀是求局部最大值的操作,腐蚀是求局部最小值的操作。

腐蚀

操作:

用一个结构元素扫描图像中的每一个像素,用结构元素中的每一个像素与覆盖的像素做“与”操作,结果都为 1 ,则该像素为 1 ,否则为 0 。

即用卷积核扫描图像, 只不过腐蚀操作的卷积和一般都是1, 如果卷积核内所有像素点都是白色, 那么锚点即为白色。

操作:用一个结构元素扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“与”操作,如果都为 0 ,则该像素为 0 ,否则为 1 。

💬API

cv2.dilate(img,kernel,iterations)

参数:

  • img:要处理的图像
  • kernel:核结构
  • iterations:腐蚀的次数,默认为1

💎示例:

# 1.读取图像img = cv2.imread('sun.jpg')# 2.创建核结构kernel = np.ones((10, 10), np.uint8)# 3.图像的腐蚀与膨胀erosion_1 = cv2.erode(img, kernel, iterations=1) # 腐蚀erosion_2 = cv2.erode(img, kernel, iterations=2)erosion_3 = cv2.erode(img, kernel, iterations=3)dilate_1 = cv2.dilate(img, kernel, iterations=1)# 膨胀dilate_2 = cv2.dilate(img, kernel, iterations=2)dilate_3 = cv2.dilate(img, kernel, iterations=3)# 4.图像显示res_1 =np.hstack((erosion_1, erosion_2, erosion_3))res_2 =np.hstack((dilate_1, dilate_2, dilate_3))cv2.imshow('erosion', res_1)cv2.imshow('dilate', res_2)cv2.waitKey(0)cv2.destroyAllWindows()

 上面的腐蚀操作中,我们自行创建了一个的全 1 卷积核但是遇到复杂的图像操作时,我们不可能每次都自行指定卷积核,因此提供了获取卷积核的 APL.不需要我们手工创建卷积核。

getStructuringElement(shape, ksize[, anchor])

shape是指卷积核的形状, 注意不是指长宽, 是指卷积核中1形成的形状.

  • MORPH_RECT   卷积核中的1是矩形, 常用.
  • MORPH_ELLIPSE  椭圆
  • MORPH_CROSS  十字

0x01 开运算与闭运算

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

闭运算
先膨胀,再腐蚀
作用:消除“闭合”物体里面的孔洞,可以填充闭合区域

💬API

cv2.morphologyEx(img,op,kernel)

参数:

  • img: 要处理的图像
  • op:处理方式,若为开运算,则设为cv2.MORPH_OPEN;若为闭运算,则设为cv2.MORPH_CLOSE
  • kernel:核结构
     

 0x02 礼帽与黑帽

礼帽:用来分离比领近点亮一些的斑块。当一幅图像具有大幅背景的时候,而微小的物品比较有规律的情况下,可以使用礼帽运算作为背景提取。

礼帽 = 原始输入 -  开运算结果

cv2.morphologyEx(img,op,kernel)cv2.MORPH_TOPHAT#礼帽运算cv2.MORPH_BLACKHAT#黑帽运算


Ⅱ. 图像平滑

0x00图像噪声

概念:由于图像采集、处理、传输等过程不可避免的会受到噪声的污染,妨碍人们对图像理解及分析处理。常见的图像噪声有高斯噪声、椒盐噪声等。

1. 椒盐噪声
椒盐噪声也称为脉冲噪声,是图像中经常见到的一种噪声,它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。

椒盐噪声的成因可能是影像讯号受到突如其来的强烈干扰而产生、类比数位转换器或位元传输错误等。

例如失效的感应器导致像素值为最小值,饱和的感应器导致像素值为最大值。

 2. 高斯噪声

高斯噪声是指噪声密度函数服从高斯分布的一类噪声。

由于高斯噪声在空间和频域中数学上的易处理性,这种噪声(也称为正态噪声)模型经常被用于实践中。高斯随机变量z的概率密度函数由下式给出:

其中  表示灰度值,  表示  的平均值或期望值,  表示  的标准差。标准差的平方 ​  称为 的方差。

高斯函数的曲线如图所示

 

0x01图像平滑
概念:图像平滑从信号处理的角度看就是去除其中的高频信息,保留低频信息。因此我们可以对图像实施低通滤波。低通滤波可以去除图像中的噪声,对图像进行平滑。

根据滤波器的不同可分为均值滤波,高斯滤波,中值滤波, 双边滤波。

均值滤波
采用均值滤波模板对图像噪声进行滤除。令  表示中心在  点,

尺寸为  的矩形子图像窗口的坐标组。 均值滤波器可表示为:

由一个归一化卷积框完成的。它只是用卷积框覆盖区域所有像素的平均值来代替中心元素。

例如, 标准化的平均过滤器如下所示:

均值滤波的优点是算法简单,计算速度较快;

缺点是在去噪的同时去除了很多细节部分,将图像变得模糊。

💬API

cv.blur(src, ksize, anchor, borderType)

参数:

  •  src:输入图像
  •  ksize:卷积核的大小
  •  anchor:默认值 (-1,-1) ,表示核中心
  •  borderType:边界类型

高斯滤波

二维高斯是构建高斯滤波器的基础,其概率分布函数如下所示:

 的分布是一个突起的帽子的形状。这里的  可以看作两个值,一个是  方向的标准差  ,另一个是  方向的标准差  

​当  和  取值越大,整个形状趋近于扁平;

当  和取值越小,整个形状越突起。

正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。

计算平滑结果时,只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。

高斯平滑在从图像中去除高斯噪声方面非常有效。

高斯平滑的流程:

  •  首先确定权重矩阵
  • 图像噪声

    • 椒盐噪声:图像中随机出现的白点或者黑点
    • 高斯噪声:噪声的概率密度分布是正态分布

    参数:

    • src:传入的图像
    • ddepth:图像的深度
    • dx和dy:指求导的阶数,,沿着水平方向求导;,沿着垂直方向求导
    • ksize:是Sobel算子的大小,即卷积核的大小,必须为奇数,默认为3(若ksize= -1 ,就演变成的Scharr算子)
    • scale:缩放导数的比例常数,默认情况为没有伸缩系数
    • borderType:图像边界的模式,默认值为cv2.BORDER_DEFAULT

    Sobel函数求完导数后会有负值,还有会大于255的值。而原图像是uint8,即8位无符号数,所以Sobel建立的图像位数不够,会有截断。

    因此要使用16位有符号的数据类型,即cv2.CV_16S。

    处理完图像后,再使用cv2.convertScaleAbs( )函数将其转回原来的uint8格式,否则图像无法显示。

    Sobel算子是在两个方向计算的,最后还需要用cv2.addWeighted( )函数将其组合起来

    💬API

    Scale_abs = cv2.convertScaleAbs(src)#格式转换函数result = cv2.addWeighted(src1, alpha, src2, beta)#图像混合

    💎实例:

    1.若只处理x轴:

    img = cv2.imread('sun.jpg')sobel = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)cv2.imshow('sobel', sobel)cv2.waitKey(0) # 等待时间,毫秒级,0表示按任意键终止cv2.destroyAllWindows()

     2.处理x轴与y轴

    img = cv2.imread('sun.jpg')gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)sobelx = cv2.Sobel(gray_image,cv2.CV_64F, 1, 0, ksize=3)sobely = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3)sobelx = cv2.convertScaleAbs(sobelx)#convertScaleAbs 图像增强函数sobely = cv2.convertScaleAbs(sobely)sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)

    0x01 Laplacian算子

    Laplacian是利用二阶导数来检测边缘。因为图像是 "2维",我们需要在两个方向求导,如下式所示:

    那不连续的函数的二阶导数是:

     那使用的卷积核是:

     即中间点和周围比较

    边缘检测的原理

    • 基于搜索:利用一阶导数的最大值获取边界
    • 基于零穿越:利用二阶导数为0获取边界

    Sobel算子

    • 基于搜索的方法获取边界

    cv.sobel()

    cv.convertScaleAbs()

    cv.addweights()

    Laplacian算子

    • 基于零穿越获取边界

    cv.Laplacian()

    算子比较: 

    需要做网站?需要网络推广?欢迎咨询客户经理 13272073477