分段边缘 [英] Segmentation Edges

查看:184
本文介绍了分段边缘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究需要检测不同类型文档轮廓的项目。
目前我能够使用findcontours分割和检测轮廓,在大多数情况下一切正常。
但是,如果文档是白色并且背景类似于白色,我无法检测到轮廓。
例如,在此图像中



或此xhttp://i.stack.imgur.com/ 9exrg.jpg



我无法检测白皮书。
这是我用来分割图像以检测完美边缘(无孔边缘)/完全笔直的代码。

  public static Mat process(Mat original){
Mat src = original.clone();
Mat hsvMat = new Mat();
Mat gray = new Mat();
Mat sobx = new Mat();
Mat soby = new Mat();
Mat grad_abs_val_approx = new Mat();

Imgproc.cvtColor(src,hsvMat,Imgproc.COLOR_BGR2HSV);
列表< Mat> hsv_channels = new ArrayList< Mat>(3);
Core.split(hsvMat,hsv_channels);
Mat hue = hsv_channels.get(0);
Mat sat = hsv_channels.get(1);
Mat val = hsv_channels.get(2);

Imgproc.GaussianBlur(val,grey,new Size(9,9),2,2);
Mat imf = new Mat();
gray.convertTo(imf,CV_32FC1,0.5f,0.5f);

Imgproc.Sobel(imf,sobx,-1,1,0);
Imgproc.Sobel(imf,soby,-1,0,1);

sobx = sobx.mul(sobx);
soby = soby.mul(soby);

Mat sumxy = new Mat();
Core.add(sobx,soby,sumxy);
Core.pow(sumxy,0.5,grad_abs_val_approx);

sobx.release();
soby.release();
sumxy.release();;


Mat filtered = new Mat();
Imgproc.GaussianBlur(grad_abs_val_approx,filtered,new Size(9,9),2,2);

final MatOfDouble mean = new MatOfDouble();
final MatOfDouble stdev = new MatOfDouble();
Core.meanStdDev(filtered,mean,stdev);

Mat thresholded = new Mat();
Imgproc.threshold(filtered,thresholded,mean.toArray()[0] + stdev.toArray()[0],1.0,Imgproc.THRESH_TOZERO);

Mat conversion = new Mat();
thresholded.convertTo(converted,CV_8UC1);
返回转换;
}

使用上面的代码会产生以下结果:





正如您所注意到的那样,边缘并不是完全笔直的(并且有孔洞) )。边缘几乎看不到,Findcontours无法检测到轮廓。



我已经尝试了所有解决方案/建议


i am working on project where i need to detect the contour of differents type of document. Currently i am able to segment and detect contours using findcontours and everything works fine in most cases. But, if the document is white color and the background similar to white color, i can't detect the contour. For example, in this image

or this xhttp://i.stack.imgur.com/9exrg.jpg

i can't detect the white paper. Here is the code i am using to segment the image in order to detect perfect edge (edges with no holes) / Perfectly straight.

public static Mat process(Mat original){
Mat src = original.clone();
Mat hsvMat = new Mat();
Mat gray = new Mat();
Mat sobx = new Mat();
Mat soby = new Mat();
Mat grad_abs_val_approx = new Mat();

Imgproc.cvtColor(src, hsvMat, Imgproc.COLOR_BGR2HSV);
List<Mat> hsv_channels = new ArrayList<Mat>(3);
Core.split(hsvMat, hsv_channels);
Mat hue = hsv_channels.get( 0 );
Mat sat = hsv_channels.get( 1 );
Mat val = hsv_channels.get( 2 );

Imgproc.GaussianBlur(val, gray, new Size(9, 9), 2, 2);
Mat imf = new Mat();
gray.convertTo(imf, CV_32FC1, 0.5f, 0.5f);

Imgproc.Sobel(imf, sobx, -1, 1, 0);
Imgproc.Sobel(imf, soby, -1, 0, 1);

sobx = sobx.mul(sobx);
soby = soby.mul(soby);

Mat sumxy = new Mat();
Core.add(sobx,soby, sumxy);
Core.pow(sumxy, 0.5, grad_abs_val_approx);

sobx.release();
soby.release();
sumxy.release();;


Mat filtered = new Mat();
Imgproc.GaussianBlur(grad_abs_val_approx, filtered, new Size(9, 9), 2, 2);

final MatOfDouble mean = new MatOfDouble();
final MatOfDouble stdev = new MatOfDouble();
Core.meanStdDev(filtered, mean, stdev);

Mat thresholded = new Mat();
Imgproc.threshold(filtered, thresholded, mean.toArray()[0] + stdev.toArray()[0], 1.0, Imgproc.THRESH_TOZERO);

Mat converted = new Mat();
thresholded.convertTo(converted, CV_8UC1);
return converted;
}

Using the code above leads to the following result :

As you can notice, the edges is not Perfectly straight (and there is holes). Edges are barely visible and Findcontours fails to detect the contours.

I have tried alls solutions/suggestions described here

therefore, here is my questions :

1) what's wrong with my code ?

2) how can i preprocess the image in order to detect perfect edge (edges with no holes) / Perfectly straight for contour detection ?

Many thanks in advance for your assistance.

解决方案

When you see that the edges are not easily detected, you can try other complementary approaches. For example, on this image, the simple matlab code (which you can implement using OpenCV):

I=imread('page.png');
r=I(:,:,1);
g=I(:,:,2);
b=I(:,:,3);
imshow(b>g);

Produces the following result, which you can use using your edge detection code:

这篇关于分段边缘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆