How to get well-defined edges regardless of the co

2019-02-25 00:02发布

I am trying to develop an App that detects cards "master cards, visa, cutomer cards, etc" using Android Camera, for that purpose i used OpenCV4Android version 3.0.0. To achieve this task, i did the following:

1- converted the frame taken from the camera to gray scale using

Imgproc.cvtColor(this.mMatInputFrame, this.mMatGray, Imgproc.COLOR_BGR2GRAY);

2- blurring the frame using

Imgproc.blur(this.mMatGray, this.mMatEdges, new Size(7, 7));

3- apply Canny edge detector as follows

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

4- to show Canny's result on the real image, i did the following

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);

5- dialated the image using

dilated = new Mat();
Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_DILATE, new Size(3, 3));
Imgproc.dilate(mMatEdges, dilated, dilateElement);

6- finding the contour of the card detected as follows:

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));
            }
    }
}

When I run the App,

Case 1

if the card to be detected is of a homogenous color "the entire card is painted with the same color", Canny produces well defined edges which can easily detected as shown in the image "same-color-0" and "same-color-1". moreover, when i place the card that of a homogenous color on a table and move the camera around it, the edges are getting detected properly despite i am moving the camera. or in other words, the red frame that surrounds the edges of the card is always fixed around the edges and never disappears

case 2

if the card is not of a homogenous color "of a mixed colors", then the edge detection is bad as shown in image "mixed-color-0" and "mixed-color-1", and moreover, the red frame that surrounds the edges of the card disappears so often. Another case extended from this case is, when the card is of two colors, one is light and one is dark, in this case, the edge detector detects only the dark part in the card because its edges are well defined as shown in image "mixed-color-2"

Please let me know how to get well defined and card-sized edges of the cards regardless of the color? is there any other more accurate way for edge detection?

same-color-0:

enter image description here

same-color-1

enter image description here

mixed-color-0

enter image description here

mixed-color-1

enter image description here

mixed-color-2

enter image description here

original images:

enter image description here

enter image description here

enter image description here

1条回答
冷血范
2楼-- · 2019-02-25 00:11

You can use Structured Edge Detection.

I got these results running the C++ code in this my other answer. This seems like a good and robust result to me.

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

To use this in Java, you should know that Structured Edge Detection is in contrib module ximgproc. You probably need to recompile OpenCV to use it: Build OpenCV with contrib modules and Java wrapper

查看更多
登录 后发表回答