图像数学形态学变换

创建结构元素
IplConvKernel* cvCreateStructuringElementEx
int         cols, 
int         rows, 
int         anchor_x, 
int         anchor_y,
int         shape, 
int*        values=NULL );
cols
结构元素的列数目
rows
结构元素的行数目
anchor_x
锚点的相对水平偏移量
anchor_y
锚点的相对垂直偏移量
shape
结构元素的形状,可以是下列值:
CV_SHAPE_RECT,                核是矩形 ;
CV_SHAPE_CROSS,             核是十字交叉型 a cross-shaped element;
CV_SHAPE_ELLIPSE,           核是椭圆元素;
CV_SHAPE_CUSTOM          核是用户自定义的值
, 用户自定义元素。这种情况下参数 values 定义了 mask,即象素的那个邻域必须考虑。
values
指向结构元素的指针,它是一个平面数组,表示对元素矩阵逐行扫描。(非零点表示该点属于结构元)。如果指针为空,则表示平面数组中的所有元素都是非零的,即结构元是一个长方形(该参数仅仅当shape参数是  CV_SHAPE_CUSTOM 时才予以考虑)。

函数 cv CreateStructuringElementEx 分配和填充结构 IplConvKernel, 它可作为形态操作中的结构元素。
eg:
若此为结构元素,指针点为锚点。则需设定shape为 CV_SHAPE_CUSTOM
设定: value[] = {0,0,0,0
                                    0,0,1,0
                                    0,1,1,0
                                    0,0,0,0}

删除结构元素  
void   cvReleaseStructuringElement( IplConvKernel** element );
element  
被删除的结构元素的指针
函数 cvReleaseStructuringElement 释放结构 IplConvKernel 。如果 *element 为 NULL, 则函数不作用。

使用任意结构元素腐蚀图像 
void cvErode(       const CvArr*         src, 
CvArr*                   dst, 
IplConvKernel *   element=NULL, 
int                        iterations=1 );
src 
输入图像.
dst 
输出图像.
element 
用于腐蚀的结构元素。若为 NULL, 则使用 3×3 矩形的结构元素
iterations 
腐蚀的次数
函数 cvErode 对输入图像使用指定的结构元素进行腐蚀,该结构元素决定每个具有最小值象素点的邻域形状: 

dst=erode(src,element): dst(x,y)=min((x',y') in element))src(x+x',y+y')
函数可能是本地操作,不需另外开辟存储空间的意思。腐蚀可以重复进行 (iterations) 次. 对彩色图像,每个彩色通道单独处理。

使用任意结构元素膨胀图像 
void cvDilate
const CvArr*          src, 
CvArr*                    dst, 
IplConvKernel*     element=NULL, 
int                          iterations=1 );
src 
输入图像.
dst 
输出图像.
element 
用于膨胀的结构元素。若为 NULL, 则使用 3×3 矩形的结构元素
iterations 
膨胀的次数
函数 cvDilate 对输入图像使用指定的结构元进行膨胀,该结构决定每个具有最小值象素点的邻域形状:
dst=dilate(src,element): dst(x,y)=max((x',y') in element))src(x+x',y+y')
函数支持(in-place)模式。膨胀可以重复进行 (iterations) 次. 对彩色图像,每个彩色通道单独处理。

高级形态学变换  
void cvMorphologyEx(  const CvArr*           src
CvArr*                     dst
CvArr*                     temp,
IplConvKernel*       element,
int                            operation
int                           iterations=1 );
src 
输入图像.
dst 
输出图像.
temp 
临时图像,某些情况下需要
element 
结构元素
operation 
形态操作的类型:
        名称                          形态学操作       是否需要临时图像?(temp)
CV_MOP_OPEN                 开运算                      否
CV_MOP_CLOSE                闭运算                      否
CV_MOP_GRADIENT       形态梯度                   总是
CV_MOP_TOPHAT            "礼帽"                      需要(in-place时)
CV_MOP_BLACKHAT         "黑帽"                      需要(in-place时)
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 模式下需要。 
 
 
 
#include "cv.h"
#include "highgui.h"

int main(int argc, char **argv)
{
	// 载入图像 彩色
	IplImage *src_clr_img = cvLoadImage("lena.bmp", 1) ;
	if (NULL == src_clr_img)
	{
		perror("lena.bmp");
		return 0;
	}
	// bgr to gray
	IplImage *src_gray_img = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 1);
	cvCvtColor(src_clr_img, src_gray_img, CV_BGR2GRAY);
	// temp image
	IplImage *temp = cvCreateImage(cvSize(src_clr_img->width, src_clr_img->height),
		IPL_DEPTH_8U, 3);
	// create destination image
	IplImage *des_clr_erode = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 3);
	IplImage *des_gray_erode = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 1);
	IplImage *des_clr_dilate = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 3);
	IplImage *des_gray_dilate = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 1);
	IplImage *des_clr_open = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 3);
	IplImage *des_clr_close = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 3);
	IplImage *des_clr_gradient = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 3);
	IplImage *des_clr_tophat = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 3);
	IplImage *des_clr_blackhat = cvCreateImage(cvGetSize(src_clr_img), IPL_DEPTH_8U, 3);

	// 结构元素
	// a.系统自带核CV_SHAPE_RECT,_CROSS,_ELLIPSE
	IplConvKernel *element = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT, NULL);
	// b.自定义核CV_SHAPE_CUSTOM
	int kernel_value[] =	{0,1,1,0,
							1,1,1,1,
							0,1,1,0};
	IplConvKernel *element_custom = cvCreateStructuringElementEx(3,4,2,2,CV_SHAPE_CUSTOM, kernel_value);
	// 腐蚀操作
	cvErode(src_clr_img, des_clr_erode, element_custom, 1);
	cvErode(src_gray_img, des_gray_erode, element_custom, 1);
	// 膨胀操作
	cvDilate(src_clr_img, des_clr_dilate, element_custom, 1);
	cvDilate(src_gray_img, des_gray_dilate, element_custom, 1);
	// 更通用的形态学变换
	// 开运算
	cvMorphologyEx(src_clr_img, des_clr_open, temp, element, CV_MOP_OPEN, 1);
	// 闭运算
	cvMorphologyEx(src_clr_img, des_clr_close, temp, element, CV_MOP_CLOSE, 1);
	// 形态学梯度
	cvMorphologyEx(src_clr_img, des_clr_gradient, temp, element, CV_MOP_GRADIENT, 1);
	// 礼帽
	cvMorphologyEx(src_clr_img, des_clr_tophat, temp, element, CV_MOP_TOPHAT, 1);
	// 黑帽
	cvMorphologyEx(src_clr_img, des_clr_blackhat, temp, element, CV_MOP_BLACKHAT, 1);
	// create window
	cvNamedWindow("src_clr", 1);
	cvNamedWindow("src_gray", 1);
	cvNamedWindow("des_clr_erode", 1);
	cvNamedWindow("des_gray_erode", 1);
	cvNamedWindow("des_clr_dilate", 1);
	cvNamedWindow("des_gray_dilate", 1);
	cvNamedWindow("des_clr_open", 1);
	cvNamedWindow("des_clr_close", 1);
	cvNamedWindow("des_clr_gradient", 1);
	cvNamedWindow("des_clr_tophat", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("des_clr_blackhat", CV_WINDOW_AUTOSIZE);


	// show image
	cvShowImage("src_clr", src_clr_img);
	cvShowImage("src_gray", src_gray_img);
	cvShowImage("des_clr_erode", des_clr_erode);
	cvShowImage("des_gray_erode", des_gray_erode);
	cvShowImage("des_clr_dilate", des_clr_dilate);
	cvShowImage("des_gray_dilate", des_gray_dilate);
	cvShowImage("des_clr_open", des_clr_open);
	cvShowImage("des_clr_close", des_clr_close);
	cvShowImage("des_clr_gradient", des_clr_gradient);
	cvShowImage("des_clr_tophat", des_clr_gradient);
	cvShowImage("des_clr_blackhat", des_clr_blackhat);
	cvWaitKey(0);
	// release and destroy
	cvReleaseImage(&src_clr_img);
	cvReleaseImage(&src_gray_img);
	cvReleaseImage(&des_clr_erode);
	cvReleaseImage(&des_gray_erode);
	cvReleaseImage(&des_clr_dilate);
	cvReleaseImage(&des_gray_dilate);
	cvReleaseImage(&des_clr_open);
	cvReleaseImage(&des_clr_close);
	cvReleaseImage(&des_clr_gradient);
	cvReleaseImage(&des_clr_tophat);
	cvReleaseImage(&des_clr_blackhat);
	cvDestroyAllWindows();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值