简体   繁体   中英

How to verify if rect is inside cv::Mat in OpenCV?

Is there anything like cv::Mat::contains(cv::Rect) in Opencv?

Background: After detecting objects as contours and trying to access ROIs by using cv::boundingRect my application crashed. OK, that's because the bounding rects of the object close to image border may be not entirely within the image.

Now I skip the objects not entirely in image by this check:

if(
  cellRect.x>0 && 
  cellRect.y>0 && 
  cellRect.x + cellRect.width < m.cols && 
  cellRect.x + cellRect.width < m.rows) ...

where cellRect is the bounding rect of the object and m is the image. I hope there is a dedicated opencv function for this.

Simple way is to use the AND (ie & ) operator.

Assume you want to check if cv::Rect rect is inside cv::Mat mat :

bool is_inside = (rect & cv::Rect(0, 0, mat.cols, mat.rows)) == rect;

You can create rect "representing"(x,y = 0, width and height equal to image width and height) your image and check whether it contains bounding rects of your contours. To achieve that you need to use rect intersection - in OpenCV it's very simple, just use rect1 & rect2 . Hope that code makes it clear:

cv::Rect imgRect = cv::Rect(cv::Point(0,0), img.size());
cv::Rect objectBoundingRect = ....;
cv::Rect rectsIntersecion = imgRect & objectBoundingRect;
if (rectsIntersecion.area() == 0)
  //object is completely outside image
else if (rectsIntersecion.area() == objectBoundingRect.area()) 
  //whole object is inside image
else 
  //((double)rectsIntersecion.area())/((double)objectBoundingRect.area()) * 100.0 % of object is inside image

Here is a method to judge whether a rectangle contains an other rectangle. you can get the size info from cv::Mat first , and then use method below:

public bool rectContainsRect(Rectangle containerRect, Rectangle subRect)
{
    if( containerRect.Contains(new Point(subRect.Left, subRect.Top)) 
        && containerRect.Contains(new Point(subRect.Right, subRect.Top))
        && containerRect.Contains(new Point(subRect.Left, subRect.Bottom))
        && containerRect.Contains(new Point(subRect.Right, subRect.Bottom)))
    {
        return true;
    }
    return false;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM