1. 程式人生 > >opencv學習(七)之影象卷積運算函式filter2D()

opencv學習(七)之影象卷積運算函式filter2D()

接上篇
在其官方文件中,filter2D()函式在掩模板介紹中一筆帶過,我認為該函式應該進行詳細介紹。
對於使用掩模板矩陣(kernel)計算每個畫素值,結合函式filter2D()函式,其定義如下:

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

其官方指導檔案對filter2D()函式的描述為:Convolves an image with kernel即利用核心實現對影象的卷積運算。引數含義如下:

InputArray src: 輸入影象

OutputArray dst: 輸出影象,和輸入影象具有相同的尺寸和通道數量

int ddepth: 目標影象深度,如果沒寫將生成與原影象深度相同的影象。原影象和目標影象支援的影象深度如下:

    src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F
    src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F
    src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F
    src.depth() = CV_64F, ddepth = -1/CV_64F

當ddepth輸入值為-1時,目標影象和原影象深度保持一致。

InputArray kernel: 卷積核(或者是相關核),一個單通道浮點型矩陣。如果想在影象不同的通道使用不同的kernel,可以先使用split()函式將影象通道事先分開。

Point anchor: 核心的基準點(anchor),其預設值為(-1,-1)說明位於kernel的中心位置。基準點即kernel中與進行處理的畫素點重合的點。

double delta: 在儲存目標影象前可選的新增到畫素的值,預設值為0

int borderType: 畫素向外逼近的方法,預設值是BORDER_DEFAULT,即對全部邊界進行計算。

該函式使用於任意線性濾波器的影象,支援就地操作。當其中心移動到影象外,函式可以根據指定的邊界模式進行插值運算。函式實質上是計算kernel與影象的相關性而不是卷積:
這裡寫圖片描述
也就是說kernel並不是中心點的映象,如果需要一個正真的卷積,使用函式flip()並將中心點設定為(kernel.cols - anchor.x - 1, kernel.rows - anchor.y -1).
該函式在大核(11x11或更大)的情況下使用基於DFT的演算法,而在小核情況下使用直接演算法(使用createLinearFilter()檢索得到).
示例程式如下:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat srcImage = imread("lena.jpg");

    //判斷影象是否載入成功
    if(srcImage.data)
        cout << "影象載入成功!" << endl << endl;
    else
    {
        cout << "影象載入失敗!" << endl << endl;
        return -1;
    }
    namedWindow("srcImage", WINDOW_AUTOSIZE);
    imshow("srcImage", srcImage);

    Mat kern = (Mat_<char>(3,3) << 0, -1 ,0,
                                   -1, 5, -1,
                                   0, -1, 0);
    Mat dstImage;
    filter2D(srcImage,dstImage,srcImage.depth(),kern);
    namedWindow("dstImage",WINDOW_AUTOSIZE);
    imshow("dstImage",dstImage);


    waitKey(0);

    return 0;
}

執行結果如下:
這裡寫圖片描述
與上一篇執行結果相比並沒有黑邊存在!