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和幅度也不同. 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从不扩展卷积结果,所以要小心. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |