Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

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.

like image 217
Valentin H Avatar asked Mar 18 '15 10:03

Valentin H


People also ask

What is a CV :: mat?

In OpenCV the main matrix class is called Mat and is contained in the OpenCV-namespace cv. This matrix is not templated but nevertheless can contain different data types. These are indicated by a certain type-number. Additionally, OpenCV provides a templated class called Mat_, which is derived from Mat.

What is Vec3b?

Vec3b is the abbreviation for "vector with 3 byte entries" Here those byte entries are unsigned char values to represent values between 0 .. 255. Each byte typically represents the intensity of a single color channel, so on default, Vec3b is a single RGB (or better BGR) pixel.

What is CV_64FC1?

That is, image of type CV_64FC1 is simple grayscale image and has only 1 channel: image[i, j] = 0.5. while image of type CV_64FC3 is colored image with 3 channels: image[i, j] = (0.5, 0.3, 0.7) (in C++ you can check individual pixels as image.at<double>(i, j) ) CV_64F is the same as CV_64FC1 .

What is mat type in OpenCV?

The Mat class of OpenCV library is used to store the values of an image. It represents an n-dimensional array and is used to store image data of grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms, etc.


2 Answers

Simple way is to use the AND (i.e. &) 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;
like image 113
herohuyongtao Avatar answered Oct 12 '22 05:10

herohuyongtao


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
like image 38
cyriel Avatar answered Oct 12 '22 04:10

cyriel