簡體   English   中英

Opencv平均濾波器提供的輸出與Matlab平均濾波器不同

[英]Opencv average filter gives different output than Matlab average filter

編寫以下OpenCV代碼作為診斷來比較Matlab和OpenCV中的平均濾波器實現。 OpenCV代碼是

Mat P(Size(5,5),CV_64FC1,Scalar(0));

for(int i = 0; i < 5; i++)
{
    for (int j = 0; j < 5 ; j++)
        P.at<double>(i,j) = i;
}


cout<<"Original Matrix is :"<<endl;
cout<<P<<endl;

Mat averageFilter(2,2,CV_64FC1,Scalar(0)),U;
averageFilter = cv::Scalar::all(1.0/(2*2));


filter2D(P, U, -1 , averageFilter, Point( -1, -1 ), 0, BORDER_REPLICATE );
cout<<"Filtered Matrix is :"<<endl;
cout<<U<<endl;  

輸出是

Original Matrix is :
[0, 0, 0, 0, 0;
  1, 1, 1, 1, 1;
  2, 2, 2, 2, 2;
  3, 3, 3, 3, 3;
  4, 4, 4, 4, 4]
Filtered Matrix is :
[0, 0, 0, 0, 0;
  0.5, 0.5, 0.5, 0.5, 0.5;
  1.5, 1.5, 1.5, 1.5, 1.5;
  2.5, 2.5, 2.5, 2.5, 2.5;
  3.5, 3.5, 3.5, 3.5, 3.5]

用於復制相同操作​​的Matlab代碼是:

ma = [0 0 0 0 0;1 1 1 1 1;2 2 2 2 2;3 3 3 3 3;4 4 4 4 4];
MEANF = fspecial('average',[2 2]);
U = imfilter(ma, MEANF, 'replicate');

輸出是

U =

    0.5000    0.5000    0.5000    0.5000    0.5000
    1.5000    1.5000    1.5000    1.5000    1.5000
    2.5000    2.5000    2.5000    2.5000    2.5000
    3.5000    3.5000    3.5000    3.5000    3.5000
    4.0000    4.0000    4.0000    4.0000    4.0000

兩個產出之間出現差異的原因是什么?

您所看到的差異是由於在偶數尺寸濾波器中的原點的不同選擇。 對於奇數大小的內核,軟件往往是一致的,並選擇中間像素作為原點。 但對於偶數大小的內核,有兩種選擇具有同等意義。

我可以通過更改過濾器的原點來復制MATLAB中的OpenCV輸出:

ma = repmat((0:4).',1,5);
filt = zeros(3);
filt(2:3,2:3) = 1/4;
U = imfilter(ma,filt,'replicate')
filt = rot90(filt,2);
V = imfilter(ma,filt,'replicate')

這給了我和你一樣的U

U =
    0.5000    0.5000    0.5000    0.5000    0.5000
    1.5000    1.5000    1.5000    1.5000    1.5000
    2.5000    2.5000    2.5000    2.5000    2.5000
    3.5000    3.5000    3.5000    3.5000    3.5000
    4.0000    4.0000    4.0000    4.0000    4.0000

V就是你在OpenCV中看到的:

V =
         0         0         0         0         0
    0.5000    0.5000    0.5000    0.5000    0.5000
    1.5000    1.5000    1.5000    1.5000    1.5000
    2.5000    2.5000    2.5000    2.5000    2.5000
    3.5000    3.5000    3.5000    3.5000    3.5000

更有啟發性的是創建一個全零的輸入,除了中間的一個值:

ma = zeros(5);
ma(3,3) = 1;
filt = zeros(3);
filt(2:3,2:3) = 1/4;
U = imfilter(ma,filt,'replicate')
filt = rot90(filt,2);
V = imfilter(ma,filt,'replicate')

現在我明白了:

U =
         0         0         0         0         0
         0    0.2500    0.2500         0         0
         0    0.2500    0.2500         0         0
         0         0         0         0         0
         0         0         0         0         0

V =
         0         0         0         0         0
         0         0         0         0         0
         0         0    0.2500    0.2500         0
         0         0    0.2500    0.2500         0
         0         0         0         0         0

很明顯,內核移動了一個像素。 同樣,使用fspecial('average',[2 2])你會得到U的結果,如果你在OpenCV中復制它,你會看到像V這樣的輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM