简体   繁体   中英

Sobel filter output from opencv and Matlab different

I am converting some code from matlab to opencv. I tried to use Sobel in opencv but the output of opencv and matlab is completely different what could be the reason. How can I make the ouput of opencv same as matlab? My MATLAB code is :

 [sobel_edges,T,V,H] = edge(rgb2gray(im),'sobel',0.03);
  sobel_angles = atan2(V,H); 
  sobel_weights = (V.*V+H.*H).^0.5;

where 0.03 is the threshold. In opencv when I use the prebuilt Sobel filter the output is completely different that of matlab even the engle and magnitude calculated in openc vis different. The opencv code is:

Mat gray_img=Mat::zeros(img.size(),CV_8U);
Mat gradientX=Mat::zeros(gray_img.size(),CV_64F);
Mat gradientY=Mat::zeros(gray_img.size(),CV_64F);
Mat sobel_edge=Mat::zeros(gray_img.size(),CV_64F);
cvtColor(img, gray_img, CV_BGR2GRAY);
Sobel(gray_img, gradientX, gradientX.type(), 1, 0, 3);
Sobel(gray_img, gradientY, gradientY.type(), 0, 1, 3);
Sobel(gray_img,sobel_edge,sobel_edge.type(),1,1,3);
sobel_edge.convertTo(sobel_edge,CV_8U);
sobel_edge.convertTo(sobel_edge,CV_64F);
sobel_edge=sobel_edge/255.0; //I divided this my 255 becuz in MATLAB the output is between 0 to 1
imshow("Sobel",sobel_edge);

   Mat magnitude(gray_img.size(), CV_64F, cv::Scalar(0.0));
    Mat angles=Mat::zeros(gradientX.size(),CV_64F);
    bool anglesInDegrees = true;
    cartToPolar(gradientX, gradientY, magnitude, angles, anglesInDegrees);

The sobel edge itself is different and the magnitude and angle too, I tried to convert manually too the sobel in opencv by looking at the edge function in matlab but still the output is different because it turns out the filter2D of opencv and imfilter in matlab returns different output. How can I obtain the same output of sobel in matlab and opencv???The code of manually converting sobel of matlab to opencv is:

Mat gray_img=Mat::zeros(img.size(),CV_32FC1);
  cvtColor(img, gray_img, CV_RGB2GRAY);
  double minVal,maxVal;
  cv::Mat gray = cv::Mat(gray_img.size(),CV_32FC1);
  gray_img.convertTo(gray_img,CV_32FC1);
  gray=gray_img/255.0;
  cout<<gray<<endl<<"End";
  double data[]={1,2,1,0,0,0,-1,2,-1};
  Mat op=Mat(3,3,CV_64F,data).clone();
  op=op/8;
  Mat x_mask;
  transpose(op,x_mask);
  cout<<x_mask<<endl;
  Mat y_mask=op.clone();
  int scale=4;
  int offset[]={0,0,0,0};
  double sobel_thresh=0.03;
  Mat bx,by,bx_mul,by_mul,b;
  Point anchor(0,0);
  float delta = 0.0;
  cv::filter2D(gray, bx, CV_32FC1, x_mask, anchor, delta, BORDER_REPLICATE);
   bx=abs(bx);
   imshow("f1",bx);

  cv::filter2D(gray, by, CV_32FC1, y_mask, anchor, delta, BORDER_REPLICATE);
   by=abs(by);
  imshow("by",by);

  pow(bx,2,bx_mul);
      imshow("f2",bx_mul);
  pow(by,2,by_mul);
  b= bx_mul+by_mul;
   imshow("f3",b);

  double cut_off;
  cut_off=pow(sobel_thresh,2);
  Mat sobel_edge(gray.size(),CV_32FC1);
    for(int i=0;i<b.rows;i++)
    {
        for(int j=0;j<b.cols;j++)
        {
            if((b.at<float>(i,j))>cut_off)
            {
                sobel_edge.at<float>(i,j)=1;
            }
            else
            {
               sobel_edge.at<float>(i,j)=0;
            }
        }
    }
    imshow("Sobel_edge",sobel_edge);

This code gives me the same result as MATLAB code:

int main(int argc, char* argv[])
{
    namedWindow("result");
    Mat img=imread("D:\\ImagesForTest\\1.tiff",0);
    img.convertTo(img,CV_32FC1,1.0/255.0);
    Mat h,v,g;
    cv::Sobel(img,h,-1,1,0,3,1.0/8.0);
    cv::Sobel(img,v,-1,0,1,3,1.0/8.0);
    cv::magnitude(h,v,g);

    // Check extremums
    double m,M;
    cv::minMaxLoc(g,&m,&M);
    cout << m << ":" << M << endl;
    cv::minMaxLoc(h,&m,&M);
    cout << m << ":" << M << endl;
    cv::minMaxLoc(v,&m,&M);
    cout << m << ":" << M << endl;
    imshow("result",g);
    cv::waitKey(0);
}

OpenCV never scales convolution result, so, be careful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM