在一个图像中,有两个嵌套的矩形,它们共享两条边,如何使用opencv识别这两个矩形

fslejnso  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(104)

抱歉,由于安全原因,无法上传原图。以下为示意图:
原始图像:

我的目标:

现状:

现在我使用findContours函数来完成目标,目前使用的代码是(使用Python 3和OpenCV):

edges = cv2.Canny(mask, 10, 150)
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(ima, [contour], -1, (0, 0, 255), 5)

我还使用了以下函数参数:

cv2.RETR_EXTERNAL,cv2.RETR_LIST,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE,cv2.CHAIN_APPROX_TC89_L1,cv2.CHAIN_APPROX_TC89_KCOS

事实原始图像:

lymnna71

lymnna711#

每个白色区域的边界框可以用来判断简单的矩形“嵌套”关系。
使用connectedComponentsWithStats,可以获得AABB(轴对齐边界框)。
(下面的代码是C++。

//Judge the rectangular nested relation
bool Is_A_Including_B( const cv::Rect &A, const cv::Rect &B, int Margin )
{
    int Left = A.x - Margin;
    int Right = Left + A.width + 2*Margin - 1;
    int Top = A.y - Margin;
    int Bottom = Top + A.height + 2*Margin - 1;
    
    auto B_br = B.br();
    return ( Left<=B.x  &&  B_br.x<=Right  &&  Top<=B.y  &&  B_br.y<=Bottom );
}

//main
int main()
{
    //Load Image and Binalize
    cv::Mat SrcImg = cv::imread( "Regs.png", cv::IMREAD_GRAYSCALE );
    if( SrcImg.empty() )return 0;

    cv::Mat BinImg;
    cv::threshold( SrcImg, BinImg, 128, 255, cv::THRESH_BINARY );

    //Find Bounding Boxes of white regions
    std::vector< cv::Rect > BBs;
    {
        cv::Mat Labels, Stats, Centroids;
        int N = cv::connectedComponentsWithStats( BinImg, Labels, Stats, Centroids );

        BBs.reserve( N-1 );
        for( int i=1; i<N; ++i )
        {
            BBs.emplace_back(
                Stats.at<int>( i, cv::CC_STAT_LEFT ),
                Stats.at<int>( i, cv::CC_STAT_TOP ),
                Stats.at<int>( i, cv::CC_STAT_WIDTH ),
                Stats.at<int>( i, cv::CC_STAT_HEIGHT )
            );
        }
    }

    //Find nested region
    std::vector< cv::Rect > Found;
    for( auto i=BBs.begin(); i!=BBs.end(); ++i )
    {
        for( auto j=BBs.begin(); j!=BBs.end(); ++j )
        {
            if( i == j )continue;
            if( Is_A_Including_B( *i, *j, 5 ) )
            {   Found.push_back( *j );  }
        }
    }

    //Visualize
    cv::Mat ShowImg;
    cv::cvtColor( BinImg, ShowImg, cv::COLOR_GRAY2BGR );
    ShowImg *= 0.5;
    for( const auto &Rect : Found )
    {
        cv::rectangle( ShowImg, Rect, cv::Scalar(0,0,255), 4 );
    }
    cv::imshow( "Result", ShowImg );
    cv::waitKey();
    return 0;
}

测试结果:

相关问题