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
hamoid
February 11, 2019, 2:07am
2
Hi! If you look at the source code
* @return
*/
public Contour getPolygonApproximation(){
MatOfPoint2f approx = new MatOfPoint2f();
Imgproc.approxPolyDP(new MatOfPoint2f(inputPoints), approx, polygonApproximationFactor, true);
return new Contour(parent, approx);
}
/**
* Calculate a convex hull from the current Contour.
* Returns a new Contour representing the convex hull.
*
* @return Contour
*/
public Contour getConvexHull(){
MatOfInt hull = new MatOfInt();
MatOfPoint points = new MatOfPoint(pointMat);
Imgproc.convexHull(points, hull);
Point[] hp = new Point[hull.height()];
it seems like the method returns a new contour but you are not using it (not even storing it in a variable).
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.
type or paste code here
hamoid
February 13, 2019, 4:37am
4
laptophead:
Can you help?
Maybe if you mention what you need?
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
hamoid
February 14, 2019, 7:01am
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
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
hamoid
February 15, 2019, 1:15am
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
.
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
hamoid
February 17, 2019, 7:40am
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
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