博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
opencv学习笔记九(膨胀与腐蚀及trackbar滑动条)
阅读量:3958 次
发布时间:2019-05-24

本文共 5813 字,大约阅读时间需要 19 分钟。

膨胀与腐蚀及trackbar滑动条

膨胀与腐蚀

膨胀和腐蚀的主要用途:

  • 消除噪声;
  • 分割出独立的图像元素,在图像中连接相邻的元素;
  • 寻找图像中明显的极大值或极小值区;
  • 求出图像的梯度;
  • 参考链接:https://blog.csdn.net/qq_40855366/article/details/81177174
    https://jingyan.baidu.com/article/f96699bbf99d9e894f3c1b4c.html

膨胀

转载于https://blog.csdn.net/qq_40855366/article/details/81177174

  • 膨胀就是求局部最大值的操作。
  • 按数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为A)与核(我们称之为B)进行卷积。
  • 核可以是任何的形状和大小,它拥有一个单独定义出来的参考点,我们称其为锚点(anchorpoint)。多数情况下,核是一个小的中间带有参考点和实心正方形或者圆盘,其实,我们可以把核视为模板或者掩码。
  • 而膨胀就是求局部最大值的操作,核B与图形卷积,即计算核B覆盖的区域的像素点的最大值,并把这个最大值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐增长。如下图所示,这就是膨胀操作的初衷。
    在这里插入图片描述
    右图比左图大一圈

腐蚀

转载于https://jingyan.baidu.com/article/f96699bbf99d9e894f3c1b4c.html

腐蚀原理:
腐蚀:局部最小值(与膨胀相反);
①定义一个卷积核B,
核可以是任何的形状和大小,且拥有一个单独定义出来的参考点-锚点(anchorpoint);
通常和为带参考点的正方形或者圆盘,可将核称为模板或掩膜;
②将核B与图像A进行卷积,计算核B覆盖区域的像素点最小值;
③将这个最小值赋值给参考点指定的像素;
因此,图像中的高亮区域逐渐减小。
在这里插入图片描述

opencv中的函数讲解

  1. OpenCV中膨胀函数-dilate()
void dilate(InputArray src,//输入OutputArray dst, //输出InputArray kernel, //核大小Point anchor=Point(-1,-1),// 锚位置,默认值(-1,-1)为中心int iterations=1, //迭代次数,默认值1int borderType=BORDER_CONSTANT,//图像边界像素模式,默认值BORDER_CONSTANTconst Scalar& borderValue =morphologyDefaultBorderValue()//边界值,有默认值,一般默认即可)

使用dilate函数,一般只需要填前面的三个参数,后面的四个参数都有默认值,而且往往会结合getStructuringElement()

  1. OpenCV中腐蚀函数-erode()
void erode(InputArray src,//输入OutputArray dst, //输出InputArray kernel, //核大小,当为NULL时,表示使用参考点位于中心3*3的核。一般使用函数getStructuringElement()配合使用Point anchor=Point(-1,-1),// 锚位置,(-1,-1)为中心int iterations=1, //迭代次数int borderType=BORDER_CONSTANT,//图像边界像素模式const Scalar& borderValue=morphologyDefaultBorderValue()//边界值)

erode函数与膨胀函数类似前三个参数需要填写,后面的四个参数有默认值可根据需要填写。

  1. 结构元素
getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));参数:shape:表核的形状,矩形MORPH_RECT;交叉形MORPH_CROSS;椭圆形MORPH_ELLIPSE;ksize:核尺寸大小;anchor:锚点的位置,锚点只影响形态学运算结果的偏移;功能:返回指定形状和尺寸的结构元素;

注意膨胀与腐蚀的对象

  1. 此处需要明确图片中的前景像素和背景像素对应像素值,或者说要明确图片中的像素值较大的部分,因为膨胀、腐蚀的操作对象是相对于像素值较大的部分而言的,即高亮白部分而不是黑色部分,要注意下面几点。
  • 膨胀是图像中的高亮部分进行膨胀,领域扩张,效果图拥有比原图更大的高亮区域;
  • 腐蚀是图像中的高亮部分被腐蚀掉,领域缩减,效果图拥有比原图更小的高亮区域;
  1. 膨胀
  • 如下图所示对左图进行膨胀操作时,会发现白色背景区域变大,黑色区域的字变小,因为膨胀操作对应的是像素值较高的部分如白色区域,所以白色区域膨胀了,黑色区域缩小了。
    在这里插入图片描述
  • 而对下图白色为前景黑色为背景的图进行膨胀时,结果如下,同样是白色的区域变大了,黑色的区域变小了。但前景的白色字变大了,而不是像上图中的黑色字变小了
    在这里插入图片描述
  1. 对左侧图像进行腐蚀操作结果如下,像素值高的部分白色区域变小,而像素值低的部分黑色区域变大
    在这里插入图片描述
    在这里插入图片描述

创建滑动条createTrackbar

转载于:https://www.cnblogs.com/geek-hao/p/11668248.html

此链接关于createTrackbar的用法很详尽,尤其是代码部分

  1. 函数原型:
CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,int* value, int count,TrackbarCallback onChange = 0, void* userdata = 0);参数1:trackbarname,这个参数用来给这个滚动条取一个名字;参数2:winname,这个参数用来指定你要吧这个滚动条用到那个窗口上;参数3:value,这个参数用来设置滑块初始值位置,同时记录滑块以后的位置;参数4:count,这个参数用来指定滚动条可以滚动的最大值;参数5:onChange,这个参数可以理解为一个函数类型的变量(当然这样说感觉有点怪),用来接收回调函数函数名的,默认值为0;参数6:userdata,这个变量这个参数是用户传给回调函数的数据,用来处理轨迹条事件,默认值为0。
  1. 回调函数的函数原型:
    void (TrackbarCallback)(int pos, void userdata);
  • 有些代码中定义回调函数时为什么必须要有上面俩参数。回调函数是一个必须依托于createTrackbar()函数而使用的函数,他不能单独拿来使用。
  • 第一个形参pos,它表示的是当前滑块所在的位置,它的值是createTrackbar()传给他的,也就是createTrackbar()形参value的值,这个传输过程是在createTrackbar()内部实现的,无需深究。
  • 然后回调函数形参userdata的值就是通过createTrackbar()的形参userdata直接得到的,所以createTrackbar()的形参userdata其实就是专门给回调函数准备的。可以传递各种类型数据如Mat,但在回调函数使用时需要转换类型如下

示例:

//TrackBar发生改变的回调函数void onChangeTrackBar(int pos, void* userdata);//主函数int main() {     //trackbar的值    int posTrackBar = 0;     //trackbar的最大值    int maxValue = 255;    //读入图像,以灰度图形式读入     Mat img = imread("F:\\图片\\timg.jpg", 0);    //新建窗口    namedWindow("二值化");     imshow("二值化", img);         //创建trackbar,我们把img作为数据传进回调函数中    createTrackbar("pos", "二值化", &posTrackBar, maxValue, onChangeTrackBar, &img);    waitKey();    return 0; }// 回调函数void onChangeTrackBar(int posTrackBar, void* img) {     // 强制类型转换    Mat src = *(Mat*)(img);     Mat dst;    // 二值化    threshold(src, dst, posTrackBar, 255, 0);     imshow("二值化", dst); }

运行效果

  1. 如下图所示,当膨胀的值为1时,实际在回调函数中的卷积核的大小为1*2+1即Size(3,3)大小的,因为卷积核必须是奇数,而滑动条则是由0到定义最大值的整数,所以要将其在回调函数中转化一下,这样在滑动滑块的时候可以看到一系列的变化,有利于对膨胀的理解。此处膨胀后,白色像素值大的区域变大,而黑色像素值为0的区域就变小了。
    在这里插入图片描述
    下面图片的背景及前景颜色与上方图片相反
    在这里插入图片描述
  2. 同理对图片进行腐蚀操作
  • 前景为黑色,背景为黑色时

    在这里插入图片描述

  • 前景为白色,背景为黑色时

    在这里插入图片描述

代码实现

#include 
#include
using namespace cv;using namespace std;Mat src, dst;char OUTPUT_WIN[] = "output image";//定义一个输出窗口名//int element_size = 3;//此处定义滑动条当前值,若此处使用全局变量,就无需在回调函数中定义形参,回调函数可定义为void CallBack_dilate(int , void* );//int max_size = 21;//定义滑动条最大值void CallBack_dilate(int pos, void* userdata); //声明膨胀的回调函数void CallBack_erode(int pos, void* userdata); //声明腐蚀的回调函数int main(){
src = imread("G:/OpenCV/opencv笔记所用图片/wen2.png"); if (src.empty()) {
cout << "could not load image..."<< endl; getchar(); return -1; } namedWindow("input image", CV_WINDOW_AUTOSIZE);//命名一个窗口显示输入图像 imshow("input image", src); int element_size = 3;//此处定义滑动条当前值 int max_size = 21;//定义滑动条最大值 Mat strElement; namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);//命名一个窗口显示输出图像 //创建膨胀滑动条 createTrackbar("膨胀 :", OUTPUT_WIN, &element_size, max_size, CallBack_dilate);//滑动条名称,//窗口名称,//滑动条当前值,//滑动条最大值,//回调函数,//最后的用户参数默认不写(也可以传递各种类型数据如Mat,但在回调函数使用时需要转换类型) //创建腐蚀滑动条 createTrackbar("腐蚀 :", OUTPUT_WIN, &element_size, max_size, CallBack_erode); waitKey(0); return 0;}//定义膨胀的回调函数void CallBack_dilate(int element_size, void* strElement) {
int s = element_size * 2 + 1; //此处将createTrackbar传递过来的element_size值变为奇数 //此处s必须为奇数,因为后面获取结构元素中的Size(s, s)必须是奇数 Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));//此处定义的结构元素为方形,大小长s,宽s,锚点为中心 dilate(src, dst, structureElement, Point(-1, -1), 1);//膨胀函数,对原始图像进行膨胀,核的大小为structureElement,通过调节核的大小来调节膨胀程度的大小 //erode(src, dst, structureElement); imshow(OUTPUT_WIN, dst); return;}//定义腐蚀的回调函数void CallBack_erode(int element_size, void* userdata) {
int s = element_size * 2 + 1; Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));//此处定义的结构元素为方形,大小长s,宽s,锚点为中心 // dilate(src, dst, structureElement, Point(-1, -1), 1); erode(src, dst, structureElement);//腐蚀函数,对原始图像进行腐蚀操作,此处后4个参数采用默认值 imshow(OUTPUT_WIN, dst); return;}
你可能感兴趣的文章
JSP彩色验证码源程序编写
查看>>
java操作Excel、PDF文件
查看>>
java 获得系统变量
查看>>
window.event对象用法讲解
查看>>
jive license保护原理
查看>>
java des加密
查看>>
struts&hibernate&spring例子
查看>>
inno使用教程
查看>>
网吧系统母盘制作(系统分区整体考虑优化配置篇)
查看>>
spring beans beanfactory applicationcontext
查看>>
使用ORM工具进行数据访问
查看>>
使用ORM工具进行数据访问
查看>>
Quartz 使用手记 --转
查看>>
编译与部署Eclipse+Tomcat+MySQL+Liferay4.1.2
查看>>
MySQL用户授权
查看>>
mysql忘记密码怎么办?~
查看>>
MySQL修改密码方法总结
查看>>
怎么将我的硬盘屏蔽
查看>>
关于MySQL select into 和 SQLServer select into
查看>>
2003应用
查看>>