Ask Your Question

# Fill an image with the content of RotatedRect

I have:

   Mat myImage;
RotatedRect(myCenter,mySize,myAngle);


I would like to fill with black the rotated rectangle inside myImage.

Any fast/elegant way to do it?
Note: I would avoid to rotate the image just to fill that rotatedRect

edit retag close merge delete

## 3 answers

Sort by » oldest newest most voted

You can take the rotated rectangle's edges and use fillConvexPoly()

more

## Comments

Thanks to Ben for the nice answer! So you should only compute fillConvexPoly(myImage, rRect.points(vertices), 4, Scalar(0));

fillConvexPoly() seems like the right solution. Here is the version I wrote based on Ben's answer:

 // default color is white
inline void drawRotatedRect(cv::Mat& image, cv::RotatedRect rRect, cv::Scalar color = cv::Scalar(255.0, 255.0, 255.0) ) {

cv::Point2f vertices2f;
cv::Point vertices;
rRect.points(vertices2f);
for(int i = 0; i < 4; ++i){
vertices[i] = vertices2f[i];
}
cv::fillConvexPoly(image,
vertices,
4,
color);
}

// default color is white
inline void drawRectangle(cv::Mat& image, cv::Point center, cv::Size rectSizePixels, double rotDeg, cv::Scalar color = cv::Scalar(255.0, 255.0, 255.0) ) {

cv::RotatedRect rRect(center, rectSizePixels, rotDeg); // opencv expects degrees
drawRotatedRect(image,rRect);

}

more Here is an answer to this: The idea is to check whether every pixel is in the region respect to rectangle edges:

for(int i=0; i<myImage.rows; ++i)
{
for(int j=0; j<myImage.cols; ++j)
{
if(isInRotatedRect( Point(j,i), rotated_rect))
{
myImage.at<uchar>(i,j) = 0;
}
}
}


for computing isInRotatedRect:

bool isInRotatedRect(Point p, RotatedRect rRect)
{
double line_pro;
Point2f vertices;
rRect.points(vertices);
for(int i=0; i<4; ++i)
{
line_pro[i] = computeProduct(p, vertices[i], vertices[(i+1)%4]);
}
if(line_pro*line_pro<0 && line_pro*line_pro<0)
{
return true;
}
return false;
}

//finding whether  point p is at the left or right side of rectangle edge ab.
double computeProduct(Point p, Point2f a, Point2f b)
{
double m = (a.y-b.y) / (a.x-b.x);
double c = a.y - k * a.x;
return m * p.x - p.y + c;
}


A better and more intuitive way would be rather than doing this for every image make a zero one mask and the cross product original image! This may be more efficient specially in video.

more

## Comments

-1. This is a naive brute-force solution unable to generalize (i.e. different line widths and styles) and simply too complicated and therefore slow.

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2013-06-07 01:22:42 -0500

Seen: 9,111 times

Last updated: Oct 07 '13