当前位置: 首页 > news >正文

OpenCV入门(17):图像形态学操作

图像形态学操作是图像处理中的一种重要技术,主要用于处理二值图像(即黑白图像)。

OpenCV 中的图像形态学操作是图像处理中的重要工具,通过腐蚀、膨胀、开运算、闭运算和形态学梯度等操作,可以实现对图像的噪声去除、对象分离、边缘检测等效果。掌握这些操作有助于更好地处理和分析图像数据。

以下是 OpenCV 中常用的形态学操作及其函数:

操作 函数 说明 应用场景
腐蚀 cv::erode() 用结构元素扫描图像,如果结构元素覆盖的区域全是前景,则保留中心像素。 去除噪声、分离物体。
膨胀 cv::dilate() 用结构元素扫描图像,如果结构元素覆盖的区域存在前景,则保留中心像素。 连接断裂的物体、填充空洞。
开运算 cv::morphologyEx() 先腐蚀后膨胀。 去除小物体、平滑物体边界。
闭运算 cv::morphologyEx() 先膨胀后腐蚀。 填充小孔洞、连接邻近物体。
形态学梯度 cv::morphologyEx() 膨胀图减去腐蚀图。 提取物体边缘。
顶帽运算 cv::morphologyEx() 原图减去开运算结果。 提取比背景亮的细小物体。
黑帽运算 cv::morphologyEx() 闭运算结果减去原图。 提取比背景暗的细小物体。

一、腐蚀(erode)

腐蚀操作是一种缩小图像中前景对象的过程。腐蚀操作通过将结构元素与图像进行卷积,只有当结构元素完全覆盖图像中的前景像素时,中心像素才会被保留,否则会被腐蚀掉。


1.1 API

erode( InputArray src, OutputArray dst, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
  • src:表示需要处理的原始图像
  • dst:表示处理后的输出图像
  • kernel:结构元素
  • anchor:锚点,默认中心像素;
  • iterations:迭代处理的次数;

1.2 示例代码

#include<iostream>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_erosion;   // 定义输入图像,灰度图像,腐蚀图像image = imread("font.jpg");  // 读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);// 转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);// 腐蚀Mat se = getStructuringElement(MORPH_RECT, Size(5, 5)); // 构造矩形结构元素erode(image_gray, image_erosion, se, Point(-1, -1), 1); // 执行腐蚀操作imshow("image_erosion", image_erosion);waitKey(0);return 0;
}

腐蚀操作是使用最小像素值用来替换锚点的像素,可以看到通过取最小值,使得图像中形状变细,效果图如下所示:

Blog_OpenCV_Learnl_80.png


二、膨胀(dilate)

膨胀操作与腐蚀相反,它是一种扩大图像中前景对象的过程。膨胀操作通过将结构元素与图像进行卷积,只要结构元素与图像中的前景像素有重叠,中心像素就会被保留。


2.1 API

dilate( InputArray src, OutputArray dst, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
  • src:表示需要处理的原始图像
  • dst:表示处理后的输出图像
  • kernel:结构元素
  • anchor:锚点,默认中心像素;
  • iterations:迭代处理的次数;

2.2 示例代码

#include<iostream>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_dilate;   // 定义输入图像,灰度图像,膨胀图像image = imread("font.jpg");  // 读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);// 转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);// 膨胀Mat se = getStructuringElement(0, Size(5, 5)); // 构造矩形结构元素dilate(image_gray, image_dilate, se, Point(-1, -1), 1); // 执行膨胀操作imshow("image_dilate", image_dilate);waitKey(0);return 0;
}

膨胀操作是使用最小像素值用来替换锚点的像素,可以看到通过取最大值,使得图像形状变粗,效果图如下所示:

Blog_OpenCV_Learnl_81.png


三、开运算(open)

开运算是先腐蚀后膨胀的组合操作。开运算主要用于去除图像中的小噪声或分离连接的对象。

开操作的作用:

  • 常用于图像中的噪声消除
  • 通过对小对象放在背景中来从图像的前景中移除;

3.1 API

void morphologyEx( InputArray src, OutputArray dst,int op, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
  • src:源图像。
  • dst:与源图像大小和类型相同的目标图像。
  • op:形态学操作类型,开运算使用 MORPH_OPEN
  • kernel:结构元素。 它可以使用 getStructuringElement 创建。
  • anchor:与内核锚定位置。 负值表示锚点位于内核中心。
  • iterations:应用腐蚀和膨胀的次数。
  • borderType:像素外推法。
  • borderValue:边界值在恒定边界的情况下。 默认值具有特殊含义。

3.2 示例代码

#include<iostream>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_morphologyEx;   // 定义输入图像,灰度图像,开运算图像image = imread("font.jpg");  // 读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);// 转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);// 开运算Mat se = getStructuringElement(0, Size(5, 5)); // 构造矩形结构元素morphologyEx(image, image_morphologyEx, MORPH_OPEN, se, Point(-1, -1), 1); // 执行开运算imshow("image_morphologyEx", image_morphologyEx);waitKey(0);return 0;
}

开运算可以去除图像中的小噪声,同时保留图像中的主要前景对象。效果图如下所示:

Blog_OpenCV_Learnl_82.png


四、闭运算(close)

闭运算是先膨胀后腐蚀的组合操作。闭运算主要用于填补前景对象中的小孔或连接断裂的对象。

闭操作的作用:

  • 能够填充间隙来闭合形状的操作,也可以用来去除噪声;
  • 通过把背景中的小对象来放入前景中来移除前景的小孔;

4.1 API

void morphologyEx( InputArray src, OutputArray dst,int op, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
  • op:形态学操作类型,开运算使用 MORPH_CLOSE

  • 该函数和其它参数跟开运算的一样,这里不再赘述。


4.2 示例代码

#include<iostream>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_morphologyEx;   // 定义输入图像,灰度图像,闭运算图像image = imread("font.jpg");  // 读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);// 转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);// 闭运算Mat se = getStructuringElement(MORPH_RECT, Size(5, 5)); // 构造矩形结构元素morphologyEx(image, image_morphologyEx, MORPH_CLOSE, se, Point(-1, -1), 1); // 执行闭运算imshow("image_morphologyEx", image_morphologyEx);waitKey(0);return 0;
}

闭运算可以填补前景对象中的小孔,同时保留图像中的主要前景对象。效果图如下所示:

Blog_OpenCV_Learnl_83.png


五、形态学梯度(Morphological Gradient)

形态学梯度是膨胀图像与腐蚀图像的差值,又称基本梯度(其他还包括内部梯度, 方向梯度)。形态学梯度主要用于提取图像中前景对象的边缘。

形态学梯度的作用:

  • 通过获取图像的膨胀和腐蚀之间的差异,绘制围绕形状的边界;

5.1 API

void morphologyEx( InputArray src, OutputArray dst,int op, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
  • op:形态学操作类型,开运算使用 MORPH_GRADIENT

  • 该函数和其它参数跟开运算的一样,这里不再赘述。


5.2 示例代码

#include<iostream>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_morphologyEx;   // 定义输入图像,灰度图像,形态学梯度图像image = imread("font.jpg");  // 读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);// 转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);// 形态学梯度Mat se = getStructuringElement(MORPH_RECT, Size(5, 5)); // 构造矩形结构元素morphologyEx(image, image_morphologyEx, MORPH_GRADIENT, se, Point(-1, -1), 1);imshow("image_morphologyEx", image_morphologyEx);waitKey(0);return 0;
}

形态学梯度可以提取图像中前景对象的边缘,常用于边缘检测。效果图如下所示:

Blog_OpenCV_Learnl_84.png


六、顶帽(Top hat)

顶帽是原始图像减去图像开运算的结果,用于提取比背景亮的细小物体。

顶帽的作用:

  • 从图像中提取更精细的细节或者图像的噪声;

6.1 API

void morphologyEx( InputArray src, OutputArray dst,int op, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
  • op:形态学操作类型,顶帽使用 MORPH_TOPHAT

  • 该函数和其它参数跟开运算的一样,这里不再赘述。


6.2 示例代码

#include<iostream>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_morphologyEx;   // 定义输入图像,灰度图像,顶帽图像image = imread("font.jpg");  // 读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);// 转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);// 顶帽Mat se = getStructuringElement(MORPH_RECT, Size(5, 5)); // 构造矩形结构元素morphologyEx(image, image_morphologyEx, MORPH_TOPHAT, se, Point(-1, -1), 1);imshow("image_morphologyEx", image_morphologyEx);waitKey(0);return 0;
}

效果图如下所示:

Blog_OpenCV_Learnl_85.png


七、黑帽(Black hat)

黑帽是图像闭运算操作减去原始图像的结果,用于提取比背景暗的细小物体。。

黑帽的作用:

  • 得到图像内部的小孔,或者前景色中的小黑点,即从图像中提取更精细的细节;

7.1 API

void morphologyEx( InputArray src, OutputArray dst,int op, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
  • op:形态学操作类型,黑帽使用 MORPH_GRADIENT

  • 该函数和其它参数跟开运算的一样,这里不再赘述。


7.2 示例代码

#include<iostream>
#include<opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_morphologyEx;   // 定义输入图像,灰度图像,黑帽图像image = imread("font.jpg");  // 读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);// 转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);// 黑帽Mat se = getStructuringElement(MORPH_RECT, Size(5, 5)); // 构造矩形结构元素morphologyEx(image, image_morphologyEx, MORPH_BLACKHAT, se, Point(-1, -1), 1);imshow("image_morphologyEx", image_morphologyEx);waitKey(0);return 0;
}

效果图如下所示:

Blog_OpenCV_Learnl_86.png


http://www.aitangshan.cn/news/633.html

相关文章:

  • M序列 CEVA DSP 实现
  • 各类损失loss
  • 数论 学习笔记
  • [笔记]GGML 或GGUF的14种不同量化模式说明
  • Visual studio 2017安装教程 VS2017(附安装包)
  • Python装饰器底层原理
  • 用 Amazon Q AI 写了个 PHP 缓存库,解决” 若无则获取并回填” 这个老问题
  • 安装mkcert的ip证书
  • 告别外发文件管理乱象:Ftrans B2B为企业筑牢数据安全防线!
  • 转:UML一一 类图关系 (泛化、实现、依赖、关联、聚合、组合)_uml类图关系
  • 8.12
  • 动态规划题单做题日志
  • 告别传统FTP!国产FTP服务器软件如何实现10倍速升级?
  • 率先对接GPT-5!燕千云AI能力重磅升级,打造企业级全栈大模型服务生态
  • 国产化FPGA-2050-基于JFMK50T4(XC7A50T)的核心板
  • Luogu题解:P13463 [GCJ 2008 #1C] Text Messaging Outrage
  • Prometheus 告警时为何无法获取现场值
  • Luogu题解:P13427 [COCI 2020/2021 #2] Odasiljaci
  • post提交数据到服务器应该使用textarea还是div editable
  • Python 库 DuckDB
  • OpenCV入门(16):图像滤波(平滑处理)
  • Luogu题解:P13594 『GTOI - 1A』Bath
  • G. ABBC or BACB
  • 第十一届能源材料与电力工程学术会议(ICEMEE 2025)
  • JetBrains WebStorm 2025.2 (macOS, Linux, Windows) - JavaScript 和 TypeScript IDE
  • 牛逼!花了9天,开发了一款一站式智能测试平台:STP!
  • 第八届IEEE机电一体化与计算机技术工程国际学术会议(MCTE 2025)
  • VMware Avi Load Balancer 30.2.4 - 多云负载均衡平台
  • VMware NSX 4.2.3 - 网络安全虚拟化平台
  • JetBrains IDE 2025.2 (macOS, Linux, Windows) - 跨平台开发者工具