OpenCV—形态学运算定义与实现

本文详细介绍了OpenCV中的形态学运算原理及应用,包括腐蚀、膨胀、开运算、闭运算等基本概念,并提供了丰富的代码示例。通过不同的结构元素进行演示,展示了如何调整图像边界、填充空洞及平滑边界。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、形态学运算

形态学运算是一种图像处理技术,用于改变图像的形状和结构。它主要基于图像的形态学特征,如图像的形状、大小、连接性等。

形态学运算通常使用结构元素来描述要操作的图像区域。结构元素是一个小的图像模板,可以是各种形状,如矩形、圆形或其他形状。

形态学运算主要包括膨胀、腐蚀、开运算和闭运算等操作。

  • 膨胀(dilation)运算可以扩展图像的边界,使图像中的目标区域增大。它通过将结构元素与图像中的每个像素进行逐个比较,如果有一个匹配的像素,则将目标像素置为目标像素值。

  • 腐蚀(erosion)运算可以缩小图像的边界,使图像中的目标区域减小。它通过将结构元素与图像中的每个像素进行逐个比较,只有当结构元素完全包含在目标像素周围时,目标像素才被保留。

  • 开运算(opening)是指先进行腐蚀运算,然后再进行膨胀运算。它可以用来平滑图像、消除噪声和分离连接的目标。

  • 闭运算(closing)是指先进行膨胀运算,然后再进行腐蚀运算。它可以用来填充图像中的空洞、连接断裂的目标和平滑边界。

形态学运算与结构元素的选择取决于图像处理的具体应用和所需的效果。结构元素的形状和大小可以根据目标区域的特征进行选择,以便更好地提取目标或改变目标的形状和结构。

二、结构元素

形态学元素常用的结构元素有:

  1. 点形态学元素:由一个点组成,表示图像中的单个像素。

  2. 线形态学元素:由一条线段组成,表示图像中的直线。

  3. 十字形态学元素:由两条线段交叉组成,表示图像中的十字。

  4. 方形形态学元素:由一个方形区域组成,表示图像中的矩形。

  5. 圆形形态学元素:由一个圆形区域组成,表示图像中的圆形。

示例:

  • 点形态学元素:[1]
  • 线形态学元素:[0,0,1,0,0]
  • 十字形态学元素:[0,1,0,1,0]
  • 方形形态学元素:[[1,1,1],[1,1,1],[1,1,1]]
  • 圆形形态学元素:[[0,1,0],[1,1,1],[0,1,0]]

使用Mat_模板类自定义5×5大小十字形、菱形、方形、x形结构元素: 

    cv::Mat_<uchar> cross(5,5);  
    cv::Mat_<uchar> diamond(5,5);  
    cv::Mat_<uchar> x(5,5);  
    cv::Mat_<uchar> square(5,5);  
  
     // Creating the cross-shaped structuring element  
    cross <<  
          0, 0, 1, 0, 0,  
          0, 0, 1, 0, 0,  
          1, 1, 1, 1, 1,  
          0, 0, 1, 0, 0,  
          0, 0, 1, 0, 0;  
            
     // Creating the diamond-shaped structuring element  
     diamond <<  
          0, 0, 1, 0, 0,  
          0, 1, 1, 1, 0,  
          1, 1, 1, 1, 1,  
          0, 1, 1, 1, 0,  
          0, 0, 1, 0, 0;  
            
      // Creating the x-shaped structuring element  
      x <<  
          1, 0, 0, 0, 1,  
          0, 1, 0, 1, 0,  
          0, 0, 1, 0, 0,  
          0, 1, 0, 1, 0,  
          1, 0, 0, 0, 1;  
  
      // Creating the square-shaped structuring element  
      square <<  
          1, 1, 1, 1, 1,  
          1, 1, 1, 1, 1,  
          1, 1, 1, 1, 1,  
          1, 1, 1, 1, 1,  
          1, 1, 1, 1, 1;  
<span style="white-space:pre">    </span> //display x-shaped structuring element  
     cout<<endl<<"x-shaped structuring element"<<endl<<endl;  
     int xnr = x.rows;  
     int xnl = x.cols;  
     for(int j = 0;j<nr;j++)  
     {  
        char *data = x.ptr<char>(j);  
        for(int i = 0; i<nl; i++)  
        {  
            int value = data[i];  
            cout<<value<<" ";  
        }  
        cout<<endl;  
     }  

三、腐蚀运算

腐蚀运算是数学形态学中的一种基本操作,用于图像处理和计算机视觉领域。它是一种局部操作,通过对图像中的每个像素进行处理,使其与周围像素进行比较,并根据特定的规则来更新像素的值。

数学定义: 腐蚀运算可以被定义为将图像中的每个像素与其周围的像素进行比较,并取最小值作为新像素的值。这可以用以下公式表示: E(x, y) = min{I(x+i, y+j) | (x+i, y+j) ∈ S}

其中,E(x, y)表示经过腐蚀运算后的新像素值,I(x, y)表示原始图像中的像素值,(x+i, y+j)表示周围像素的位置,S表示结构元素,用于指定腐蚀运算的邻域大小和形状。结构元素可以是任何形状,如方形、圆形或十字形。

意义: 腐蚀运算在图像处理中有着重要的意义。它可以用于去除噪声、分割图像、提取图像中的重要特征等。

  1. 去除噪声:由于腐蚀运算会将像素值更新为周围像素的最小值,它可以有效地去除图像中的小尺寸噪声。通过适当选择结构元素的大小和形状,可以去除不同尺寸和形状的噪声。

  2. 分割图像:腐蚀运算可以将图像中相邻的区域合并在一起,从而分割图像。通过多次应用腐蚀运算,可以使相邻区域逐渐合并,直到达到所需的分割效果。

  3. 特征提取:腐蚀运算可以用于提取图像中的边缘、细线条等细节特征。通过将原始图像与腐蚀后的图像进行差异化操作,可以获得图像中的边缘信息。

总之,腐蚀运算在图像处理中起着重要作用,可以对图像进行去噪、分割和特征提取等操作,从而提高图像的质量和可用性。

腐蚀的作用

腐蚀是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。

// Read input image  
    cv::Mat image= cv::imread("binary.bmp");  
    if (!image.data)  
        return 0;   
// Display the image  
    cv::namedWindow("Image");  
    cv::imshow("Image",image);  
// Erode the image  
    cv::Mat eroded;  
    cv::erode(image,eroded,cv::Mat());//cv::Mat()为空矩阵,此时采用默认3*3正方形结构元素  
// Display the eroded image  
    cv::namedWindow("Eroded Image");  
    cv::imshow("Eroded Image",eroded);  
// Erode the image with a larger s.e.定义更大的结构元素  
    cv::Mat element(7,7,CV_8U,cv::Scalar(1));  
 // Display the eroded image by large s.e.  
    cv::erode(image,eroded,element);  
    cv::namedWindow("Eroded Image (7x7)");  
    cv::imshow("Eroded Image (7x7)",eroded);  
// Erode the image 3 times.腐蚀3次  
    cv::erode(image,eroded,cv::Mat(),cv::Point(-1,-1),3);//cv::Point(-1,-1)表示原点是矩阵的中心点  
// Display the eroded image  
    cv::namedWindow("Eroded Image (3 times)");  
    cv::imshow("Eroded Image (3 times)",eroded);  
    cv::waitKey(0);  

原始二值图像

3×3正方形结构元素腐蚀结果

7×7正方形结构元素腐蚀结果

3×3正方形结构元素腐蚀3次结果

四、膨胀运算

膨胀运算是数学中的一种形态学变换操作,通常用于图像处理和形态学操作中。它可以用来扩大或放大图像中的特定区域或结构,使其更加突出或明显。

在二值图像处理中,膨胀运算可以将图像中的物体边界向外扩展。它是通过在图像中滑动一个结构元素(也称为窗口或模板),并将窗口内与结构元素相重叠的所有像素点都设置为1(或白色),来实现的。

在灰度图像处理中,膨胀运算可以增强图像的亮度或灰度级别。它通过将窗口内的像素点的最大值作为窗口中心像素点的新值,来实现对图像进行膨胀操作。

膨胀运算在图像处理中的意义主要体现在以下几个方面:

  1. 填充空洞:膨胀运算可以将图像中的孔洞或空洞填充起来,使其更加完整。
  2. 连接分离的物体:膨胀运算可以连接相互靠近但并不完全接触的物体,使它们形成一个整体。
  3. 消除细小的噪声:膨胀运算可以帮助消除图像中的细小噪声,使图像更加清晰和平滑。
  4. 放大细节:膨胀运算可以放大图像中的细节或结构,使其更加突出和明显。
  5. 合并形状:膨胀运算可以将相邻的形状合并在一起,形成一个更大的形状。

总之,膨胀运算在图像处理中是一种重要的操作,可以用于多种目的,帮助改善图像的质量和特征。

膨胀的作用

也就是说,膨胀是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来填补物体中的空洞。

// Dilate the image  
    cv::Mat dilated;  
    cv::dilate(image,dilated,cv::Mat());  
// Display the dialted image  
    cv::namedWindow("Dilated Image");  
    cv::imshow("Dilated Image",dilated);  

3×3正方形结构元素膨胀结果

五、闭运算

形态学闭运算是一种数字图像处理操作,用于去除图像中小的细节和噪音,同时保留较大的结构和形状。

形态学闭运算的数学定义如下:给定一个二值图像A和一个结构元素B,形态学闭运算定义为A和B的膨胀运算的结果与B的腐蚀运算的结果之间的差,即闭运算(A, B) = 膨胀(腐蚀(A, B), B)。

形态学闭运算的意义在于可以平滑图像、填充空洞、消除小的噪音和细节,以改善图像的质量和清晰度。闭运算可以使边界更加连续,形状更加完整,从而更便于后续的图像分析和处理任务。它在图像分割、边缘检测和形状识别等领域中被广泛应用。

闭运算作用

闭运算用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积。基本上所有小到不能完整容纳结构元素的空隙或间隙,都会被闭运算消除(即连起来)。

cv::Mat element5(5,5,CV_8U,cv::Scalar(1));//5*5正方形,8位uchar型,全1结构元素  
cv::Mat closed;  
cv::morphologyEx(image, closed,cv::MORPH_CLOSE,element5);//高级形态学运算函数  
// Display the opened image  
cv::namedWindow("Closed Image");  
cv::imshow("Closed Image",closed);  
cv::waitKey(0);  

5×5正方形结构元素闭运算结果

六、开运算

形态学开运算是一种基本的形态学图像处理操作,包括两个步骤:先进行腐蚀操作,再进行膨胀操作。其数学定义如下:

设A为二值图像,B为结构元素,开运算定义如下:

A∘B = (A⊖B)⊕B

其中,⊖表示腐蚀操作,⊕表示膨胀操作。

开运算可用于去除图像中的小噪点、平滑图像边缘以及调整图像的形状。

其意义包括:

  1. 去除小噪点:开运算可以通过先腐蚀再膨胀的操作,消除图像中的小噪点,使得图像更加清晰。

  2. 平滑图像边缘:开运算可以平滑图像边缘,消除图像中的细小不连续区域,使得图像边缘更加光滑。

  3. 调整形状:开运算可以调整图像的形状。通过选择合适的结构元素,可以改变图像中对象的形状,并且保持图像的整体结构。

综上所述,开运算在形态学图像处理中具有去噪、平滑和形状调整的作用,常常用于预处理图像或提取感兴趣的图像特征。

开运算作用

用来背景中的消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。所有小到不能容纳结构元素的物体都会被移除。

[cpp]  view plain  copy
  1. cv::Mat element5(5,5,CV_8U,cv::Scalar(1));//5*5正方形,8位uchar型,全1结构元素  
  2. cv::Mat opened;  
  3. cv::morphologyEx(image, opened,cv::MORPH_OPEN,element5);  
  4. // Display the opened image  
  5. cv::namedWindow("Opened Image");  
  6. cv::imshow("Opened Image",opened);  
  7. cv::waitKey(0);  

5×5正方形结构元素开运算结果

七、自定义结构元素

除了使用常规的规则结构元素,我们也可以自定义结构元素。下面使用Mat类型的构造函数创建一个3×3十字型的结构元素。

  1. // 创建自定义结构元素  
    unsigned char m[9] = {  
            0,1,0,  
            1,1,1,  
            0,1,0     
        };  
    cv::Mat element1(3,3,CV_8U,m); //创建自定义矩阵element1  
    //显示该结构元素  
    int nr = element1.rows;  
    int nl = element1.cols;  
    for(int j = 0;j<nr;j++)  
    {  
        char *data = element1.ptr<char>(j);  
        for(int i = 0; i<nl; i++)  
        {  
            int value = data[i];  
            cout<<value<<" ";  
    }  
        cout<<endl;  
    }  
     // Display the eroded image by large s.e.  
        cv::erode(image,eroded,element1);  
        cv::namedWindow("Eroded Image (user define)");  
        cv::imshow("Eroded Image (user define)",eroded);  

自定义结构元素腐蚀结果

参考:
  1. OpenCV—形态学运算定义与实现_c++ opencv形态学-优快云博客
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩瀚之水_csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值