2013-03-01 106 views
1

我想要過程圖像,因此每個像素值將是其值和4個鄰居的平均值。具有兩種功能差異的平均圖像

創建了兩個不同的功能:

Mat meanImage(cv::Mat& inputImage) 
{ 
    Mat output; 
    Mat kernel(3,3,CV_32F,0.0); 
    kernel.at<float>(0,1) = 0.2; 
    kernel.at<float>(1,0) = 0.2; 
    kernel.at<float>(1,1) = 0.2; 
    kernel.at<float>(1,2) = 0.2; 
    kernel.at<float>(2,1) = 0.2; 
    filter2D(inputImage,output,-1,kernel); 
    return output; 
} 

和:

Mat meanImage2(Mat& inputImage) 
{ 
    Mat temp; 
    Mat output(inputImage.rows,inputImage.cols,inputImage.type()); 
    copyMakeBorder(inputImage,temp,1,1,1,1,BORDER_REPLICATE); 
    CV_Assert(output.isContinuous()); 
    CV_Assert(temp.isContinuous()); 
    const int len = output.rows * output.cols * output.channels(); 
    const int rowLenTemp = temp.cols * temp.channels(); 
    const int twoRowLenTemp = 2 * rowLenTemp; 
    const int rowLen = output.cols * output.channels(); 
    uchar* outPtr = output.ptr<uchar>(0); 
    uchar* tempPtr = temp.ptr<uchar>(0); 
    for(int i = 0; i < len; ++i) 
    { 
     const int a = 6 * (i/rowLen) + 3; 
     outPtr[i] = (tempPtr[i+rowLenTemp+a] + tempPtr[i+a] + 
        tempPtr[i+rowLenTemp+a+3] + tempPtr[i+rowLenTemp+a-3] + 
        tempPtr[i+twoRowLenTemp+a])/5; 
    } 
    return output; 
} 

我認爲結果會是一樣的。所以我比較了圖片:

Mat diff; 
compare(meanImg1,meanImg2,diff,CMP_NE); 
printf("Difference: %d\n",countNonZero(diff)); 
imshow("diff",diff); 

並獲得很多差異。 這個函數有什麼區別?

編輯: 差異性的lena圖像從Lena

Lena_diff

+0

什麼是你的圖像類型? – cedrou 2013-03-01 16:23:27

+0

類型是CV_UC3。 – krzych 2013-03-01 17:07:20

+0

你的意思是CV _ ** 8 ** UC3? – cedrou 2013-03-01 21:41:48

回答

2

採取小心,當你做像素的總和,你添加unsigned char S和你可能會溢出。

通過將這些像素值轉換爲int來測試您的代碼。

outPtr[i] = ((int)tempPtr[i+rowLenTemp+a] + (int)tempPtr[i+a] + 
      (int)tempPtr[i+rowLenTemp+a+3] + (int)tempPtr[i+rowLenTemp+a-3] + 
      (int)tempPtr[i+twoRowLenTemp+a])/5; 

編輯:我寧願這個代碼所示(假設圖像類型是UCHAR,它有3個通道)

for (int r = 0; r < output.rows; r++) 
{ 
    uchar* previousRow = temp.ptr<uchar>(r) + 3; 
    uchar* currentRow = temp.ptr<uchar>(r+1) + 3; 
    uchar* nextRow = temp.ptr<uchar>(r+2) + 3; 

    uchar* outRow = output.ptr<uchar>(r); 

    for (int c = 0; c < 3*output.cols; c++) 
    { 
    int value =    (int)previousRow[c] + 
     (int)currentRow[c-3] + (int)currentRow [c] + (int)currentRow[c+3] + 
          (int)nextRow [c]; 

    outRow[c] = value/5; 
    } 
} 
+0

感謝您的優化建議。它比我的實現更快。我也應用了對int的建議,並看到溢出的可能性。有線的事情是,它沒有任何區別,我已經測試了不同的圖像。這個答案沒有回答我的問題。您的實現結果與我的實現相同,仍與'cv :: filter2D'的'meanImage'不同。 – krzych 2013-03-01 17:33:51

+0

它也應該是'currentRow [c-3]'和'currentRow [c + 3]'我建議編輯。 – krzych 2013-03-01 17:49:57

+0

是的,你是對的...我編輯它。 – cedrou 2013-03-01 21:34:56