无论颜色如何,如何获得定义良好的边

时间:2016-10-14 09:41:07

标签: android opencv3.0 edge-detection object-detection opencv4android

我正在尝试使用Android相机开发一款可以检测卡“主卡,签证,裁剪卡等”的应用程序,为此我使用的是OpenCV4Android 3.0.0版本。为了完成这项任务,我做了以下工作:

使用

将从相机拍摄的画面转换为灰度
Imgproc.cvtColor(this.mMatInputFrame, this.mMatGray, Imgproc.COLOR_BGR2GRAY);

2-使用

模糊框架
Imgproc.blur(this.mMatGray, this.mMatEdges, new Size(7, 7));

3-应用Canny边缘检测器如下

Imgproc.Canny(this.mMatEdges, this.mMatEdges, 2, 900, 7, true);

4-显示Canny在真实图像上的结果,我做了以下

this.mDest = new Mat(new Size(this.mMatInputFrame.width(), this.mMatInputFrame.height()), CvType.CV_8U, Scalar.all(0));
this.mMatInputFrame.copyTo(this.mDest, this.mMatEdges);

使用

对图像进行了透析
dilated = new Mat();
Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_DILATE, new Size(3, 3));
Imgproc.dilate(mMatEdges, dilated, dilateElement);

6-发现卡的轮廓如下:

ArrayList<MatOfPoint> contours = new ArrayList<>();
 hierachy = new Mat();
Imgproc.findContours(dilated, contours, hierachy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);

for (int i = 0; i < contours.size(); i++) {
    if (Imgproc.contourArea(contours.get(i), true) > 90000) {
        Rect rect = Imgproc.boundingRect(contours.get(i));

        if (rect.height > 60) {
            Imgproc.rectangle(mMatInputFrame, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 0, 0));
            }
    }
}

当我运行App时,

案例1

如果要检测的卡片具有均匀的颜色“整张卡片涂有相同的颜色”,Canny会生成边界清晰的边缘,可以很容易地检测出来,如图中“同色0”和“相同颜色”所示-color-1" 。 此外,当我将同色卡片放在桌子上并围绕它移动相机时,尽管我正在移动相机,但边缘也会被正确检测到。换句话说,围绕边缘的红框 卡片始终固定在边缘,永不消失

案例2

如果卡片不是“混合颜色”的同色,则边缘检测不好,如图像“混合颜色0”和“混合颜色-1”所示,此外,红色围绕卡片边缘的框架经常消失。 从这种情况延伸出来的另一种情况是,当卡片有两种颜色时,一种是浅色,一种是暗色,在这种情况下,边缘检测器只检测卡片中的暗部分,因为它的边缘很好地定义,如图所示 “混合色-2”

请告诉我如何获得卡片的明确定义和卡片大小的边缘,无论颜色如何? 还有其他更准确的边缘检测方法吗?

同色-0

enter image description here

同色-1

enter image description here

混色-0

enter image description here

混色-1

enter image description here

混色-2

enter image description here

原始图片

enter image description here

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

您可以使用Structured Edge Detection

我得到了这些结果在this my other answer中运行C ++代码。这对我来说似乎是一个很好的结果。

enter image description here enter image description here enter image description here

要在Java中使用它,您应该知道结构化边缘检测在contrib模块ximgproc中。 您可能需要重新编译OpenCV才能使用它:Build OpenCV with contrib modules and Java wrapper