1.原理
形态学操作:
图像形态学操作 – 基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学
形态学有四个基本操作:腐蚀、膨胀、开、闭
膨胀与腐蚀是图像处理中最常用的形态学操作手段
膨胀:
跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。注意膨胀由于像素高的去代替锚点,所以图像整体白色区域变多。
腐蚀:
腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值。腐蚀黑色区域增加。
2.相关API介绍
(1)getStructuringElement(int shape, Size ksize, Point anchor):返回指定形状和尺寸的结构元素(kernel)
第一个参数:内核形状有矩形:MORPH_RECT;交叉形:MORPH_CROSS;椭圆形:MORPH_ELLIPSE;
第二个参数:内核大小
第三个参数:锚点,一般Point(-1,-1)中心点
(2)dilate(src, dst, kernel):膨胀
第一个第二个参数:输入输出图像
第三个参数:前面设定的结构元素
(3)erode(src, dst, kernel):腐蚀,参数设置与膨胀一致
(4)createTrackbar(const String & trackbarname, const String winName, int* value, int count, Trackbarcallback func, void* userdata=0):在图像中拖动滑块可以修改参数
trackbarname:滑动空间的名称
winname:滑动空间用于依附的图像窗口的名称
value:初始化阈值
count:滑动控件的刻度范围
TrackbarCallback:回调函数,定义为typedef void (CV_CDECL *TrackbarCallback)(int pos, void* userdata);
3.代码实现
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
Mat src, dst;
int esize = 3;
int maxsize = 29;
char outPutWin[] = "输出图像";
void CallBack(int ,void *);//注意参数定义
int main()
{
src = imread("D:/VS project/Image/people.jpg");
if (src.empty())
{
cout << "找不到图像文件" << endl;
return -1;
}
namedWindow("源图像", CV_WINDOW_AUTOSIZE);
imshow("源图像", src);
namedWindow(outPutWin, CV_WINDOW_AUTOSIZE);
createTrackbar("Element size",outPutWin, &esize, maxsize,CallBack);//构建动态滑块
CallBack(0,0);
waitKey(0);
return 0;
}
void CallBack(int ,void *)
{
int s = esize*2+1;//保证奇数
Mat structElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1,-1));
dilate(src, dst, structElement);//膨胀
//erode(src, dst, structElement);//腐蚀
imshow(outPutWin, dst);
return;
}
4.运行结果
(1)膨胀结果:
(2)腐蚀结果