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;
}
執行結果如下:
與上一篇執行結果相比並沒有黑邊存在!