七、 图像形态学处理
图像形态学是基于数学拓扑学的概念,主要分析图像几何结构,几何距离、形状、连通性和边界等特点,包括腐蚀(erosion)、膨胀(dilation)、开(opening)、闭(closing)四种基本运算。图像形态学操作一般用于二值图像。二值图像是一种2bit图像,每个像素点的值只有0和1两种情况,二值图像的处理运算速度快,方便提取图像的某些典型的信息,因此广泛地用于各类图像处理中。步骤通常是先依据某些规则将图像二值化,经过处理后提取特征再进行识别。
1、 图像腐蚀
图像腐蚀操作可以缩小图形边界,使整个图形边界向内部收缩。过程描述为对图形A用模板B来腐蚀,将A中每个点扩大成B的形状,若该点仍然包含在A中,则保留,若该点扩大后存在不在A之内的区域,则该点被腐蚀。腐蚀模板可根据具体需求,取正方形、菱形、圆形、十字形等,具体操作可以等效为取模板内的最小值,对二值图像来说,对应点的模板内区域若存在0,则该点被腐蚀。
Opencv函数 做腐蚀操作
CVAPI(void) cvErode( const CvArr* src, CvArr* dst,
IplConvKernel* element CV_DEFAULT(NULL),
int iterations CV_DEFAULT(1) );
参数一:源图像
参数二:输出图像
参数三:结构核元素,默认NULL为3*3矩形
参数四:腐蚀次数,默认1次
注:腐蚀操作实际上是取模板区域内的最小值,对于灰度图像来说,值越大越接近白色,腐蚀操作会让黑色区域变小,白色区域变大。
Opencv函数 创建结构元素,作为腐蚀膨胀的参数
CVAPI(IplConvKernel*) cvCreateStructuringElementEx(
int cols, int rows, int anchor_x, int anchor_y,
int shape, int* values CV_DEFAULT(NULL) );
参数一:列数目
参数二:行数目
参数三:锚点的水平偏移量,为0时以结构元素水平中心做操作
参数四:锚点的垂直偏移量,为0时以结构元素垂直中心做操作
参数五:结构元素形状
enum MorphShapes_c
{
CV_SHAPE_RECT =0,
CV_SHAPE_CROSS =1,
CV_SHAPE_ELLIPSE =2,
CV_SHAPE_CUSTOM =100 //自定义元素
};
参数六:当参数5是自定义元素时,表示自定义元素的数组指针,其中非零值表示属于该结构元素形状中的一点;当为NULL时,表示默认的矩形形状。
代码如下:
IplImage *g_src, *dst;
g_src = cvCreateImage(cvGetSize(m_ipl), IPL_DEPTH_8U, 1);
cvCvtColor(m_ipl, g_src, CV_RGB2GRAY);
dst = cvCreateImage(cvGetSize(g_src), IPL_DEPTH_8U, 1);
IplConvKernel *ker;
ker = cvCreateStructuringElementEx(3, 3, 0, 0, CV_SHAPE_RECT);
cvErode(g_src, dst, ker);
cvNamedWindow(_T("原图像"));
cvShowImage(_T("原图像"), g_src);
cvNamedWindow(_T("腐蚀后图像"));
cvShowImage(_T("腐蚀后图像"), dst);
cvReleaseImage(&g_src);
cvReleaseImage(&dst);
cvReleaseStructuringElement(&ker);
输出结果如下:
2、 图像膨胀
图像膨胀是图像腐蚀的相反操作,即对图像边界向外扩充。对二值图像来说,每个像素为1的值都向外扩张一个结构元素的形状大小的值。
Opencv函数 膨胀操作
CVAPI(void) cvDilate( const CvArr* src, CvArr* dst,
IplConvKernel* element CV_DEFAULT(NULL),
int iterations CV_DEFAULT(1) );
参数一:源图像
参数二:输出图像
参数三:结构核元素,默认NULL为3*3矩形
参数四:膨胀次数,默认1次
注:与腐蚀操作相反,膨胀操作实际上是取模板区域内的最大值。
代码如下:
IplImage *g_src, *dst;
g_src = cvCreateImage(cvGetSize(m_ipl), IPL_DEPTH_8U, 1);
cvCvtColor(m_ipl, g_src, CV_RGB2GRAY);
dst = cvCreateImage(cvGetSize(g_src), IPL_DEPTH_8U, 1);
IplConvKernel *ker;
ker = cvCreateStructuringElementEx(3, 3, 0, 0, CV_SHAPE_RECT);
cvDilate(g_src, dst, ker);
cvNamedWindow(_T("原图像"));
cvShowImage(_T("原图像"), g_src);
cvNamedWindow(_T("膨胀后图像"));
cvShowImage(_T("膨胀后图像"), dst);
cvReleaseImage(&g_src);
cvReleaseImage(&dst);
cvReleaseStructuringElement(&ker);
输出结果如下:
3、 图像形态学运算
- 开运算
将图像先腐蚀再膨胀,可以平滑图像的轮廓,消弱掉一些尖锐狭长部分或孤立点。 - 闭运算
将图像先膨胀后腐蚀,可以填充图像中的小洞,连接狭小的空隙,融合窄的缺口,平滑图像轮廓。 - 形态梯度
将图像膨胀后的结果减去腐蚀的结果,可以计算图形轮廓的趋势。 - 顶帽
原图像减去开运算的结果,分离出原图像边缘周围比较亮的区域 - 黑帽
闭运算减去原图像的结果,分离出原图像边缘周围比较暗的区域
Opencv函数 形态学操作
CVAPI(void) cvMorphologyEx( const CvArr* src, CvArr* dst,
CvArr* temp, IplConvKernel* element,
int operation, int iterations CV_DEFAULT(1) );
参数一:源图像
参数二:输出图像
参数三:临时图像,做形态梯度、顶帽和黑帽时用到
参数四:结构核元素,默认NULL为3*3矩形
参数五:操作方式
/** Morphological operations */
enum
{
CV_MOP_ERODE =0,
CV_MOP_DILATE =1,
CV_MOP_OPEN =2,
CV_MOP_CLOSE =3,
CV_MOP_GRADIENT =4,
CV_MOP_TOPHAT =5,
CV_MOP_BLACKHAT =6
};
参数六:操作迭代次数
代码如下:
IplImage *g_src, *dst;
g_src = cvCreateImage(cvGetSize(m_ipl), IPL_DEPTH_8U, 1);
cvCvtColor(m_ipl, g_src, CV_RGB2GRAY);
dst = cvCreateImage(cvGetSize(g_src), IPL_DEPTH_8U, 1);
IplConvKernel *ker;
ker = cvCreateStructuringElementEx(3, 3, 0, 0, CV_SHAPE_RECT);
cvMorphologyEx(g_src, dst, NULL, ker, CV_MOP_CLOSE);
cvNamedWindow(_T("原图像"));
cvShowImage(_T("原图像"), g_src);
cvNamedWindow(_T("开运算后图像"));
cvShowImage(_T("开运算后图像"), dst);
cvReleaseImage(&g_src);
cvReleaseImage(&dst);
cvReleaseStructuringElement(&ker);
输出结果如下: