2013-11-28 72 views
0

我是新來opencv C++。我得到的卷積代碼(從互聯網),這是相當於conv2在MATLAB中的錯誤。問題是所有的像素值都變成了255。我在代碼中使用的過濾器與圖像大小相同。任何人都可以請幫我糾正problem.My OpenCV的C++代碼如下:在OpenCV C++過濾圖像卷積過程中的錯誤

 #include<opencv2/highgui/highgui.hpp> 
    #include <opencv2/imgproc/imgproc.hpp> 
    #include<stdio.h> 
    #include<iostream> 
    #include<math.h> 
    #include<cv.hpp> 
    using namespace cv; 
    using namespace std; 
    Mat gd,img,bimgFiltered,gimgFiltered,rimgFiltered,fin_img; 
    Mat b,g,r,cr,cb,cg,B,G,R; 
    Mat b_logplane, b_plane,b_logfiltered,b_log,g_logplane,g_plane,g_logfiltered; 
    Mat g_log,r_logplane,r_plane,r_logfiltered,r_log; 
    Mat kernel, dest; 
    int m,n,m1,m2,n1,n2; 
    int c = 120; 
    double mysum = 0.0, mysum1 = 0.0, k = 0; 
    int cent=0,radius=0; 
    enum ConvolutionType { 
    /* Return the full convolution, including border */ 
    CONVOLUTION_FULL, 
    /* Return only the part that corresponds to the original image */ 
    CONVOLUTION_SAME, 
    /* Return only the submatrix containing elements that were not influenced 
    by the border  
    */ 
     CONVOLUTION_VALID 
    }; 

    void conv2(const Mat &img, const Mat& kernel, ConvolutionType type,Mat& dest) 
    { 
    Mat source = img; 
    if(CONVOLUTION_FULL == type) 
    { 
    source = Mat(); 
    const int additionalRows = kernel.rows - 1, additionalCols = kernel.cols - 1; 
    copyMakeBorder(img, source, (additionalRows + 1)/2, additionalRows/2, 
     (additionalCols + 1)/2, additionalCols/2, BORDER_CONSTANT, Scalar(0)); 
    } 

    flip(kernel, kernel, -1); 
    Point anchor(kernel.cols - kernel.cols/2 - 1, kernel.rows - kernel.rows/2 - 1); 
    int borderMode = BORDER_CONSTANT; 
    filter2D(source, dest, img.depth(), kernel, anchor, 0, borderMode); 

    if(CONVOLUTION_VALID == type) 
    { 
    dest = dest.colRange((kernel.cols - 1)/2, dest.cols - kernel.cols/ 
    2).rowRange((kernel.rows - 1)/2, dest.rows - kernel.rows/2); 
    } 
    } 

    int main() 
    { 
    img = imread("milla.bmp", CV_LOAD_IMAGE_COLOR); 
    b.create(img.size(),img.type()); 
    g.create(img.size(),img.type()); 
    r.create(img.size(),img.type()); 

    cr.create(img.size(),img.type()); 
    cg.create(img.size(),img.type()); 
    cb.create(img.size(),img.type()); 

    Mat planes[3]; 
    split(img,planes); 

    bimgFiltered.create(img.size(),img.type()); 
    gimgFiltered.create(img.size(),img.type()); 
    rimgFiltered.create(img.size(),img.type()); 

    dest.create(img.size(), img.type()); 
    gd.create(img.size(), img.type()); 

    for(int j = 0; j < img.rows; j++) 
    { 
    for(int i = 0; i < img.cols; i++) 
    { 
     radius = ((cent - i)^2 + (cent - j)^2); 
     gd.at<float>(j, i) = exp((-(radius)/c^2)); 

     mysum = mysum + gd.at<float>(j, i); 
    } 
    mysum1 = mysum1 + mysum; 
    } 

     k=1/mysum1; 
    cout<<endl<<k<<"\n"<<endl; 

    for(int j = 0; j < img.rows; j++) 
    { 
     for(int i = 0; i < img.cols; i++) 
     { 
     gd.at<float>(j, i) = k * gd.at<float>(j, i); 
     } 
     } 

    planes[0].convertTo(planes[0],CV_32F,1.0/255.0); 
    planes[1].convertTo(planes[1],CV_32F,1.0/255.0); 
    planes[2].convertTo(planes[2],CV_32F,1.0/255.0); 
    conv2(planes[0],gd,CONVOLUTION_SAME,bimgFiltered); 
    conv2(planes[1],gd,CONVOLUTION_SAME,gimgFiltered); 
    conv2(planes[2],gd,CONVOLUTION_SAME,rimgFiltered); 

    imshow("img",gimgFiltered); 
    waitKey(0); 
    return 0; 
    } 

回答

2

沒有與代碼的一些問題:

問題1:

在下面兩行:

radius = ((cent - i)^2 + (cent - j)^2); 
gd.at<float>(j, i) = exp((-(radius)/c^2)); 

您正在使用^操作是按位在C/C++中使用XOR運算符。我認爲你錯把它當做電力運營商。要採取一些你不得不使用pow功能如下功率:

radius = powf((cent - i),2) + powf((cent - j),2); 
gd.at<float>(j, i) = expf((-(radius)/(c*c))); 

問題2:

gd矩陣假設是喜歡gd.at<float>(j, i)訪問有浮點值,但是它的聲明與圖像的類型相同,即CV_8UC3。所以gd應當創建如下:

gd.create(img.size(), CV_32FC1); 

問題3:

另一種可能的邏輯錯誤可以是存在於第一嵌套循環。可能必須在開始內環這樣之前設置mysum = 0;

for(int j = 0; j < img.rows; j++) 
{ 
    mysum = 0; 
    for(int i = 0; i < img.cols; i++) 
    { 
     radius = powf((cent - i),2) + powf((cent - j),2); 
     gd.at<float>(j, i) = expf((-(radius)/(c*c))); 

     mysum = mysum + gd.at<float>(j, i); 
    } 
    mysum1 = mysum1 + mysum; 
} 

問題4:

輸出濾波後的圖像應該被創建,而不是3個信道單信道:

bimgFiltered.create(img.size(),CV_8UC1); 
gimgFiltered.create(img.size(),CV_8UC1); 
rimgFiltered.create(img.size(),CV_8UC1); 
+0

先生謝謝你的回覆。我嘗試了所有這些更正。仍然我沒有得到正確的卷積輸出。我得到一個黑色的圖像,而不是。這是等效的matlab代碼。就是因爲我在轉換到opencv C++時出現了一些問題。 IR = I(:,:,1); Ig = I(:,:,2); Ib = I(:,:,3); cent = ceil(a/2); gd =零(a,b); summ = 0;對於i = 1: 對於j = 1:a radius =((cent-i)^ 2 +(cent-j)^ 2); gd(i,j)= exp( - (radius /(c^2))); end end k = 1 /(sum(sum(gd))) F = k。* gd; F_FIr = conv2(Ir,F,'same'); F_FIg = conv2(F,Ig,'same'); F_FIb = conv2(F,Ib,'same'); – user2943871

+0

@ user2943871 ...您期待什麼輸出?你能從matlab代碼中發佈一個樣本輸入和輸出圖像嗎? – sgarizvi

+0

抱歉,延遲先生。 – user2943871