创建结构元素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, 核是椭圆元素;valuesCV_SHAPE_CUSTOM 核是用户自定义的值, 用户自定义元素。这种情况下参数 values 定义了 mask,即象素的那个邻域必须考虑。
指向结构元素的指针,它是一个平面数组,表示对元素矩阵逐行扫描。(非零点表示该点属于结构元)。如果指针为空,则表示平面数组中的所有元素都是非零的,即结构元是一个长方形(该参数仅仅当shape参数是 CV_SHAPE_CUSTOM 时才予以考虑)。
0,0,1,0函数 cv CreateStructuringElementEx 分配和填充结构 IplConvKernel, 它可作为形态操作中的结构元素。eg:若此为结构元素,指针点为锚点。则需设定shape为 CV_SHAPE_CUSTOM设定: value[] = {0,0,0,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; }