I have a function that draws a polygon around some primary features in images by making use of OpenCV's contour detection. I simplify these contours using the approxPolyDP function in the snippet below to return a closed trapezoid around the regions, and it works fine:
top_poly = cv.approxPolyDP(top_cnt, 0.05 * top_perimeter, closed=True)
top_poly = np.squeeze(top_poly) # get rid of the singleton dimension
However, the approxPolyDP returns a strange type of ndarray which has a shape of N x 1 x 2, when the expected output according to the documentation linked below is an array of N x 2D points (N x 2). I had to debug for a while until I found that singleton dimension in there can be carved out using np.squeeze in the second line of the snippet. Thanks to this answer: What does cv2.approxPolydp() return?
My question is, what is the purpose of this singleton dimension? I worry I might be dropping some useful information and I don't enjoy having to use np.squeeze() in a way I don't completely understand. Thanks for any input that can shed some light on this.
https://docs.opencv.org/4.5.4/d3/dc0/group__imgproc__shape.html#ga0012a5fdaea70b8a9970165d98722b4c
CodePudding user response:
The result shape happens because of OpenCV's requirements, i.e. it has to map numpy arrays to cv::Mat
and back.
A cv::Mat
is a 2D thing with channels, which can be color (RGB or whatever), 2D points, 3D points, 4D, ..., or any other purpose.
The shape is generally (height, width, channels)
.
OpenCV returns the points as a column vector (Nx1) of 2-channel data, hence (N, 1, 2)
.
OpenCV is somewhat tolerant of different shapes like (N, 2, 1)
which is (N, 2)
(N rows, 2 columns, single-channel).