imby
imby

Reputation: 23

Enlarge and restrict a quadrilateral polygon in opencv 2.3 with C++

I can't find this answer anywhere, I hope somebody could help me.

I have an image (all black) with a white generic quadrilateral polygon inside it, and the correspondent 4 corners coordinates of such polygon.

I need to find the corners of a slightly enlarged quadrilateral and the same for a slightly reduced one (the shape must be the same, just a resize of the quadrilateral inside the image).

Is there a function which allows me to do that, or should I compute manually some geometry?

Thank you for your help.

Upvotes: 1

Views: 1943

Answers (3)

hollaus
hollaus

Reputation: 66

I agree with the answer of parapura rajkumar. I wanted to add that the solution of Jiri is not 100% correct because the vertex centroid of a quadrilateral is different to the area centroid of a quadrilateral, as it is written here. For the enlargement one would have to use the area centroid - or the much more elegant solution with the parallel lines mentioned by parapura rajkumar. I just want to add the following to this answer:

You can simply determine the outer points of the enlarged quadrilateral by computing the normal vectors of the vectors between the points of the original quadrilateral. Afterwards, normalize the normal vectors, multiply them with the offset and add them to the points of the original quadrilateral. Given these outer points you can now compute the intersection of the parallel lines with this formula.

Upvotes: -1

Jiri Kriz
Jiri Kriz

Reputation: 9292

Consider a vertex p of the polygon, with its predecessor p1 and successor p2.

enter image description here

The vectors between these points are

v1 = p1 - p
v2 = p2 - p

(The computation is componentwise for the x and y coordinates respectively). In the shrunk polygon the vertex p is moved to p' along the line which halves the angle a between the vectors v1 and v2. The vector w in this direction is

w = v1 + v2

and the unit vector v in this direction is

v = w / |w| = (w_x, w_y) / sqrt(w_x*w_x + w_y*w_y)

The new point p' is

p' = p + k * v ,  i.e. :
p_x' = p_x + k * v_x
p_y' = p_y + k * v_y

where k is the shifting distance (a scalar).

If the vertex p is convex (as in the figure), then k >= 0 means shrinking and k <= 0 means expanding. If the vertex p is concave, then k >= 0 means expanding and k <= 0 means shrinking.

Upvotes: 2

parapura rajkumar
parapura rajkumar

Reputation: 24403

What you want is polygon offset. If you want to use an existing library. Consider using Clipper

     void OffsetPolygons(const Polygons &in_polys, 
         Polygons &out_polys, 
         double delta, 
         JoinType jointype = jtSquare, double MiterLimit = 2.0);

This function offsets the 'polys' polygons parameter by the 'delta' amount. Positive delta values expand outer polygons and contract inner 'hole' polygons. Negative deltas do the reverse.

Although I must add for a simple geometry like a Quadrilateral it is easy to do it from scratch.

  • Identity all four infinite lines that form the Quadrilateral
  • Offset the lines parallel to themselves
  • Compute intersection of these new lines

Just be careful of corner cases. When you offset a quadrilateral which has one very small edge. It will become a triangle on offset.

Upvotes: 0

Related Questions