Anyone knows how to use getConvexHull();?

#1

I am using the OpenCV library, the example called “FindContours”.

I tried to obtain a new contour based on the ConvexHull function, but I get the same thing.

So I tried:

for (Contour contour : contours) {
    stroke(0, 255, 0);
    contour.getConvexHull();
    contour.draw();
    
    stroke(255, 0, 0);
    beginShape();
    for (PVector point : contour.getPoints()) {
     //contour.setPolygonApproximationFactor(3);
     //vertex(point.x, point.y);
    }
    endShape();
  }

Anyone knows why my contour is the same, with or without contour.getConvexHull(); line?

Here is a pic I prepared for testing

1 Like
#2

Hi! If you look at the source code


it seems like the method returns a new contour but you are not using it (not even storing it in a variable).

#3

Thanks for your help.
I was able to get a new contour. It has a different number of points than the original.
However , the area of the new contour is identical with the area of the original contour.
I wonder why. Can you help?
void ConvexHull()
{ contours2 = opencv.findContours(true,true); // Passing ‘true’ sorts them by descending area.

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

Contour contour = contours2.get(i);
println (i);
Rectangle r = contour.getBoundingBox();

if ((contour.area() > 0.9 * src.width * src.height) || (r.width < blobSizeThreshold || r.height < blobSizeThreshold))
  continue;

contour= contour.getConvexHull();
noFill();
strokeWeight(2);
// rect(r.x, r.y, r.width, r.height);

   stroke(255, 255, 0);
  contour.draw();
    float ConvexArea = contour.area();
  println ("ConvexArea =" + ConvexArea);

  int ContourPointsV1_Convex= contour.numPoints();
  println ("ConvexHull Points : "+ ContourPointsV1_Convex);

}
}
Here is the 2 contours.ConvexHull
type or paste code here

#4

Maybe if you mention what you need? :slight_smile:

#5

As you see above there are 2 contours. A regular one and the CovexHull.

When I extract the area of each of them I get the same number of pixels.
That is erroneous since the yellow bound contour is larger as you can see.

How do I get an accurate area for each?

My application requires that I compare the two areas.
What to do ? Thanks

#6

Hi, so if you again look at the source code of .area() to look at what it does, you see this:

There you can see that it only returns the size of the bounding box, and the bounding box is equal in both cases. If you want the precise area you could try the third approach shown here:

1 Like
#7

Thanks
I never realized I was getting the area of a bounding box.
I guess, I will have to fill my contours, do a saveFrame, bring the pic back to sketch and do a pixel count of the filled areas.
My areas are highly irregular, thanks for the polygon formula. It wont apply since I have curbed edges.

I wish there was a way to Snapshot my object right after the contour is drawn. Would make the sketch faster. Saving to hard drive and reloading seems cumbersome.
Thanks

#8

You don’t need to save and load an image, you can draw things to a PGraphics and then access the pixels from there. See createGraphics.

#9

I tried your method in the example “FindContours” from the OpenCV library.

after the PG definition in the setup, I tried:

  for (Contour contour : contours) {
    
    
    stroke(0, 255, 0);
    
    pg.beginDraw();
    pg.background(100);
    contour.draw();
    pg.endDraw();
    image(pg, 9, 30); 
  image(pg, 51, 30);
    
    stroke(255, 0, 0);
    beginShape();
    for (PVector point : contour.getPolygonApproximation().getPoints()) {
      vertex(point.x, point.y);
    }
    endShape();
  }

I was only able to get a gray square, but there was no contours in it.
I tried the pg.contour.draw(); hoping to make it work but it would not compile.
Is there a way to do this ?

Thanks a lot.
Mitch

#10

Maybe something in this direction?

pg.beginDraw();
pg.background(100);
pg.noStroke();
pg.fill(255);
for (Contour contour : contours) {
  pg.beginShape();
  for (PVector point : contour.getPolygonApproximation().getPoints()) {
    pg.vertex(point.x, point.y);
  }
  pg.endShape();
}
pg.endDraw();
2 Likes
#11

Thanks a lot, that worked,

If others need this, I ended up with:

void draw() {
  scale(0.5);
  image(src, 0, 0);
  image(dst, src.width, 0);

  noFill();
  strokeWeight(3);
  
  pg.beginDraw();
 //pg.background(0);
//pg.noStroke();
  pg.stroke(255, 0, 0);
  pg.strokeWeight (3);
  pg.noFill();
  pg.fill(255);
  
  for (Contour contour : contours) {
   pg.beginShape();
    stroke(255, 255, 0);
    contour.draw();
    
     pg.beginShape();
    for (PVector point : contour.getPolygonApproximation().getPoints()) {
      pg.vertex(point.x, point.y);
    }
     pg.endShape();
  }
  

    pg.endDraw();
       image(pg, 700, 0); 
   
}
 
and here is the image I was able to generate:![PNG|518x346](upload://xy9oMpVdGB2Xn5G2gBpZpVivHhR.jpeg) 

You are from Berlin? I have been there , Viellen Daken

This helps a lot with my project/
I also wonder if there is a way to capture the graphics for the
" contour.draw();" that does not relay on vertexes.

Thanks

1 Like