2015-04-02 193 views
1

我想在opencv中實現高斯模糊函數,但是當我嘗試我得到一個噪聲圖像。這裏是我的代碼:OpenCv實現高斯模糊

int main(int argc, char** argv) 
{ 
    src = imread("fruits.jpg", 0); 

    gauss3x3 = Mat(src.cols,src.rows,src.type()); //src.clone(); 

    Mat kernelX = getGaussianKernel(3, 1); 
    Mat kernelY = getGaussianKernel(3, 1); 
    Mat kernelXY = kernelX * kernelY.t(); 

    filter(src,gauss3x3,kernelXY); 

    namedWindow(window_name4, WINDOW_AUTOSIZE); 
    imshow(window_name4,gauss3x3); 
} 

void filter(Mat src, Mat dst, Mat kernel) { 
    cout << "filter" << endl; 

    for(int i=0; i<src.rows - 0; i++) { 
     for(int j=0; j<src.cols - 0; j++) { 
      float p = 0; 
      for(int k=0; k<kernel.rows; k++) { 
       for(int l=0; l<kernel.cols; l++) { 
        if(i+k < src.rows && j+l < src.cols) { 
         p += (src.at<uchar>(i + k,j + l) * kernel.at<uchar>(k,l));      
        } 
       } 
      } 

      if(i + kernel.rows/2 < src.rows && j + kernel.cols/2 < src.cols) { 
       dst.at<uchar>(i + kernel.rows/2,j + kernel.cols/2) = p/sum(kernel)[0]; 
      } 

     } 
    } 
} 

我對解決方案沒有任何想法。任何幫助,將不勝感激。

+0

爲什麼你不想使用OpenCV [GaussianBlur](http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=gaussianblur#gaussianblur)? – Antonio 2015-04-02 21:14:37

+2

原因,這是我的作業。 – cuneytyvz 2015-04-02 21:21:51

回答

1

變化

kernel.at<uchar>(k,l) 

到:

kernel.at<double>(k,l) 

的一點是,爲內核的缺省數據類型是CV_64F,其對應於兩倍(documentation)。

此外,檢查您的輸入圖像是嚴格灰度。爲了支持顏色,你必須在開始時檢測圖像類型並區分你的代碼。要創建函數的顏色版本,您必須首先使用.at<cv::Vec3b>代替(並且這當然不會是唯一必要的修改)。

我建議也是你改變你的函數聲明:

void filter(const Mat& src, Mat& dst, const Mat& kernel) { 

算法的其餘部分看起來不錯,除了它可能是相當緩慢的,它會如果您避免使用at方法要快得多,並限制了週期,因此不必檢查是否要觸摸圖像邊界,並且如果將某些本地常量變量存儲在不同的尺寸中,並在循環中使用它們。最後,sum(kernel)是恆定的,因此您也可以預先計算該值。

+0

感謝您的答案,我找不到嘗試的機會。那麼「dst.at (i + kernel.rows/2,j + kernel.cols/2)= p/sum(kernel)[0];」? – cuneytyvz 2015-04-02 23:51:48

+0

@cuneytyvz這似乎或多或少罰款,除了你隱式鑄造一個雙重字符... – Antonio 2015-04-02 23:53:58

+0

@cuneytyvz還要注意,你的功能只能用於灰度值!如果你想開始改變它,例如一個BGR圖像,你將不得不使用'.at ',它會變得更加複雜 – Antonio 2015-04-02 23:57:15