几种基于膨胀和腐蚀的更高级运算,morphologyEx()函数
2016-08-13 12:08
344 查看
既然是基于膨胀和腐蚀的运算,那么再让我们详细了解一下膨胀和腐蚀到底对图像做了什么?
第一种情况,对于二值图像来说腐蚀:核与其覆盖的图像部分做“与”操作,如果全为1,则该像素点为1,否则为0;也就是0容易得到,图像更多的地方变黑了,白色部分被腐蚀了
膨胀:核与其覆盖的图像部分做“与”操作,如果全为0,则该像素点为0,否则为1;也就是1容易得到,图像更多的地方变白了,白色部分膨胀了
第二种情况,对于一个灰度图像来说:
腐蚀:某一点的像素值,就是核与图像该部分像素值差的最小值。所以像素值变低比较容易,亮色部分被腐蚀。
膨胀:某一点的像素值,就是核与图像该部分像素值和的最大值。所以像素值变高比较容易,亮色部分膨胀。
1.开运算
先腐蚀后膨胀
作用:放大裂缝和低密度区域,消除小物体,在平滑较大物体的边界时,不改变其面积
2.闭运算
先膨胀后腐蚀
作用:排除小型黑洞,突触了比原图轮廓区域更暗的区域
3.形态学梯度
形态学梯度=膨胀图-腐蚀图
作用:保留图像边缘
4.顶帽(礼帽)
顶帽=原图-开运算
分离邻近点亮一些的斑块,进行背景提取
5.黑帽
黑帽=闭运算-原图
用来分离比邻近点暗一些的斑块
6.更加高级的形态学运算函数——morphologyEx()
下面这个程序:用键盘按键123改变核的形状,用进度条同时改变类型及Size大小,正负代表类型,绝对值代表Size
#include #include #include #include #include #include #include "vector" using namespace std; using namespace cv; //目的:写一个腐蚀/膨胀,顶帽/黑帽,开/闭运算的程序,用控制条控制运算方式及核Size,用键盘控制核类型 Mat g_src,g_dst; int g_nOpenCloseNum=0; int g_nErodeDilateNum=0; int g_nTopBlackNum=0; int g_nMaxNum=10; static void on_nOpenCloseSlide(int,void*); static void on_nErodeDilateSlide(int,void*); static void on_nTopBlackSlide(int,void*); int g_nShapeNum=MORPH_RECT; int main() { g_src=imread("cui.jpg"); //这里前面错误的写为Mat g_src=imread("cui.jpg")相当于把g_src变成了局部变量 namedWindow("腐蚀/膨胀"); namedWindow("顶帽/黑帽"); namedWindow("开/闭"); createTrackbar("Size-10","开/闭",&g_nOpenCloseNum,g_nMaxNum*2+1,on_nOpenCloseSlide); createTrackbar("Size-110","腐蚀/膨胀",&g_nErodeDilateNum,g_nMaxNum*2+1,on_nErodeDilateSlide); createTrackbar("Size-120","顶帽/黑帽",&g_nTopBlackNum,g_nMaxNum*2+1,on_nTopBlackSlide); while(1) { int c; //cin>>c; //执行回调函数 cout<<"循环1次"<0) morphologyEx(g_src,g_dst,MORPH_OPEN,element); else morphologyEx(g_src,g_dst,MORPH_CLOSE,element); imshow("开/闭",g_dst); } static void on_nErodeDilateSlide(int,void*) { cout<<"已经调用回调函数二:on_nErodeDilateSlide"<0) erode(g_src,g_dst,element); else dilate(g_src,g_dst,element); imshow("腐蚀/膨胀",g_dst); } static void on_nTopBlackSlide(int,void*) { cout<<"已经调用回调函数三:on_nTopBlackSlide"<0) morphologyEx(g_src,g_dst,MORPH_TOPHAT,element); else morphologyEx(g_src,g_dst,MORPH_BLACKHAT,element); imshow("顶帽/黑帽",g_dst); }
程序问题:1.createTrackbar不执行回调函数为什么也可以运行呢?
经试验,不写回调函数的语句,确实没有调用回调函数,但是为什么之前的例子没关系呢?
确实,不写回调函数可以,但是回调函数承担着给函数赋初值的作用,如果不写回调函数,第一,刚打开图片时是没有画面的,必须点击一下进度条才有画面。
第二,如果在循环开始不赋初值的话,当改变核形状的时候,图片不会自己转变,而是要点一下进度条才有变化。
所以,赋初值,也就是写回调函数,还是很有必要的。
2.waitkey()如何获取获取按键
waitkey灵活运用注意如下几点
当参数delay中为负,则无穷等待
否则等待delay ms.
返回值是按键值 否则返回-1
当参数为空,则一直等待按键当前线程等待
waitkey只对显示图像窗口有效,对控制台无效
3.程序中出现一个错误,那就是只有开闭运算会随着进度条的调整,图像发生变化,其他两种运算不会变化。这里有一个细节,第一下拖动进度条会变化,后面就不动了。还有一个细节,每次显示图片,开闭运算的图片总是第一个显示出来。
猜想原因是:
(1).和三个函数调用的顺序有关,经改变,情况依旧,所以排除该种可能。
(2).另外两个函数的书写有问题,经检查,没问题。
(3).偏差与element没有设置为局部变量,所以函数之间互相影响,这一点是错误,已经更正了。
错误原因找到了 offset的定义出了问题,每一个函数的offset定义不同,但是我因为是复制的,所以都一样了,所以第一个图变了,其他的offset就确定了,导致了错误。
4.3通道RGB图片可以吗?答案是可以。
相关文章推荐
- 几种基于膨胀和腐蚀的更高级运算
- 基于形态学运算的腐蚀,膨胀,开运算,闭运算
- opencv学习笔记第五章:基于形态学运算的图像变换(1)形态学运算进行腐蚀和膨胀
- 图像的腐蚀(erode)和膨胀(dilate) 开运算以及闭运算------理论知识及其对应函数
- 基于形态学运算的腐蚀,膨胀,开运算,闭运算
- 图像膨胀腐蚀开闭运算
- cvDilate()膨胀 cvErode()腐蚀函数
- OpenCV学习笔记-形态学操作-腐蚀膨胀-开闭运算
- 膨胀、腐蚀、开、闭运算——数字图像处理中的形态学
- python 简单图像处理(14) 灰度图腐蚀和膨胀,开运算、闭运算
- 形态学运算中腐蚀,膨胀,开运算和闭运算
- Matlab 图像处理 形态学 腐蚀 膨胀 开闭运算 连通分量
- python 简单图像处理(13) 二值图腐蚀和膨胀,开运算、闭运算
- 数学形态学图像处理——图像腐蚀,膨胀,开闭运算(《学习OpenCV》练习题第五章第四题)
- 基于Linux平台的高级IO扩展函数
- cvErode和cvDilate腐蚀和膨胀函数————OpenCV笔记(七)
- 图像处理算法系列 第六章 图像形态变化 膨胀 腐蚀 开运算 闭运算
- 形态学运算中腐蚀,膨胀,开运算和闭运算(转)
- 膨胀与腐蚀的组合(开运算与闭运算)
- 形态学运算中腐蚀,膨胀,开运算和闭运算