无法使用OpenCV从摄影机确定文档边缘

无法使用OpenCV从摄影机确定文档边缘,opencv,Opencv,我需要找到用户手中的文档边缘 1来自照相机的原始图像: 2然后我将图像转换为BG: 3然后我做模糊: 3使用Canny查找图像中的边缘: 4、使用扩张器: 正如您在上一张图像上看到的,地图周围的轮廓被撕裂,轮廓未确定。我的错误是什么?如何解决问题以完全确定文档的大纲 这是我如何做到这一点的代码: final Mat mat = new Mat(); sourceMat.copyTo(mat); //convert the image to black and

我需要找到用户手中的文档边缘

1来自照相机的原始图像:

2然后我将图像转换为BG:

3然后我做模糊:

3使用Canny查找图像中的边缘:

4、使用扩张器:

正如您在上一张图像上看到的,地图周围的轮廓被撕裂,轮廓未确定。我的错误是什么?如何解决问题以完全确定文档的大纲

这是我如何做到这一点的代码:

final Mat mat = new Mat();
    sourceMat.copyTo(mat);

    //convert the image to black and white
    Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGR2GRAY);

    //blur to enhance edge detection
    Imgproc.GaussianBlur(mat, mat, new Size(5, 5), 0);
    if (isClicked) saveImageFromMat(mat, "blur", "blur");

    //convert the image to black and white does (8 bit)
    int thresh = 128;
    Imgproc.Canny(mat, mat, thresh, thresh * 2);

    //dilate helps to connect nearby line segments
    Imgproc.dilate(mat, mat,
            Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3)),
            new Point(-1, -1),
            2,
            1,
            new Scalar(1));

这个答案是基于我的上述评论。如果有人拿着文档,您将看不到用户手后的边缘。因此,任何检测文档轮廓的方法都必须对边缘的某些缺失部分具有鲁棒性

我建议使用Hough变换的变体来检测文档。关于Hough变换的说法听起来很吓人,就像维基百科经常对数学主题所做的那样,但不要气馁,事实上它们并不难理解或实现

原始Hough变换检测图像中的直线。如中所述,图像中的任何直线都可以由两个参数定义:角度θ和直线到原点的距离r。因此,您可以量化这两个参数,并为图像中可能出现的每一行创建一个二维数组,其中一个单元格。使用的量化越精细,所需的阵列就越大,但找到的线的位置就越精确。将数组初始化为零。然后,对于Canny检测到的作为边缘一部分的每个像素,确定该像素可能属于的每一行θ,r,并增加相应的bin。处理完所有像素后,对于每个箱子,您将有一个计数,即在与该箱子对应的行上检测到多少像素。足够高的计数可能代表图像中的真实线条,即使部分线条缺失。因此,您只需扫描垃圾箱,查找超过阈值的垃圾箱


OpenCV包含用于直线和圆的Hough检测器,但不用于矩形。您可以使用行检测器并检查构成文档边缘的4行;或者你也可以为矩形编写自己的Hough检测器,也许可以从纸上获得灵感。矩形至少有5个自由度2D位置、比例、纵横比和旋转角度,而5D阵列的内存需求显然增长非常快。但是,由于每个参数的范围是有限的,即文档的纵横比是已知的,您可以假设文档将居中且不会旋转太多,这可能是可行的。

使用自适应阈值而不是canny。与上边缘相比,下边缘离背景灰度太近。因此,如果有人拿着文档,您将看不到用户手后的边缘。因此,无论您打算对边执行什么操作,它都必须对边的某些缺失部分具有鲁棒性。与其试图让边缘的所有部分都可见,不如在只有部分边缘可见的情况下,花时间稳健地估计真正的边缘位置。@Chungzuwalla,但是怎么做呢?@MartinBeckett,你能解释得更详细一点吗?或者可能是一些代码示例。