Reputation: 4432
I need to find the min area rect ( cv2.minAreaRect() ) for a cloud of white pixels.
I have multiple white object in my image and I want to draw a rect around them.
i found the solution in c++:
cv::cvtColor(img, gray, CV_BGR2GRAY);
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = gray.begin<uchar>();
cv::Mat_<uchar>::iterator end = gray.end<uchar>();
for (; it != end; ++it)
{
if (*it) points.push_back(it.pos());
}
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
this is my try in python:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5 ,5), 0)
retval, thresh = cv2.threshold(gray, 210, 255, cv2.THRESH_BINARY)
whitep = []
for y, row in enumerate(thresh):
for x, px in enumerate(row):
if px == 255:
whitep.append((y, x))
box = cv2.minAreaRect(whitep)
but it doesn't works:
box = cv2.minAreaRect(whitep)
TypeError: <unknown> is not a numpy array
how can I do? Thanks
Upvotes: 1
Views: 6575
Reputation: 444
You can also try this. The minAreaRect did fail for some cases, but the method stated below always did work. Uses PIL though.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5 ,5), 0)
retval,thresh = cv2.threshold(gray, 210, 255, cv2.THRESH_BINARY)
mask=Image.fromarray(thresh)
box = mask.getbbox()
Upvotes: 1
Reputation: 114976
The python documentation for minAreaRect
is misleading.
Use:
box = cv2.minAreaRect(numpy.array([whitep], dtype=numpy.int32))
This passes an array of shape (1,N,2) to minAreaRect.
You'll need to specify the dtype if you are using a system where the default integer type is numpy.int64. It is safest to be explicit.
See also: Checking contour area in opencv using python
Upvotes: 4