Ask Your Question

How to remove background of a selected contour

asked 2017-11-28 10:30:25 -0500

fi8er1 gravatar image

updated 2020-10-21 05:57:35 -0500

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    Mat srcMat = inputFrame.rgba();
    Mat processedMat = new Mat();
    Imgproc.cvtColor(srcMat, processedMat, Imgproc.COLOR_BGR2GRAY);
    Imgproc.GaussianBlur(processedMat, processedMat, new Size(3, 3), 0);
    Imgproc.threshold(processedMat, processedMat, 127, 255, Imgproc.THRESH_BINARY);
    List<MatOfPoint> contours = new ArrayList<>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(processedMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    Log.e(TAG, "ContourSize: " + contours.size());
    double maxVal = 0;
    int maxValIdx = 0;
    for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
        double contourArea = Imgproc.contourArea(contours.get(contourIdx));
        if (maxVal < contourArea) {
            maxVal = contourArea;
            maxValIdx = contourIdx;
    Imgproc.drawContours(srcMat, contours, maxValIdx, new Scalar(0,255,0),  -2);
    if (!contours.isEmpty()) {
        Log.e("largestContour", "" + contours.get(maxValIdx));
        Rect rect = Imgproc.boundingRect(contours.get(maxValIdx));
        return srcMat; }

Input Image:


image description

As you can see I have applied .submat but I'm not sure why is it masking the inners of the contour instead of the outer surface. Moreover, filtering the largest contour is also not consistent. Any ideas on how can I make it more robust based on the dimensions of the ticket as my aim is to scan tickets with very same dimensions.

As a newbie OpenCV enthusiast, I want someone to guide me with my final mission here, which is to get the year, month, date, and time from the calender in the ticket and show it in text form. The ticket will have punched holes as markings. So, what I have in mind is to track each (hole) blob and extract it along with it's surrounding digits to know which number it was based on its surrounding, and do this to all of the blobs (holes) with some hierarchy in place to know if the extraction was from the 'year' field or month or day field respectively. Or is there any other better approach for this?

edit retag flag offensive close merge delete


Sample Token Scanned:

fi8er1 gravatar imagefi8er1 ( 2017-11-28 10:32:13 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2017-11-28 12:41:26 -0500

The code is doing exactly what you asked it to, drawContours is drawing the green blob over the countour's area.

What you probably want to do instead of drawing the filled contour into srcMat, is to draw it on a mask matrix, then apply the mask matrix to srcMat to 'zero' all the cells outside the contour area.

  1. Create maskMat, the same dimensions as srcMat of CV8U.
  2. Fill maskMat with zeros.
  3. Use drawContours to draw a value of 1 into maskMat in the filled shape of the contour.
  4. do a pixel by pixel logical AND of srcMat with maskMat (in C++ it's srcMat = srcMat & maskMat).

This will zero the srcMat pixels which are outside the contour.

edit flag offensive delete link more



I'm having trouble finding tutorials or examples in java for my use and can't get my around python example either. Is there some sort of a dimension filter which I can apply to my token contour to make it more consistent, right now it shifts places and draws uneven and incomplete contours as well, even though I'm drawing the largest contour as you can see in my code, can you help me with masking to making the rest of the image blur or something to make the token pop out of the background. And I'm having hard time in applying the perspective transformation to crop the token out of the image for further processing....

fi8er1 gravatar imagefi8er1 ( 2017-11-29 03:27:11 -0500 )edit

Thanks for marking this the right answer.

I made a rather general answer. I admit I don't have a Java developer setup (and my capability with Java is limited) If you came up with actual Java code that implemented this that worked, it would improve the answer to add it here. :) If anyone with more Java skill than me wants to chime in here, that's appreciated.

You briefly list several more follow-on questions. Distinguishing subject from background and knowing what tools to use to do that is part of computer vision technique that I'm new to too. If you can make good complete questions then they could stand on their own on this forum.

opalmirror gravatar imageopalmirror ( 2017-12-01 12:05:10 -0500 )edit

Question Tools

1 follower


Asked: 2017-11-28 10:30:25 -0500

Seen: 2,392 times

Last updated: Nov 28 '17