0

It is really well documented how to draw a polygon using opencv:

import numpy as np
import cv2 as cv

img = np.zeros((125, 240, 3), dtype = "uint8")
poly = np.array([[[20,15],[210,30],[220,100],[20,100]]], np.int32)
cv.polylines(img, [poly], True, (0,0,255), 1)

cv.imshow('Shapes', img)
cv.waitKey(0)
cv.destroyAllWindows()

enter image description here

My question is, how do I get the data of the polygon. I need a (n, 2) or (1, n, 2) sized array with all the pixels the red line "follows".

The best sollution I've got so far is filling the poly and getting the contour from that:

mask = np.zeros((125, 240), dtype = "uint8")
cv.fillPoly(mask, poly, 255)
contours, _ = cv.findContours(mask, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
contour = contours[0][:, 0, :]

# ->
# array([[20, 15],
#        [20, 16],
#        [20, 17],
#        ...,
#        [23, 15],
#        [22, 15],
#        [21, 15]], dtype=int32)

I wonder if I can't get this data from cv.polylines if OpenCV is already able to display the polygon?

Lukas Weber
  • 455
  • 6
  • 13
  • 2
    You already have the vertices of the polygon -- that was your given. Perhaps you should checkout Bresenham's algorithm to see how to generate a line from two endpoints. – Tim Roberts Nov 30 '22 at 20:01
  • 2
    "The function `cv::polylines` draws one or more polygonal curves." -- you get an image, that's it. Unless you take the C++ implementation of said function and rewrite it to do something else. | To get all the points along a line, in C++ you'd use LineIterator. IIRC it's not available in Python, but [here](https://stackoverflow.com/a/32857432/3962537) is an alternative. Run that on each segment of the polyline. – Dan Mašek Nov 30 '22 at 20:09
  • thanks for referencing Bresenham's, I didn't know of this one. Pobably opencv handles that [here](https://docs.opencv.org/4.x/dc/dd2/classcv_1_1LineIterator.html#ac83a4c574ce6a50a78a52d7eee10371b). But it would still need some extra steps to come from my input points to the desired output coordinates – Lukas Weber Nov 30 '22 at 20:10
  • there are no extra steps. it simply draws each line segment of each polygon... -- **why** do you need this data, what for? why do you think asking for this data is the best solution for your problem? – Christoph Rackwitz Nov 30 '22 at 22:19
  • Just get the coordinates of all non-zero pixels using np.argwhere() or np.where(). – fmw42 Nov 30 '22 at 22:33
  • @ChristophRackwitz I want to implement a feature on top of [largestinteriorrectangle](https://github.com/lukasalexanderweber/lir) that allows the user to pass any polygon as `[[20,15],[210,30],[220,100],[20,100]]` and get the lir in return. I want to use the speeded up `lir.lir(grid, contour)`, I can create the grid with `cv.fillPoly` and I wondered if I can get the contour simpler than with `cv.findContours`, since I think there would be less overhead. – Lukas Weber Dec 01 '22 at 06:14
  • if the solution requires drawing a raster image at all, you likely can't get much faster than that OpenCV gives you. it's already doing the least amount of effort in its drawing primitives. perhaps using the GPU to draw... or avoid drawing raster graphics entirely, work purely with the vector data (polygons). I have no idea what algorithms are required for inscribing rectangles into polygons. – Christoph Rackwitz Dec 01 '22 at 07:49

0 Answers0