卷积,使用filter2D创建自定义线性滤波器

  • 卷积

一个特殊卷积所实现的功能是由其卷积核的形式决定的。这个核本质上是一个大小固定、由数值参数构成的数组,数组的参考点(anchor point,也叫锚点)通常位于数组的中心。

                                                       

上图描述了一个以数组中心为参考点的3X3的卷积核,-4所在为锚点。若要计算图像上某个点的卷积值,则将卷积核的锚点定位到图像上的那个点,让核的其它元素覆盖图像中的相应的像素点。将图像上的点与卷积核对应相乘后再求和,并将这个结果放在图像上锚点的相对位置上。通过在图像上扫描卷积核,对图像的每个点重复此操作。

                                        

可以用以上公式来表示这个过程,其中定义图像为I(x,y),核为G(i,j),其中0<i<Mi-1和0<j<Mj-1,锚点位于相应核的(ai,aj)坐标上。

  •  filter2D函数

 函数原型为:

void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Pointanchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT )

使用这个函数可以将任何的线性变换应用到图像上,其中各参数的含义如下:
src:源图像
dst:目标图像
ddepth:dst的尝试,若为负值(如-1),则表示其深度与源图像相等。
kernel:用来遍历图像的核
anchor:核的锚点的相对位置,其中心点默认为(-1,-1)。
delta:在卷积的过程中,该值会加到每个像素上。默认情况下,这个值为0。
BORDER_DEFAULT:像素插值方法,这里为默认值,详细可以参照borderInterpolate()方法。

  • filter2D例程:
int _tmain(int argc, _TCHAR* argv[])
{
    Mat src = imread("girl.jpg");
    if (!src.data)
    {
        return -1;
    }
    imshow("src",src);

    Mat dst;
    int ddepth = -1;
    Mat kernel;

    int c = 0;
    int ind = 0;
    while(true)
    {
        if (c == 27)
            break;

        int kernel_size = 3 + 2 * (ind % 5);
        cout<<kernel_size<<endl;
        //Mat::ones将定义一个矩阵,里面的元素全部置1
        kernel = Mat::ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);
        filter2D(src,dst,ddepth,kernel);
        ind++;
        imshow("dst",dst);
        waitKey(0);
    }
    return 0;
}

运行该程序,将显示了由归一化滤波器模糊之后的图像。每过1秒,滤波器核的大小(边长从3~11)会有所变化:

       

posted @ 2012-11-27 19:39  笨鸟阿拉  阅读(2934)  评论(0编辑  收藏  举报