OpenCV学习 6:平滑滤波器 cvSmooth()——2
原创文章,欢迎转载,转载请注明出处
前面进行了彩色的模糊处理,我们对黑白图片进行同样的平滑处理,看看效果。
首先是需要创建黑白图片,我对opencv的各种函数还不是很熟悉,我们可以先用熟悉的创建单通道的图片。
1 IplImage* img = cvCreateImage(cvSize(300, 300), IPL_DEPTH_8U,1);
创建一张300*300pixel大小的图片,然后我们需要对像素进行操作,让图片编程全黑,然后让中心像素为白。
对像素的操作也有不少方法,我们用简单暴力的。
对像素的操作也有不少方法,我们用简单暴力的。
IplImage结构体里面有一个imageData成员,它是指向图像数据的指针,可以通过它直接读写像素。
代码如下:
1 uchar *data; 2 data = (uchar *)img->imageData; 3 for(i = 0; i <img->width; i++) 4 { 5 for (j = 0; j< img->height; j++) 6 { 7 //data[i*img->widthStep+j] = 0; 8 CV_IMAGE_ELEM(img, unsigned char, i, j) = 0; 9 } 10 }
这个很容易理解,就是用一个uchar的指针指向图像数据,然后计算偏移量,然后控制对像素的读写,我们这里偷懒了,用了数组方式的访问,其实和起始地址加偏移量是一样的哈。
可以发现,我们没有用 data[i*img->widthStep+j] = 0;,而是用了CV_IMAGE_ELEM(img, unsigned char, i, j) = 0; CV_IMAGE_ELEM是一个宏,它里面帮我们封装了下,用起来也挺简单的,所以就用它了,其定义在types_c.h里面,它的宏定义如下:
1 /* get reference to pixel at (col,row), 2 for multi-channel images (col) should be multiplied by number of channels */ 3 #define CV_IMAGE_ELEM( image, elemtype, row, col ) \ 4 (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])
这个就不解释了,很容易理解的。接下来就是把中心点设置成白色了,直接套用宏。
1 CV_IMAGE_ELEM(img, unsigned char, img->width/2, img->height/2) = 255;
接下来就用上一节的代码smooth下就好了,
先看看5*5高斯滤波和9*9高斯滤波的效果。如下图,从左到右依次为原图,5*5,9*9
下面我们看看5*5两次和一次9*9效果对比,从左到右依次为原图,5*5两次和9*9
第一眼看上去觉得他们5*5两次和9*9没smooth后的效果差不多,但是实际呢?我们把中心点smooth后的数值答应出来了,在上图的最右边,可以看到原图中心点是255,5*5一次后是36,两次后是19,9*9一次就是14了。。
看点效果不明显,我们把上面的白点变成白面,然后再算一次,