OpenCV学习(10) 图像的腐蚀与膨胀(1)

建议大家看看网络视频教程:http://www.opencvchina.com/thread-886-1-1.html 

 

腐蚀与膨胀都是针对灰度图的形态学操作,比如下面的一副16*16的灰度图。

它每个像素对应的值为(每个像素值范围都在0-255之间)为:

      我们定义一个5*5的结构元素,该结构元素用5*5的矩阵表示,其中为1的单元,表示该单元在结构元素中有效,另外还定义一个锚点,坐标为(2,2),在单元格中用蓝色表示。

腐蚀/膨胀的操作就是用结构元素的锚点位置对齐图像的像素,然后从左上角的第一个像素滑动到右下角的最后一个像素。

在滑动到每个像素时,结构元素中为1的各个坐标格子会与相应的像素对齐。比如滑动到第一个像素时,如下图所示:

此时,原图像中对齐的格子,如下图所示。

       腐蚀操作就是取其中的最小值,代替原素像素值,即image(0,0)的像素值为min(0,1,2,16,32)=0,而膨胀操作则相反,是取最大值代替原像素,即image(0,0)=max(0,1,2,16,32)=32。

下面我们再看一个例子,当结构元素滑动到image(4,4 ) 位置时候,图像的腐蚀膨胀操作:

      此时,结构元素对齐的像素如下图所示,对于腐蚀操作,此时image(4,4)应该等于min(36,52,66,67,68,69,70,84,100)=36,而膨胀操作,则是image(4,4)等于max(36,52,66,67,68,69,70,84,100)=100。

需要注意下面的一种情况:

结构元素如下图所示,仍是5*5的十字形状,但锚点位置在(3,3),此时当结构元素在图像中滑动时候,会有一些特殊情况需要注意。

比如滑动到图像的(0,0)位置时,结构元素中为1的单元格和图像没有交叉的格子,此时按我的理解,应该保持像素的值不变,但opencv中却不是这样,当腐蚀时,此时(0,0)位置像素值为255,当膨胀时,(0,0)位置像素值为0。

下面是我写的简单的腐蚀膨胀函数代码:

cv::Mat gMophEx::Erode(cv::Mat& img,  cv::Mat  kernel, cv::Point anchor)    {    cv::Mat tmpImg;    img.copyTo(tmpImg);int i, j, m, n;    uchar* p;for(i=0; i<img.rows; i++)        {        p = tmpImg.ptr<uchar>(i);for(j=0; j<img.cols; j++)            {int min = 100000;for(m = 0; m < kernel.rows; m++)                {for(n=0; n <kernel.cols; n++)                    {if(kernel.data[m*kernel.cols+n]==1)                        {//printf("i=%d, j=%d, m=%d,n=%d,tt1=%d, tt2=%d, tt3=%d\n",i,j,m,n,j+n-anchor.y,i + m - anchor.x,(i + m - anchor.x)*img.cols + j+n-anchor.y);if(j+n-anchor.x < 0 || j+n-anchor.y >=img.cols || i + m - anchor.x < 0 || i + m - anchor.x >= img.rows)continue;//printf("%d \n",img.data[(i + m - anchor.x)*img.cols + j+n-anchor.y]);if(img.data[(i + m - anchor.x)*img.cols + j+n-anchor.y]<min)                            min = img.data[(i + m - anchor.x)*img.cols + j+n-anchor.y];                        }                    }                }

if (min < 256)                {                p[j] = min;                }else if(min==100000)                {                p[j] = 255; //opencv结果是这样,当腐蚀时候,当前像素找不到相应的点,赋予最大值                }

}        }return tmpImg;    }

cv::Mat gMophEx::Dilate(cv::Mat& img,  cv::Mat  kernel, cv::Point anchor)    {    cv::Mat tmpImg;    img.copyTo(tmpImg);int i, j, m, n;    uchar* p;for(i=0; i<img.rows; i++)        {        p = tmpImg.ptr<uchar>(i);for(j=0; j<img.cols; j++)            {int max=-1;for(m = 0; m < kernel.rows; m++)                {for(n=0; n <kernel.cols; n++)                    {if(kernel.data[m*kernel.cols+n]==1)                        {//printf("i=%d, j=%d, m=%d,n=%d, tt=%d\n",i,j,m,n,(i + m - anchor.x)*img.cols + j+n-anchor.y);if(j+n-anchor.y < 0 || j+n-anchor.y >=img.cols || i + m - anchor.x < 0 || i + m - anchor.x >= img.rows)continue;//printf("%d \n",img.data[(i + m - anchor.x)*img.cols + j+n-anchor.y]);if(img.data[(i + m - anchor.x)*img.cols + j+n-anchor.y]>max)                            max = img.data[(i + m - anchor.x)*img.cols + j+n-anchor.y];                        }                    }                }

if (max >= 0)                {                p[j] = max;                }else if(max == -1)                {                p[j] = 0;                }//PrintMat(tmpImg);            }        }return tmpImg;    }

最后我们对图像进行腐蚀操作,得到新的图像像素值为:

膨胀操作后的像素值为:

程序代码: 工程FirstOpenCV4

时间: 2024-10-24 13:01:53

OpenCV学习(10) 图像的腐蚀与膨胀(1)的相关文章

OpenCV学习(11) 图像的腐蚀与膨胀(2)

先对一副灰度图像进行腐蚀操作,然后在腐蚀后的图像上再进行膨胀操作,我们定义这个操作为开操作. 先对一副图像进行膨胀操作,然后在膨胀后的图像上再进行腐蚀操作,我们定义这个操作为闭操作.       开操作可以去掉场景中一些孤立的点,而闭操作通常可以填充前景中一些小洞,通常通过这两种操作,使得图像看起来更圆润光滑一点. 在opencv中,我们通过函数 cv::morphologyEx(Image, resOpen, cv::MORPH_OPEN, element ); cv::morphologyE

OpenCV学习(12) 图像的腐蚀与膨胀(3)

通过使用不同的结构元素来进行膨胀腐蚀操作,可以检测图像中的角点,下面就一步一步看这个算法如果实现角点检测. 原图像: 首先我们创建四个结构元素 先用十字结构元素对原图像进行膨胀操作,得到下面的图像 再对这个图像用钻石型结构元素进行腐蚀操作,得到图像1,如下图所示: 接着,我们对原图像用X型结构元素进行膨胀操作,得到: 我们再用方形结构元素对上面图像进行腐蚀操作,得到图像2 最后我们用图像2减去图像1,就可以得到角点位置: 程序源码:工程FirstOpenCV5

(转) OpenCV学习笔记大集锦 与 图像视觉博客资源2之MIT斯坦福CMU

      首页 视界智尚 算法技术 每日技术 来打我呀 注册     OpenCV学习笔记大集锦 整理了我所了解的有关OpenCV的学习笔记.原理分析.使用例程等相关的博文.排序不分先后,随机整理的.如果有好的资源,也欢迎介绍和分享. 1:OpenCV学习笔记 作者:CSDN数量:55篇博文网址:http://blog.csdn.net/column/details/opencv-manual.html 2:部分OpenCV的函数解读和原理解读 作者:梦想腾飞数量:20篇博文网址:http:/

OpenCV学习(39) OpenCV中的LBP图像

本章我们学习LBP图像的原理和使用,因为接下来教程我们要使用LBP图像的直方图来进行脸部识别. 参考资料: http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html http://www.cnblogs.com/mikewolf2002/p/3438166.html       LBP的基本思想是以图像中某个像素为中心,对相邻像素进行阈值比较.如果中心像素的亮度大于等于它的相邻像素,把相邻像素标记为1,否则标

指针-opencv学习灰度图锐化的两个函数的差别不理解

问题描述 opencv学习灰度图锐化的两个函数的差别不理解 下面是一个灰度图锐化的函数,我有两种方式实现,方式1,和方式2,居然得到的结果不一样,图片数据也不一样,请高手看一下,可能是C语言的知识掌握的不好. void my_sharpen(const cv::Mat &image, cv::Mat &result) { result.create (image.size(), image.type ()); for(int j=1; j<image.rows-1; j++) { u

【OpenCV】访问图像中每个像素的值 (I)

最近要做的东西要对每个像素值进行处理,所以上网搜... 居然发现搜出来的好文章都是一个人写的,而且还是一个妹子..于是收藏之...按时间顺序发! 转载请注明出处:http://blog.csdn.net/xiaowei_cqu/article/details/7557063 !!此篇是基于IplImage* (C接口或者说2.1之前版本的接口,新的Mat的访问方式请参考博文: <访问Mat图像中每个像素的值>) IplImage是OpenCV中CxCore部分基础的数据结构,用来表示图像,其中

深度学习在图像超分辨率重建中的应用

超分辨率技术(Super-Resolution)是指从观测到的低分辨率图像重建出相应的高分辨率图像,在监控设备.卫星图像和医学影像等领域都有重要的应用价值.SR可分为两类:从多张低分辨率图像重建出高分辨率图像和从单张低分辨率图像重建出高分辨率图像.基于深度学习的SR,主要是基于单张低分辨率的重建方法,即Single Image Super-Resolution (SISR). SISR是一个逆问题,对于一个低分辨率图像,可能存在许多不同的高分辨率图像与之对应,因此通常在求解高分辨率图像时会加一个

深度学习在图像取证领域中的进展

雷锋网按:本文作者杨朋朋,就读于北京交通大学,信号与信息处理专业博士生二年级,导师倪蓉蓉教授.研究兴趣包括多媒体取证.隐写分析,深度学习.所在团队为教育部创新团队和科技部重点领域创新团队,负责人为赵耀教授. 图像取证 在当今飞速发展的信息时代,数字图像已经渗透到社会生活的每一个角落,数字图像的广泛使用也促进了数字图像编辑软件的开发与应用,例如:Adobe Photoshop.CorelDRAW.美图秀秀等等.利用这些编辑工具,用户可以随意对图像进行修改,从而达到更好的视觉效果.然而,在方便了用户

无法解析的外部符号-opencv简单的图像程序,总是出现下面的错误,解决不了!

问题描述 opencv简单的图像程序,总是出现下面的错误,解决不了! opencv简单的图像程序,总是出现下面的错误,解决不了啊!vs2013,vs2010都一样!!!谢谢各位帮帮我!! 我被折磨好几天了!!都重装几次了!!快哭了!!网上也没找到准确的解决方法!!! 谢谢大神们帮助!!没有C币... 解决方案 你的opencv环境配置过没?建议按教程配置下 解决方案二: 需要添加lib库文件http://blog.csdn.net/zyxlinux888/article/details/8048