# eliminate unwanted contours opencv

I am working on a program that extracts the stickers on the puzzle and then later on finds the RGB of them. Currently, I am at the point where I want to remove any contours that aren't "square" like. I was wondering how I could do this.

What I do is I load the image, gray it, blur it, canny edge detection, dilate it find contours and draw them.

Is there a way I can draw around the contours instead of filling them in? And remove contours that aren't roughly the same size around or have almost 90 degree angles?

public static void main(String[] args) {

//Gray
Mat gray = new Mat();
Imgproc.cvtColor(capturedFrame, gray, Imgproc.COLOR_BGR2GRAY);

//Blur
Mat blur = new Mat();
Imgproc.blur(gray, blur, new Size(3,3));
//Canny image
Mat canny = new Mat();
Imgproc.Canny(blur, canny, 20, 40, 3, true);

Imgcodecs.imwrite("test.png", canny);

//System.exit(0);
Mat kernel = Imgproc.getStructuringElement(1, new Size(3,3));
Mat dilated = new Mat();
Imgproc.dilate(canny,dilated, kernel);

List<MatOfPoint> contours = new ArrayList<>();
//find contours
Imgproc.findContours(dilated, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_NONE);
//draw contours

Imgproc.cvtColor(capturedFrame, capturedFrame, Imgproc.COLOR_BGR2RGB);
for(int i = 0; i < contours.size(); i++){
Imgproc.drawContours(capturedFrame, contours, i, new Scalar(0, 0, 255), -1);
}

Imgcodecs.imwrite("after.png", capturedFrame);

Imshow img = new Imshow("firstImg");

img.show(capturedFrame);

}


Here is the initial image:

Here is the image with the contours drawn:

edit retag close merge delete

Sort by » oldest newest most voted

I suggest using color thresholding (inRange() ) then get contours.

Now you want to filter unwanted contours right ?

1 -loop through all contours

2- calculate contour Area or Length

3- eliminate unwanted contours

for( int n = 0; n< contours.size(); n++ )
{
double Area = contourArea( contours[i],false);

if(condition)

contours.erase(contours[n]);
}


Hope it helps

more

Thanks this helps, however is there a way I could make it more "flexible" like looking if it has some sort of square shape, like the lengths of the sides are the same and or has almost 90 degrees in the contour? The reason I ask is because the image won't always be this one because it is a captured frame the cube could be captured closer or further away.

( 2017-08-10 10:11:35 -0500 )edit

There are many ways to approach this case but the easiest is calculating bounding rectangle :

check documentation : http://docs.opencv.org/trunk/da/d0c/t...

( 2017-08-10 10:39:13 -0500 )edit

Ziri's answer is valid, just want to add that there is a way to evaluate "squareness" of a blob,

Given a blob, you can calculate the Shape Factor

You can use cv::contourArea() to obtain A and cv::arcLength() to obtain p.

If I remember correctly, for circled blobs you are expected to get values very close to 1. For triangled blobs you are going to get low values around 0.3. For squared blobs you are expected to get values around 0.7-0.8. This will allow you to filter some unwanted blobs.

Hope this helps.

more

Thank you for the extra help :) So I tired doing something like this

    for(int i = 0; i < contours.size(); i++){

double area = Imgproc.contourArea( contours.get(i),false);
MatOfPoint2f contour2f = new MatOfPoint2f( contours.get(i).toArray());

double arch = Imgproc.arcLength(contour2f, true);

double squareness = 4 * Math.PI * area / Math.pow(arch,2);

System.out.println("Squareness: " + squareness);

if(squareness <= 0.7 && squareness >=  0.8){
contours.remove(i);
}

}

( 2017-08-10 13:04:29 -0500 )edit

That is not right, the denominator in the equation is the arch squared, not the square root.

Also, if you don't multiply the result by 100, squareness will be between 0 and 1, so that condition will never verify

But you should first verify the values you are getting for the blobs to create the threshold. The values I wrote in my answer are just indicative.

( 2017-08-10 13:51:32 -0500 )edit
1

Ah, just saw the edit, now its right :)

( 2017-08-10 13:52:02 -0500 )edit

Official site

GitHub

Wiki

Documentation