首页 > 代码库 > OpenCV笔记(三)——线性滤波

OpenCV笔记(三)——线性滤波

对像素(i, j)做线性滤波的方法:

1. 做一个3X3的矩阵,分别赋予(i, j)和它的4邻域和D邻域相应的权值。

2. 计算。

示例代码如下:

 1 void Sharpen(const Mat& myImage,Mat& Result) 2 { 3     CV_Assert(myImage.depth() == CV_8U);  // accept only uchar images 4  5     const int nChannels = myImage.channels(); 6     Result.create(myImage.size(),myImage.type()); 7  8     for(int j = 1 ; j < myImage.rows-1; ++j) 9     {10         const uchar* previous = myImage.ptr<uchar>(j - 1);11         const uchar* current  = myImage.ptr<uchar>(j    );12         const uchar* next     = myImage.ptr<uchar>(j + 1);13 14         uchar* output = Result.ptr<uchar>(j);15 16         for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i)17         {18             *output++ = saturate_cast<uchar>(5*current[i]19                          -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);20         }21     }22 23     Result.row(0).setTo(Scalar(0));24     Result.row(Result.rows-1).setTo(Scalar(0));25     Result.col(0).setTo(Scalar(0));26     Result.col(Result.cols-1).setTo(Scalar(0));27 }

 

第10行、11行、12行分别使用指针指向上一行、当前行、下一行。

第18行就是对当前像素进行滤波操作。滤波的矩阵为(0, -1, 0,

                       -1,  5, -1,

                        0,  -1, 0)

函数当中使用ptr<uchar>方法,返回指向某行的指针,用来遍历当前行的每个字节,而非像素。

第23行,row(0)和col(0)分别返回第0行和第0列的所有元素构成的Mat。

setTo(Scalar(0))方法调用,将调用它的Mat所有元素设为Scalar(0)。

 

OpenCV实现了线性滤波的方法:filter2D。

1     Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,2                                    -1,  5, -1,3                                     0, -1,  0);4     t = (double)getTickCount();5     filter2D(I, K, I.depth(), kern ); /* 其中I是输入的Mat,K是输出的Mat*/

 

filter2D的声明为

C++: void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, intborderType=BORDER_DEFAULT )

前面四个参数都很清楚了。

第五个参数anchor是中心点在kernel矩阵中的相对位置。可能有点抽象,看下面这个式子,就清楚anchor了:

 

第六个参数delta,是在将结果保存至dst之前,加上一个常数。

第七个参数borderType,暂时没看是什么。

 

OpenCV笔记(三)——线性滤波