分段边缘 [英] Segmentation Edges
问题描述
我正在研究需要检测不同类型文档轮廓的项目。
目前我能够使用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屋!