形态学操作
形态学操作就是基于形状的一系列图像处理操作。
OpenCV 为进行图像的形态学变换提供了快捷、方便的函数。
最基本的形态学操作有二种,他们是:膨胀与腐蚀 (Dilation 与 Erosion)。
膨胀与腐蚀能实现多种多样的功能,主要如下:
- 消除噪声
- 分割 (isolate) 出独立的图像元素,在图像中连接 (join) 相邻的元素。
- 寻找图像中的明显的极大值区域或极小值区域
- 求出图像的梯度
腐蚀和膨胀是针对白色部分(高亮部分)而言的。
- 膨胀就是对图像高亮部分进行 “领域扩张”,效果图拥有比原图更大的高亮区域;
- 腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。
膨胀用来处理缺陷问题; 腐蚀用来处理毛刺问题。
膨胀 dilate
膨胀就是求局部最大值的操作,从图像直观看来,就是将图像光亮部分放大,黑暗部分缩小。
按数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为 A)与核(我们称之为 B)进行卷积。假设有图像 A 和结构元素 B,结构元素 B 在 A 上面移动,其中 B 定义其中心为锚点,
以 B 覆盖下 A 的最大像素值(偏白)替换锚点的像素,其中 B 作为结构体可以是任意形状(与卷积不同之处,可以是线、矩阵、圆、十字等形状)。
二值图像与灰度图像上的膨胀操作:
- 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;
}
与膨胀相反,可以看到白色的像素点(像素值高的像素点)越来越少,黑色的部分(像素值低的像素点)越来越多。
参考文章:
标签:原图,erode,Mat,dilate,opencv,腐蚀,图像,操作,膨胀 From: https://www.cnblogs.com/zhuoss/p/17172493.html