加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 来自opencv和Matlab的Sobel滤波器输出不同

发布时间:2020-12-16 07:05:43 所属栏目:百科 来源:网络整理
导读:我正在将一些代码从matlab转换为opencv.我尝试在opencv中使用Sobel但是opencv和matlab的输出完全不同可能是原因.如何使opencv的输出与matlab相同?我的MATLAB代码是: [sobel_edges,T,V,H] = edge(rgb2gray(im),'sobel',0.03); sobel_angles = atan2(V,H); s
我正在将一些代码从matlab转换为opencv.我尝试在opencv中使用Sobel但是opencv和matlab的输出完全不同可能是原因.如何使opencv的输出与matlab相同?我的MATLAB代码是:

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

其中0.03是阈值.在opencv中,当我使用预构建的Sobel滤波器时,输出与matlab的输出完全不同,即使是在openc中计算的engle和幅度也不同.
opencv代码是:

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,3);
Sobel(gray_img,gradientY,gradientY.type(),sobel_edge,sobel_edge.type(),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,magnitude,angles,anglesInDegrees);

sobel边缘本身也是不同的,幅度和角度也是不同的,我试图通过查看matlab中的边缘函数来手动转换opencv中的sobel,但输出仍然不同,因为它结果是opencv的filter2D和matlab中的imfilter返回不同的输出.如何在matlab和opencv中获得相同的sobel输出?将slab of matlab手动转换为opencv的代码为:

Mat gray_img=Mat::zeros(img.size(),CV_32FC1);
  cvtColor(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,-1};
  Mat op=Mat(3,3,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};
  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,y_mask,BORDER_REPLICATE);
   by=abs(by);
  imshow("by",by);

  pow(bx,bx_mul);
      imshow("f2",bx_mul);
  pow(by,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);

解决方法

这段代码给出了与MATLAB代码相同的结果:

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

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

OpenCV从不扩展卷积结果,所以要小心.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读