分段边缘

时间:2017-03-18 20:42:01

标签: opencv image-processing computer-vision

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

或者这个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);
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;
}

使用上面的代码可以得到以下结果:

Result Image

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

我已尝试了here

所述的所有解决方案/建议

因此,这是我的问题:

1)我的代码出了什么问题?

2)我如何预处理图像以检测完美边缘(没有孔的边缘)/完全笔直的轮廓检测?

非常感谢您的协助。

1 个答案:

答案 0 :(得分:1)

当您发现边缘不易被检测到时,您可以尝试其他补充方法。 例如,在此图像上,使用简单的matlab代码(可以使用OpenCV实现):

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

生成以下结果,您可以使用边缘检测代码来使用该结果:

Output image