opencv(5)形态学操作
来源:互联网 发布:如何使用网络爸爸 编辑:程序博客网 时间:2024/05/12 11:04
图像形态学一般用于阈值化后的二值图像,其实也可以用于灰度图像的处理,这篇文章主要对灰度中的应用做分析。
1.膨胀与腐蚀
函数void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );//腐蚀函数void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );//膨胀函数
函数解释可以参考:opencv论坛,关于里面的结构IplConvKernel可以参考:http://blog.csdn.net/babbxazzg/article/details/5976177
腐蚀操作要计算核区域内像素的最小值。膨胀操作要计算核区域内的像素最大值。具体的函数表达:
如果在二值图像中进行表达,那么就是按核进行扩展,在二值图像中,膨胀可以填充小的凹陷,链接一些相近的部件,腐蚀可以去除一些小的斑点。
2.IplConvKernel结构
结构typedef struct _IplConvKernel{ int nCols; int nRows; int anchorX; int anchorY; int *values; int nShiftR;}IplConvKernel;在这里,对其中的变量定义做一简单的描述:nCols,nRows:结构元素的行宽与列高;anchorX,anchorY:结构元素原点(锚点)的位置坐标,水平,垂直;nShiftR:用于表示结构元素的形状类型,有如下几个值:#define CV_SHAPE_RECT 0#define CV_SHAPE_CROSS 1#define CV_SHAPE_ELLIPSE 2#define CV_SHAPE_CUSTOM 100分别表示矩形,十字,椭圆和自定义。values:当nShiftR为自定义时,value是指向结构元素数据的指针,如果结构元素的大小定义为8*6,那么values为48长的int数组,值为0或1。
操作函数:
结构IplConvKernel* cvCreateStructuringElementEx( int cols, int rows, int anchor_x, int anchor_y,int shape, int* values=NULL );//创建void cvReleaseStructuringElement( IplConvKernel** element );//释放
以前做过一个点识别的程序,就是用这个实现的,代码图片如下:
形态学灰度操作实例#include "stdafx.h"#include "cv.h"#include "cxcore.h"#include "highgui.h"#include "math.h"int _tmain(int argc, _TCHAR* argv[]){cvNamedWindow("src");cvNamedWindow("dst");cvNamedWindow("thresh");IplImage *img=cvLoadImage("2.bmp");IplImage *img2 = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);IplImage *img3 = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);cvCvtColor(img,img2,CV_BGR2GRAY);cvShowImage("src",img2);IplConvKernel* t = cvCreateStructuringElementEx(11, 11, 6,6,CV_SHAPE_ELLIPSE);cvDilate(img2,img3,t);cvReleaseStructuringElement( &t );cvSaveImage("dst.jpg",img3);cvShowImage("dst",img3);cvThreshold(img3,img2,60,255,CV_THRESH_BINARY);cvShowImage("thresh",img2);cvWaitKey();cvDestroyWindow("thresh");cvDestroyWindow("dst");cvDestroyWindow("src");return 0;}
上面虽然不是一个很好的例子,但是在一定程度上说明形态学灰度的效果。
3. cvMorphologyEx
opencv中实现开运算、闭运算、形态梯度、tophat,baackhat的函数是cvMorphologyEx();具体使用方法:
cvMorphologyExvoid cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp,IplConvKernel* element, int operation, int iterations=1 );src输入图像.dst输出图像.temp临时图像,某些情况下需要element结构元素operation形态操作的类型:CV_MOP_OPEN - 开运算CV_MOP_CLOSE - 闭运算CV_MOP_GRADIENT - 形态梯度CV_MOP_TOPHAT - "顶帽"CV_MOP_BLACKHAT - "黑帽"iterations膨胀和腐蚀次数.函数 cvMorphologyEx 在膨胀和腐蚀基本操作的基础上,完成一些高级的形态变换:开运算dst=open(src,element)=dilate(erode(src,element),element)闭运算dst=close(src,element)=erode(dilate(src,element),element)形态梯度dst=morph_grad(src,element)=dilate(src,element)-erode(src,element)"顶帽"dst=tophat(src,element)=src-open(src,element)"黑帽"dst=blackhat(src,element)=close(src,element)-src临时图像 temp 在形态梯度以及对“顶帽”和“黑帽”操作时的 in-place 模式下需要。
有人说,这个函数使用非对称结构的时候会造成偏移,其实即使使用opencv其他函数实现也会造成偏移,原理使其然,并不阻碍我们使用。
需要说明的是,最后一个参数,例如闭运算,iterations=2的时候,并不是说分别执行2次闭运算,也就是dilate—>erode-->dilate—>erode,实际的情况是dilate—>dilate-->erode—>erode。
(1)开运算,必运算
开运算是先腐蚀,再膨胀,用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。
闭运算是先膨胀,在腐蚀,用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积。
就用《learning opencv》上的图说明吧:
开运算 闭运算
下图为例,演示通过开运算和闭运算消除噪声,突出需要的物体,原图以及经过二值化以后的图像如下:
可以看到二值画以后的图像中,区域边缘有很多毛刺,虽然滤波也可以消除,但是不是很干净,想我采用的形态学操作办法,代码:
形态学操作例子cvNamedWindow("src");cvNamedWindow("dst");IplImage *img=cvLoadImage("12.bmp");IplImage *img2 = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);IplImage *img3 = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);cvCvtColor(img,img2,CV_BGR2GRAY);cvThreshold(img2,img2,60,255,CV_THRESH_BINARY);cvShowImage("src",img2);cvSaveImage("src.jpg",img2);IplConvKernel* t = cvCreateStructuringElementEx(7, 7, 4,4,CV_SHAPE_ELLIPSE);IplConvKernel* t2 = cvCreateStructuringElementEx(5, 5, 3,3,CV_SHAPE_ELLIPSE);cvMorphologyEx(img2,img3,NULL,t2,CV_MOP_OPEN);cvMorphologyEx(img3,img3,NULL,t2,CV_MOP_OPEN);cvMorphologyEx(img3,img3,NULL,t,CV_MOP_CLOSE);cvMorphologyEx(img3,img3,NULL,t,CV_MOP_CLOSE);cvReleaseStructuringElement( &t );cvReleaseStructuringElement( &t2 );cvSaveImage("dst.jpg",img3);cvShowImage("dst",img3);cvWaitKey();cvDestroyWindow("dst");cvDestroyWindow("src");return 0;
即先进性2次开运算,扩大边缘的噪声,在使用闭运算,连接边缘的毛刺,开运算和闭运算的结果如下:
经过开运算,闭运算后,边缘平滑很多,这并不是一个很好的例子,手边刚好有这么一张图片,就一次来说明问题而已
转自:http://www.cnblogs.com/zsb517/archive/2012/06/08/2541193.html
- opencv(5)形态学操作
- OpenCV形态学操作
- OpenCV形态学操作
- opencv之形态学操作
- OpenCV形态学操作
- opencv中的形态学操作
- OpenCV形态学操作
- OpenCV形态学操作
- [转]OpenCV形态学操作
- OpenCV形态学操作
- OpenCV形态学相关操作
- OpenCv形态学操作
- 学习OpenCV---形态学操作
- OpenCV--形态学操作
- opencv--形态学操作
- opencv学习笔记--形态学操作
- opencv形态学操作函数morphologyEx
- OpenCV学习之形态学操作
- 全面剖析XMLHttpRequest对象(1)
- HDU 1175 连连看
- 二分搜索技术
- 编译uClinux时出错
- NYOJ - 小柯的编译器
- opencv(5)形态学操作
- 计算机专业视频大全
- 预装win8的电脑如何安装win7或xp系统
- 关于计算机原理的学习
- Python写爬虫——抓取网页并解析HTML
- SMTP RFC 协议笔记
- 批处理语法
- 全面剖析XMLHttpRequest对象(2)
- 常用的OpenCV函数速查