形态学的这几个例子其实就是几个函数的应用
腐蚀erode和膨胀dilate是两个单独的函数
而开闭运算,顶帽黑帽都是封装在一个函数morpologyEx,根据参数不同选择不同的效果。
开运算 MORPH_OPEN
闭运算 MORPH_CLOSE
顶帽 MORPH_TOPHAT
黑帽 MORPH_BLACKHAT
1.这些效果的使用
如设置开运算的效果,则调用函数:morpologyEx(src_Image,dst_Image,MORPH_OPEN,element);//element为基本的内核值
内核值的定义可以理解成腐蚀程度或者一个size,在morpologyEx里面算是一个参数,这个参数要在前面设置好
2.内核值element的设置
内核值的设置用的是getStructuringElement函数,涉及到几个参数shape,size,point。
开闭运算:g_nOpenCloseNum-g_nMaxIterationNum
腐蚀膨胀:g_nErodeDilateNum-g_nMaxIterationNum
顶帽黑帽:g_nTopBlackHatNum-g_nMaxIterationNum
shape也就是内核的形状,有多种选择,如MORPH_RECT等
size的计算是上面那三个公式各自的绝对值*2+1
point也就是设置锚点的位置,为Absolute_offset
3.轨迹条的设置
其实就是opencv自带的一个函数CreateTrackBar
createTrackbar("迭代值", "open/close", &g_nOpenCloseNum,g_nMaxIterationNum*2+1, on_OpenClose);
第一个参数是轨迹条的名称,第二个参数是窗口名称,第三个参数是滑动块的初始位置,第四个参数是滑块可以滑动到的最大位置,
最后是回调函数
其实有的东西对于初学者来说有点杂乱,参数很多会不知道到底指的是什么,不要着急,多写几个例子,多做就可以了
下面是代码
//25.形态学的综合应用:开运算/闭运算/形态学梯度/顶帽/黑帽
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
Mat src_Image,dst_Image;
int g_nElementShape=MORPH_RECT;
int g_nMaxIterationNum=10;
int g_nOpenCloseNum=0;
int g_nErodeDilateNum=0;
int g_nTopBlackHatNum=0;
static void on_OpenClose(int,void *);
static void on_ErodeDilate(int,void *);
static void on_TopBlackHat(int,void *);
static void on_OpenClose(int,void *){
int offset=g_nOpenCloseNum-g_nMaxIterationNum;
int Absolute_offset=offset>0?offset:-offset;
//自定义核
Mat element=getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1,Absolute_offset*2+1),Point(Absolute_offset,Absolute_offset));
if(offset<0)
morphologyEx(src_Image, dst_Image, MORPH_OPEN, element);
else
morphologyEx(src_Image, dst_Image, MORPH_CLOSE, element);
imshow("open/close", dst_Image);
}
static void on_ErodeDilate(int,void *){
int offset=g_nErodeDilateNum-g_nMaxIterationNum;//定义偏差值,根据函数不同,计算也不同
int Absolute_offset=offset>0?offset:-offset;//绝对值
Mat element=getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1,Absolute_offset*2+1),Point(Absolute_offset,Absolute_offset));//设置内核值
if(offset<0)
erode(src_Image, dst_Image, element);
else
dilate(src_Image, dst_Image, element);//调用各个效果
imshow("erode/dilate", dst_Image);
}
static void on_TopBlackHat(int,void *){
int offset=g_nTopBlackHatNum-g_nMaxIterationNum;
int Absolute_offset=offset>0?offset:-offset;
Mat element=getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1,Absolute_offset*2+1),Point(Absolute_offset,Absolute_offset));
if(offset<0)
morphologyEx(src_Image, dst_Image, MORPH_TOPHAT, element);
else
morphologyEx(src_Image, dst_Image, MORPH_BLACKHAT, element);
imshow("topblackhat", dst_Image);
}
int main(){
src_Image=imread("/Users/oumoemoe/Downloads/girl.png");
if(!src_Image.data){
printf("图像读取失败/n");
return 0;
}
namedWindow("1");
imshow("1", src_Image);
namedWindow("open/close",1);
namedWindow("erode/dilate",1);
namedWindow("topblackhat",1);
g_nOpenCloseNum=9;
g_nErodeDilateNum=9;
g_nTopBlackHatNum=2;
createTrackbar("迭代值", "open/close", &g_nOpenCloseNum,g_nMaxIterationNum*2+1, on_OpenClose);
createTrackbar("迭代值", "erode/dilate", &g_nErodeDilateNum, g_nMaxIterationNum*2+1,on_ErodeDilate);
createTrackbar("迭代值", "topblackhat", &g_nTopBlackHatNum, g_nMaxIterationNum*2+1,on_TopBlackHat);
while(1){
int c;
on_OpenClose(g_nOpenCloseNum, 0);
on_ErodeDilate(g_nErodeDilateNum, 0);
on_TopBlackHat(g_nTopBlackHatNum, 0);
c=waitKey(0);
/*if((char)c=='q'||(char)c==27)
break;
if((char)c==49)
g_nElementShape=MORPH_ELLIPSE;
else if((char)c==50)
g_nElementShape=MORPH_RECT;
else if((char)c==51)
g_nElementShape=MORPH_CROSS;
else if((char)c==' ')
g_nElementShape=(g_nElementShape+1)%3;*/
}
return 0;
}