afinit
afinit

Reputation: 1055

Convert cv2.minAreaRect() output to contour for input to cv2.boundingRect()

I've already tried a number of approaches to create a boundingRect() around a minAreaRect(), but I keep running into an error. I could simply use the original contour yes, but at this point it's a matter of understanding why a contour that works with cv2.isContourConvex() and cv2.drawContours() won't work with cv2.boundingRect(). Basically I'm trying to better understand the construction of a contour.

Here's the code:

import cv2
import numpy as np

# EX1: draw contour from minAreaRect() output
mar = cv2.minAreaRect( contour )
pts = cv2.cv.BoxPoints( mar )
pts_contour = np.int0(pts)
cv2.drawContours(mask, [pts_contour], 0, 255, -1)

cv2.boundingRect( pts_contour )  # ERROR: see below

# EX2: test contour convex
contour = np.array([(378, 949), (375, 940), (368, 934), 
    (359, 932), (350, 937), (345, 955), (351, 962), (359, 966), (368, 964),
    (376, 958) ], dtype=np.int)
print cv2.isContourConvex(contour)

cv2.boundingRect( contour )  # ERROR: see below

EX1: Error from boundingRect(): OpenCV Error: Unsupported format or combination of formats (The image/matrix format is not supported by the function) in cvBoundingRect This example of converting to a contour was provided in the Rotated Rectangles section here

EX2: Error from boundingRect(): OpenCV Error: Assertion failed (points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S)) in boundingRect This example of creating a contour from scratch was provided here

Again I can accomplish my goals so I don't want suggestions on workarounds, but I would instead like to better understand the construct behind the contour and the error itself because I could see it being useful to create a boundingRect() from selected points

Also, I don't know if it matters but I've noticed that there is a difference between the output from BoxPoints() and findContours()[0]:

# BoxPoints:
[[1051 1367]
[ 968 1364]
[ 977 1072]
[1061 1074]]

# findCountours()[0]:
[[[ 992 1073]]
[[ 991 1074]]
[[ 989 1074]]
[[ 988 1073]]]

>>> cv2.__version__
'2.4.9'

cv2.boxPoints() is not available to me so I'm not sure if that would net me different results

Upvotes: 0

Views: 5606

Answers (2)

Nachiket
Nachiket

Reputation: 182

You have to write like this: (x,y,w,h)=cv2.boundingRect( pts_contour ) It returns a tuple when you use this function.

Upvotes: 0

Arnaud P
Arnaud P

Reputation: 12607

One detail in EX2 is explicit in opencv error message: it is expecting an array of dtype float32 or int32 : (points.depth() == CV_32F || points.depth() == CV_32S). (tested with numpy v19, which if I were to guess you're not using since I couldn't find int0)

As for EX1, I'm sorry I can't reproduce it with opencv 3.0.0-beta (the cv2.cv is gone). By the way may I suggest not spending too much time wondering about this part of the library : cv2.cv is a legacy feature.

Upvotes: 1

Related Questions