Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any function in OpenCV to find the intersection, union and complements of two cv::Rect

Tags:

c++

opencv

Is there any function in OpenCV to find the intersection, union and complements of two cv::Rect?

I can write them by myself, but I hope there are some fast function in OpenCV to do this.

Searching documentation, did not any function.

Edit 1

As some explained, there is no union and complements for rects, so I looked at the avaliable functions and I found that in my case, I can use

rect = rect1 | rect2 (minimum area rectangle containing rect1 and rect2 )

instead of union. For complement, I need a similar function that defines as:

 rect=rect1 || rect2 (maximum area rectangle containing rect1 but not rect2 )

this is shown in the following images:

enter image description hereenter image description here

rect1 is yellow, rect2 is red and result is blue.

What is the fastest way to write this function?

like image 231
mans Avatar asked Nov 29 '22 07:11

mans


1 Answers

From OpenCV doc:

In addition to the class members, the following operations on rectangles are implemented:

rect = rect +/- point (shifting a rectangle by a certain offset)
rect = rect +/- size (expanding or shrinking a rectangle by a certain amount)

rect += point, rect -= point, rect += size, rect -= size (augmenting operations)
rect = rect1 & rect2 (rectangle intersection)
rect = rect1 | rect2 (minimum area rectangle containing rect2 and rect3 )
rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
rect == rect1, rect != rect1 (rectangle comparison)

These only cover operators that always result in another rect, so complement isn't here. you would have to work with masks there...

Since you are asking for complement and union, I'm not sure if cv::Rect is the right thing to work with. Maybe masks are better suited to fulfill your needs.

for CV_8UC1 masks (mask1 and mask2 must have same size):

union = mask1+mask2
complement = 255-mask 
intersection = mask1.mul(mask2)

To create a mask from a cv::Rect you can do the following:

cv::Mat mask = cv::Mat(yourImage.size(), CV_8UC1, cv::Scalar(0)); // creates an empty mask of your image size
cv::rectangle(mask, yourRect, cv::Scalar(255), -1);

but keep in mind, that cv::Rect is much more efficient in both: memory consumption and computation speed.

So if you can reformulate your problem to only use rectangular ROIs (so no complement possible), I would really use it this way instead of using masks!

like image 76
Micka Avatar answered Dec 18 '22 07:12

Micka