图像的膨胀和腐蚀是使用形态学滤波进行运算操作的,下面解释一下什么叫形态学滤波?在解释这个问题之前我们先来来了解一下什么是 数学形态学 。
数学形态学:是一种被定义为分析空间结构的理论,简称形态学,顾名思义就是分析物体的形状和姿态。
形态学滤波:使用数学中的形态学对图像进行运算称之为形态学滤波,和其他的滤波并没有什么本质上的不同,只是不同的滤波实现了不同发效果。
形态学通常操作的对象时二值化图像,哈哈 甚是悲哀,又得去查一下什么是二值化图像?
二值化图像是指灰度图像中每一个像素点只有两个灰度等级,一般就是或者255吧。
使用形态学滤波的基本运算有四个:图像和膨胀和腐蚀 图像的开运算和闭运算。今天学习图像的膨胀和腐蚀。
图像的腐蚀是指经过相应模型的形态学运算,将一些像素值变成0。腐蚀可以收缩图像,消除边界点,让图像中小于结构体一些毛刺消失。(哈哈 不太明白啊 怎么 收缩啦 怎么消除 消失 啦?? ?)
哈哈,百度了一下 说一下上面这个问题:
由于操作对象是一个二值化的图像进行,我看网上说分为了前景和背景,我觉得说白了前景就是白色(255)后景都是黑色(0)那么此时对这幅图像进行腐蚀操作,就是定义一会模板或者说核或者说掩码 ,一般定义成n*n的一个正方形就可以啦 n为奇数,让这个模板对二值化的图像进行遍历,这个模板的中心点称之为锚点,当锚点和某一个像素点对齐之后,模板中的其他元素自然也对应覆盖了这个锚点覆盖像素点周围的像素点,从这些周围的像素点找出来最小的像素值去代替锚点覆盖的那个像素点的像素值,因为对二值化图像进行操作,所以如果是白色则被替换为黑色,但是如果整张图片都是白色或者黑色,那么这个运算自然也就不会有什么作用了。现在突然明白所谓的收缩图像和消除边界点的意思了? 所谓的收缩图像其实并不是图像的尺寸减少了,图像依旧还是那么大?只是前景物体(也就是白色部分)因为这个操作周围的白色像素点被更换成为了黑色,所以这个前景物体缩小了,哈哈缩小或者消除边界应该都是相对于前景物体来说的!!我也不知道这样理解的对不对,如果有问题,请大神指点。那么同样膨胀就基本和这个类似啦!!
下面附上一些操作学习的代码
#include<opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
Mat image, result1, result2, result3;
int g_nTrackbarNmuer = 0;//0表示腐蚀,1表示膨胀
int g_nStructRlementSize = 5;//内核矩阵尺寸
//全局函数声明
void Process();//膨胀和腐蚀
void on_TrackbarNumChange(int, void*);
void on_ElementSizeChange(int, void*);
int main()
{
system("color 5E");
//由于二值化图像是对灰度图像进行操作 所以这里读入图片的时候需要进行色彩转换
image = imread("Test1.jpg", IMREAD_GRAYSCALE);
//二值化 函数 150:是阈值 大于150 赋值255 小于150 赋值0
/*
double threshold( InputArray src,OutputArray dst,double threshold,double maxval,int type );
参数说明src:原始数组,可以是Mat类型。dst:输出数组,必须与 src 的类型一致。
threshold:阈值maxval:使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值。
type:阈值类型type=CV_THRESH_BINARY:如果 src(x,y)>threshold ,dst(x,y) = max_value; 否则,dst(x,y)=0;
type=CV_THRESH_BINARY_INV:如果 src(x,y)>threshold,dst(x,y) = 0; 否则,dst(x,y) = max_value.
type=CV_THRESH_TRUNC:如果 src(x,y)>threshold,dst(x,y) = max_value; 否则dst(x,y) = src(x,y).
type=CV_THRESH_TOZERO:如果src(x,y)>threshold,dst(x,y) = src(x,y) ; 否则 dst(x,y) = 0。
type=CV_THRESH_TOZERO_INV:如果 src(x,y)>threshold,dst(x,y) = 0 ; 否则dst(x,y) = src(x,y)
*/
threshold(image, result1, 150, 255, CV_THRESH_BINARY);
//getStructuringElement函数会返回指定形状和尺寸的结构元素 如果不记得这个函数参数意思 直接去看定义即可
//看的别人的代码 中 发现 最后一个point()中的参数 使用了内核的尺寸变量 作为参数 这样锚点在哪里呢 这样做有什么意义吗?
Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructRlementSize + 1, 2 * g_nStructRlementSize + 1), Point(-1, -1));
cout << element << endl;
erode(result1, result2, element);
dilate(result1, result3, element);
imshow("二值化图像",result1);
imshow("腐蚀图像", result2);
imshow("膨胀图像", result3);
/*
"腐蚀/膨胀"作为第一个参数 是轨迹条的名字 第二个参数为轨迹条窗口的名字
打开函数定义的位置 最后两个参数作用不太明白
*/
namedWindow("after图");
createTrackbar("腐蚀/膨胀", "after图", &g_nTrackbarNmuer, 1, on_TrackbarNumChange);
createTrackbar("内核尺寸", "after图", &g_nStructRlementSize, 21, on_ElementSizeChange);
waitKey(0);
return 0;
}
void Process()
{
Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructRlementSize + 1, 2 * g_nStructRlementSize + 1), Point(-1, -1));
if (g_nTrackbarNmuer == 0)
{
erode(result1, result2, element);
}
else
{
dilate(result1, result2,element);
}
imshow("After图像", result2);
}
void on_TrackbarNumChange(int, void*)
{
Process();
}
void on_ElementSizeChange(int, void*)
{
Process();
}