frx08
frx08

Reputation: 4432

find the bounding box of a white pixels set in opencv (python)

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

Answers (2)

Akhil prasannan
Akhil prasannan

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

Warren Weckesser
Warren Weckesser

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

Related Questions