簡體   English   中英

OpenCV中是否有任何函數來查找兩個cv :: Rect的交集,並集和補碼

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

OpenCV中是否有任何函數可以找到兩個cv::Rect的交集,並集和補碼?

我可以自己編寫它們,但我希望OpenCV中有一些快速功能可以做到這一點。

搜索文檔,沒有任何功能。

編輯1

正如一些人所解釋的,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掩碼( mask1mask2必須具有相同的大小):

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文檔中提取了以下內容:

除類成員外,還對矩形執行以下操作:

  • rect + =點,rect-=點,rect + =大小,rect-=大小(擴展操作)
  • rect = rect1和rect2 (矩形交集)
  • rect = rect1 | rect2 (包含rect2和rect3的最小面積矩形)
  • rect&= rect1,rect | = rect1(以及相應的擴充操作)rect == rect1,rect!= rect1(矩形比較)

為了定義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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM