[英]Is there any function in OpenCV to find the intersection, union and complements of two cv::Rect
OpenCV中是否有任何函數可以找到兩個cv::Rect
的交集,並集和補碼?
我可以自己編寫它們,但我希望OpenCV中有一些快速功能可以做到這一點。
搜索文檔,沒有任何功能。
正如一些人所解釋的,rects沒有並集和補碼,因此我查看了可用的函數,發現在我的情況下,我可以使用
rect = rect1 | rect2 (minimum area rectangle containing rect1 and rect2 )
而不是工會。 為了補充,我需要一個類似的函數定義為:
rect=rect1 || rect2 (maximum area rectangle containing rect1 but not rect2 )
如下圖所示:
rect1
為黃色, rect2
為紅色,結果為藍色。
編寫此功能最快的方法是什么?
從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)
這些僅涵蓋總是導致另一個rect的運算符,因此補碼不在此處。 您將不得不在那里使用口罩...
由於您要補充和結合,所以我不確定cv::Rect
是否適用。 也許口罩更適合滿足您的需求。
對於CV_8UC1
掩碼( mask1
和mask2
必須具有相同的大小):
union = mask1+mask2
complement = 255-mask
intersection = mask1.mul(mask2)
要從cv::Rect
創建遮罩,您可以執行以下操作:
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);
但請記住, cv::Rect
在內存消耗和計算速度上都效率更高。
因此,如果您可以將問題改寫為僅使用矩形ROI(因此不可能進行補充),那么我真的會以這種方式使用它而不是使用蒙版!
C ++方式(cv :: Rect),您可以輕松地說
interesect = r1 & r2;
請參考此鏈接 。 所有操作均在文檔中給出。
// In addition to the class members, the following operations
// on rectangles are implemented:
// (shifting a rectangle by a certain offset)
// (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)
好吧,我不確定這是否可以解決您的問題(我認為是),但是我從CV文檔中提取了以下內容:
除類成員外,還對矩形執行以下操作:
為了定義complement
,可以使用以下功能:
cv::Rect RectWithoutRect(cv::Rect r1, cv::Rect r2)
{
// 32 bit integer values:
int minVal = -2147483648;
int maxVal = 2147483647;
// rectangles that define the space left, right, top and bottom of r2
cv::Rect leftOf = cv::Rect(cv::Point(minVal, minVal), cv::Point(r2.x, maxVal)); // rect covering the whole area left of r2
cv::Rect topOf = cv::Rect(cv::Point(minVal, minVal), cv::Point(maxVal, r2.y)); // rect covering the whole area top of r2
cv::Rect rightOf = cv::Rect(cv::Point(r2.x+r2.width, minVal), cv::Point(maxVal, maxVal)); // rect covering the whole area left of r2
cv::Rect bottomOf= cv::Rect(cv::Point(minVal, r2.y+r2.height), cv::Point(maxVal,maxVal)); // rect covering the whole area top of r2
// intersect the spaces with r1 to find regions of r1 that lie left, right, top and bottom of r2
cv::Rect allExterior[4];
allExterior[0] = leftOf;
allExterior[1] = topOf;
allExterior[2] = rightOf;
allExterior[3] = bottomOf;
// now choose the biggest one
int biggestSize = 0;
cv::Rect biggestRect(0,0,0,0);
for(unsigned int i=0; i<4; ++i)
{
cv::Rect intersection = allExterior[i] & r1;
int size = intersection.width * intersection.height ;
if(size > biggestSize)
{
biggestSize = size;
biggestRect = intersection;
}
}
return biggestRect;
}
一個小的測試程序:
int main()
{
cv::Mat output = cv::Mat(512,512,CV_8UC3,cv::Scalar(255,255,255));
cv::Rect r1 = cv::Rect(128,128,256,256);
//cv::Rect r2 = cv::Rect(300,299, 128,128);
cv::Rect r2 = cv::Rect(150,140, 50,50);
cv::Rect intersection = r1 & r2;
cv::rectangle(output, r1, cv::Scalar(0,255,255),-1);
cv::rectangle(output, r2, cv::Scalar(0,0,255),-1);
//cv::rectangle(output, intersection, cv::Scalar(255,0,0),-1);
cv::Rect rWithoutR = RectWithoutRect(r1, r2);
cv::rectangle(output, rWithoutR, cv::Scalar(255,0,0),-1);
cv::imshow("output", output);
cv::waitKey(0);
return 0;
}
您可以輕松修改RectWithoutRect
函數以返回“所有最大矩形”的向量。
PS:函數返回后忘記檢查矩形的大小,以查找是否返回了合法的矩形。
為了提高性能,您可以在調用函數之前優化代碼和/或測試r1和r2是否完全相交。
以下是一些測試結果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.