OpenCV實現(xiàn)可分離濾波
更新時間:2021年06月23日 11:54:55 作者:我有一個夢想
這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)可分離濾波,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
自定義濾波
無論是圖像卷積還是濾波,在原圖像上移動濾波器的過程中每一次的計算結(jié)果都不會影響到后面過程的計算結(jié)果,因此圖像濾波是一個并行的算法,在可以提供并行計算的處理器中可以極大的加快圖像濾波的處理速度。
圖像濾波還具有可分離性
先對X(Y)方向濾波,再對Y(X)方向濾波的結(jié)果與將兩個方向的濾波器聯(lián)合后整體濾波的結(jié)果相同。兩個方向的濾波器的聯(lián)合就是將兩個方向的濾波器相乘,得到一個矩形的濾波器

void filter2D( InputArray src, OutputArray dst, int ddepth,
InputArray kernel, Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT );
- src:待濾波圖像
- dst:輸出圖像,與輸入圖像src具有相同的尺寸、通道數(shù)和數(shù)據(jù)類型。
- ddepth:輸出圖像的數(shù)據(jù)類型(深度),根據(jù)輸入圖像的數(shù)據(jù)類型不同擁有不同的取值范圍,具體的取值范圍在表5-1給出,當賦值為-1時,輸出圖像的數(shù)據(jù)類型自動選擇。
- kernel:濾波器。
- anchor:內(nèi)核的基準點(錨點),其默認值為(-1,-1)代表內(nèi)核基準點位于kernel的中心位置?;鶞庶c即卷積核中與進行處理的像素點重合的點,其位置必須在卷積核的內(nèi)部。
- delta:偏值,在計算結(jié)果中加上偏值。
- borderType:像素外推法選擇標志,取值范圍在表3-5中給出。默認參數(shù)為BORDER_DEFAULT,表示不包含邊界值倒序填充。
void sepFilter2D( InputArray src, OutputArray dst, int ddepth,
InputArray kernelX, InputArray kernelY,
Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT );
- src:待濾波圖像
- dst:輸出圖像,與輸入圖像src具有相同的尺寸、通道數(shù)和數(shù)據(jù)類型。
- ddepth:輸出圖像的數(shù)據(jù)類型(深度),根據(jù)輸入圖像的數(shù)據(jù)類型不同擁有不同的取值范圍,具體的取值范圍在表5-1給出,當賦值為-1時,輸出圖像的數(shù)據(jù)類型自動選擇。
- kernelX:X方向的濾波器,
- kernelY:Y方向的濾波器。
- anchor:內(nèi)核的基準點(錨點),其默認值為(-1,-1)代表內(nèi)核基準點位于kernel的中心位置?;鶞庶c即卷積核中與進行處理的像素點重合的點,其位置必須在卷積核的內(nèi)部。
- delta:偏值,在計算結(jié)果中加上偏值。
- borderType:像素外推法選擇標志,取值范圍在表3-5中給出。默認參數(shù)為BORDER_DEFAULT,表示不包含邊界值倒序填充。
簡單示例
//
// Created by smallflyfly on 2021/6/15.
//
#include "opencv2/highgui.hpp"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main() {
float points[] = {
1, 2, 3, 4, 5,
6, 7, 8, 9, 10,
11, 12, 13, 14, 15,
16, 17, 18, 19, 20,
21, 22, 23, 24, 25
};
Mat data(5, 5, CV_32FC1, points);
// 驗證高斯濾波器可分離
Mat gaussX = getGaussianKernel(3, 1);
cout << gaussX << endl;
Mat gaussDstData, gaussDataXY;
GaussianBlur(data, gaussDstData, Size(3, 3), 1, 1, BORDER_CONSTANT);
sepFilter2D(data, gaussDataXY, -1, gaussX, gaussX, Point(-1, -1), 0, BORDER_CONSTANT);
cout << gaussDstData << endl;
cout << gaussDataXY << endl;
cout << "######################################" << endl;
// Y方向上濾波
Mat a = (Mat_<float>(3, 1) << -1, 3, -1);
// X方向上濾波
Mat b = a.reshape(1, 1);
// XY聯(lián)合濾波
Mat ab = a * b;
Mat dataX, dataY, dataXY1, dataXY2, dataSepXY;
filter2D(data, dataX, -1, b);
filter2D(dataX, dataXY1, -1, a);
filter2D(data, dataXY2, -1, ab);
sepFilter2D(data, dataSepXY, -1, a, b);
// 驗證結(jié)果
cout << dataXY1 << endl;
cout << dataXY2 << endl;
cout << dataSepXY << endl;
Mat im = imread("test.jpg");
resize(im, im, Size(0, 0), 0.5, 0.5);
Mat imX, imY, imXY, imSepXY;
filter2D(im, imX, -1, b);
filter2D(imX, imXY, -1, a);
sepFilter2D(im, imSepXY, -1, a, b);
imshow("imXY", imXY);
imshow("imSepXY", imSepXY);
waitKey(0);
destroyAllWindows();
return 0;
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于對話框程序中讓對話框捕獲WM_KEYDOWN消息的實現(xiàn)方法
下面我們將通過程序給大家演示基于對話框的應(yīng)用程序?qū)M_KEYDOWN消息的捕獲。需要的朋友可以參考下2013-05-05

