怪物奇妙物语

宇宙无敌超级美少男的怪物奇妙物语

首页 新随笔 联系 管理
  819 随笔 :: 0 文章 :: 2 评论 :: 16万 阅读

形态学操作

形态学操作就是基于形状的一系列图像处理操作。
OpenCV 为进行图像的形态学变换提供了快捷、方便的函数。
最基本的形态学操作有二种,他们是:膨胀与腐蚀 (Dilation 与 Erosion)。

膨胀与腐蚀能实现多种多样的功能,主要如下:

  • 消除噪声
  • 分割 (isolate) 出独立的图像元素,在图像中连接 (join) 相邻的元素。
  • 寻找图像中的明显的极大值区域或极小值区域
  • 求出图像的梯度

腐蚀和膨胀是针对白色部分(高亮部分)而言的。

  • 膨胀就是对图像高亮部分进行 “领域扩张”,效果图拥有比原图更大的高亮区域;
  • 腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。

膨胀用来处理缺陷问题; 腐蚀用来处理毛刺问题。

膨胀 dilate

膨胀就是求局部最大值的操作,从图像直观看来,就是将图像光亮部分放大,黑暗部分缩小。

按数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为 A)与核(我们称之为 B)进行卷积。假设有图像 A 和结构元素 B,结构元素 B 在 A 上面移动,其中 B 定义其中心为锚点,
以 B 覆盖下 A 的最大像素值(偏白)替换锚点的像素,其中 B 作为结构体可以是任意形状(与卷积不同之处,可以是线、矩阵、圆、十字等形状)。

二值图像与灰度图像上的膨胀操作:

  1. B 覆盖下的三个像素点是 1,0,0,然后最大值就是 1,然后中间的那个 0,就是替换成了 1,1,0

腐蚀 erode

腐蚀操作和膨胀操作相反,也就是将毛刺消除,腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值(偏黑)替换锚点重叠下图像的像素值。

形态学膨胀——dilate 函数

函数原型:

void dilate(
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor=Point(-1,-1),
int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue()
);

参数详解:

  • 第一个参数,InputArray 类型的 src,输入图像,即源图像,填 Mat 类的对象即可。图像通道的数量可以是任意的,但图像深度应为 CV_8U,CV_16U,CV_16S,CV_32F 或 CV_64F 其中之一。
  • 第二个参数,OutputArray 类型的 dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,InputArray 类型的 kernel,膨胀操作的核。若为 NULL 时,表示的是使用参考点位于中心 3x3 的核。
    我们一般使用函数 getStructuringElement 配合这个参数的使用。getStructuringElement 函数会返回指定形状和尺寸的结构元素(内核矩阵)。

其中,getStructuringElement 函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一:

  • 矩形: MORPH_RECT
  • 交叉形: MORPH_CROSS
  • 椭圆形: MORPH_ELLIPSE

调用范例:

//载入原图
Mat image = imread("1.jpg");
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat out;
//进行膨胀操作
dilate(image, out, element);
//-----------------------------------【头文件包含部分】---------------------------------------
// 描述:包含程序所依赖的头文件
//----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>
//-----------------------------------【命名空间声明部分】---------------------------------------
// 描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace std;
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
//载入原图
Mat image = imread("5.jpg");
//显示原图
imshow("【原图】膨胀操作", image);
//获取自定义核
Mat element1 = getStructuringElement(MORPH_RECT, Size(7, 7));
Mat element2 = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat out1;
Mat out2;
//进行膨胀操作
dilate(image, out1, element1);
dilate(image, out2, element2);
//显示效果图
imshow("【效果图】膨胀操作(ksize=5)", out1);
imshow("【效果图】膨胀操作(ksize=15)", out2);
waitKey(0);
return 0;
}

可以看到白色的像素点(像素值高的像素点)越来越多,黑色的部分(像素值低的像素点)越来越少。

形态学腐蚀——erode 函数

C++: void erode(
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor=Point(-1,-1),
int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue()
);

参数详解:

  • 第一个参数,InputArray 类型的 src,输入图像,即源图像,填 Mat 类的对象即可。图像通道的数量可以是任意的,但图像深度应为 CV_8U,CV_16U,CV_16S,CV_32F 或 CV_64F 其中之一。
  • 第二个参数,OutputArray 类型的 dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,InputArray 类型的 kernel,腐蚀操作的内核。若为 NULL 时,表示的是使用参考点位于中心 3x3 的核。我们一般使用函数 getStructuringElement 配合这个参数的使用。getStructuringElement 函数会返回指定形状和尺寸的结构元素(内核矩阵)。
//载入原图
Mat image = imread("1.jpg");
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat out;
//进行腐蚀操作
erode(image,out, element);
//-----------------------------------【头文件包含部分】---------------------------------------
// 描述:包含程序所依赖的头文件
//----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>
//-----------------------------------【命名空间声明部分】---------------------------------------
// 描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace std;
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main( )
{
//载入原图
Matimage = imread("1.jpg");
//创建窗口
namedWindow("【原图】腐蚀操作");
namedWindow("【效果图】腐蚀操作");
//显示原图
imshow("【原图】腐蚀操作", image);
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat out;
//进行腐蚀操作
erode(image,out, element);
//显示效果图
imshow("【效果图】腐蚀操作", out);
waitKey(0);
return 0;
}

与膨胀相反,可以看到白色的像素点(像素值高的像素点)越来越少,黑色的部分(像素值低的像素点)越来越多。

参考文章:

形态学图像处理(一):膨胀与腐蚀

posted on   超级无敌美少男战士  阅读(656)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示