Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 如何在大量的包围盒中检测相交和重叠的包围盒?_Image_Opencv_Image Processing - Fatal编程技术网

Image 如何在大量的包围盒中检测相交和重叠的包围盒?

Image 如何在大量的包围盒中检测相交和重叠的包围盒?,image,opencv,image-processing,Image,Opencv,Image Processing,我在图像中生成了很多边界框。如何在图像中合并重叠的边界框 比如说, _________________ ________________________ | | | | | —————————|———— | | | | | |

我在图像中生成了很多边界框。如何在图像中合并重叠的边界框

比如说,

_________________                   ________________________
|               |                   |                      |
|      —————————|————               |                      | 
|      |        |   |               |                      |
———————|——————————  |         ——>   |                      |  
       |            |               |                      |
       |    ————————|——————         |                      |
       —————|————————     |         |                      |
            |             |         |                      |
            |             |         |                      |
            ————————————————        ________________________
我知道使用
矩形1 |矩形2
生成一个新矩形

它可以通过以下方法检测并合并它们

但我的意思是,当三个或四个矩形重叠时,如何判断哪个矩形重叠。我想我可以使用重叠区域来判断它们是否重叠

这是其他有效的方法吗?
非常感谢。

这里有一些快速伪代码

  • 为图像大小的每个矩形生成二进制贴图
  • 添加这些二进制映射以创建新的单个合并映射。(您可能需要将它们的阈值降低到1和0)
  • 使用原始算法(用于获取前3个边界框的算法)为此生成新的边界框

  • 按区域对边界框进行排序:最大的框更有可能重叠

    如果做不到这一点,可以通过对所有矩形进行并集来绘制“效率不高”的所有矩形。 您可能希望为重叠框图像添加标签,以便仅选择重叠框并放弃其余框


    在这种想法下,可能需要使用一些技巧,使用一种z缓冲区来存储在每个像素上绘制的矩形?

    这是我用于解决我的问题的代码,您也可以使用它来解决您的问题

     function varargout = isBoxMerg(ReferenceBox,TestBox,isNewBox)
    
                X = ReferenceBox; Y = TestBox;
    
                X1 = X(1);Y1 = X(2);W1 = X(3);H1 = X(4);
                X2 = Y(1);Y2 = Y(2);W2 = Y(3);H2 = Y(4);
    
                if ((X1+W1)>=X2 && (Y2+H2)>=Y1 && (Y1+H1)>=Y2 && (X1+W1)>=X2 && (X2+W2)>=X1)
                    Intersection = true;
                else
                    Intersection = false;
                end
                if (~isNewBox)
                    varargout{1} = Intersection;
                elseif(isNewBox && Intersection)
                    varargout{1} = Intersection;
    
                    a = X1;b=X1+W1;c=Y1;d=Y1+H1;
                    p = X2;q=X2+W2;r=Y2;s=Y2+H2;
    
    
    
                    if a<p
                        newA = a;
                    else
                        newA = p;
                    end
                    if b>q
                        newB = b;
                    else
                        newB = q;
                    end
                    if c<r
                        newC = c;
                    else
                        newC = r;
                    end
                    if d>s
                        newD = d;
                    else
                        newD = s;
                    end
                    newCC = [newA,newC,abs(newA-newB),abs(newC-newD)];
                    varargout{2} = newCC;  
                end
    
    function varargout=isBoxMerg(参考框、测试框、isNewBox)
    X=参考框;Y=测试盒;
    X1=X(1);Y1=X(2);W1=X(3);H1=X(4);
    X2=Y(1);Y2=Y(2);W2=Y(3);H2=Y(4);
    如果((X1+W1)>=X2&&(Y2+H2)>=Y1&&(Y1+H1)>=Y2&&(X1+W1)>=X2&&(X2+W2)>=X1)
    交点=真;
    其他的
    交点=假;
    终止
    如果(~isNewBox)
    varargout{1}=交叉点;
    elseif(isNewBox和交叉口)
    varargout{1}=交叉点;
    a=X1;b=X1+W1;c=Y1;d=Y1+H1;
    p=X2;q=X2+W2;r=Y2;s=Y2+H2;
    如果a

    q newB=b; 其他的 newB=q; 终止 如果cs newD=d; 其他的 newD=s; 终止 newCC=[newA,newC,abs(newA-newB),abs(newC-newD)]; varargout{2}=newCC; 终止


    此函数获取图像轮廓并返回所需的合并框:

    ae::error_code authenticator::get_boxes(const std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Rect>& boxes){
            std::vector<cv::Rect> bounding_boxes;
            for (const auto& contour_item : contours){
                bounding_boxes.push_back(cv::boundingRect(contour_item));
            }
    
    
            auto rect_corners = [](const cv::Rect& rect)->std::vector<cv::Point>{
                return{ cv::Point(rect.x, rect.y),
                    cv::Point(rect.x + rect.width, rect.y),
                    cv::Point(rect.x + rect.width, rect.y + rect.height),
                    cv::Point(rect.x, rect.y + rect.height) };
            };
    
            auto check_shared_rects = [](const cv::Rect& rect_a, const cv::Rect& rect_b)->bool{
                return (rect_a & rect_b).area() > 0;
            };
    
    
            for (size_t rect_idx = 0; rect_idx < bounding_boxes.size() - 1; ++rect_idx){
                for (size_t other_rect_idx = rect_idx + 1; other_rect_idx < bounding_boxes.size(); ++other_rect_idx){
                    if (check_shared_rects(bounding_boxes[rect_idx], bounding_boxes[other_rect_idx])){
                        auto new_rect_points(rect_corners(bounding_boxes[rect_idx]));
                        auto temp_points(rect_corners(bounding_boxes[other_rect_idx]));
                        new_rect_points.insert(std::end(new_rect_points), std::begin(temp_points), std::end(temp_points));
                        bounding_boxes.push_back(cv::boundingRect(new_rect_points));
                        bounding_boxes.erase(std::begin(bounding_boxes) + other_rect_idx);
                        bounding_boxes.erase(std::begin(bounding_boxes) + rect_idx);
                        rect_idx = 0;
                        other_rect_idx = rect_idx;
                    }
                }
            }
            boxes = bounding_boxes;
            return ae::error_code::ae_error_free;
        }
    
    ae::error\u code authenticator::get\u box(const std::vector&contours,std::vector&box){
    std::向量边界盒;
    用于(常量自动和等高线项目:等高线){
    边界框。向后推(cv::boundingRect(轮廓项));
    }
    auto rect_corners=[](常量cv::rect&rect)->std::vector{
    返回{cv::Point(rect.x,rect.y),
    cv::点(矩形x+矩形宽度,矩形y),
    cv::点(矩形x+矩形宽度,矩形y+矩形高度),
    cv::Point(rect.x,rect.y+rect.height)};
    };
    自动检查\u共享\u rects=[](常量cv::Rect&Rect\u a,常量cv::Rect&Rect\u b)->bool{
    返回(矩形a和矩形b).area()>0;
    };
    对于(size_t rect_idx=0;rect_idx
    编辑:
    您可以忽略关于生成边界框的第一部分,因为您已经有了它们。

    您好,我使用您的方法。结果很好,我把所有的矩形都放进了一张图片中。之后,我使用了连通元件标记方法和联合查找算法。结果就是我想要得到的。但是还有一个小矩形不能去掉它里面的矩形。非常感谢你!很高兴听到它起作用了!我不确定你所说的“内部矩形”是什么意思,但也许你在添加两个边界框后没有将阈值还原为二进制?谢谢你的建议谢谢你的方法。我试试看。我还没有投你的票。多谢各位~
    ae::error_code authenticator::get_boxes(const std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Rect>& boxes){
            std::vector<cv::Rect> bounding_boxes;
            for (const auto& contour_item : contours){
                bounding_boxes.push_back(cv::boundingRect(contour_item));
            }
    
    
            auto rect_corners = [](const cv::Rect& rect)->std::vector<cv::Point>{
                return{ cv::Point(rect.x, rect.y),
                    cv::Point(rect.x + rect.width, rect.y),
                    cv::Point(rect.x + rect.width, rect.y + rect.height),
                    cv::Point(rect.x, rect.y + rect.height) };
            };
    
            auto check_shared_rects = [](const cv::Rect& rect_a, const cv::Rect& rect_b)->bool{
                return (rect_a & rect_b).area() > 0;
            };
    
    
            for (size_t rect_idx = 0; rect_idx < bounding_boxes.size() - 1; ++rect_idx){
                for (size_t other_rect_idx = rect_idx + 1; other_rect_idx < bounding_boxes.size(); ++other_rect_idx){
                    if (check_shared_rects(bounding_boxes[rect_idx], bounding_boxes[other_rect_idx])){
                        auto new_rect_points(rect_corners(bounding_boxes[rect_idx]));
                        auto temp_points(rect_corners(bounding_boxes[other_rect_idx]));
                        new_rect_points.insert(std::end(new_rect_points), std::begin(temp_points), std::end(temp_points));
                        bounding_boxes.push_back(cv::boundingRect(new_rect_points));
                        bounding_boxes.erase(std::begin(bounding_boxes) + other_rect_idx);
                        bounding_boxes.erase(std::begin(bounding_boxes) + rect_idx);
                        rect_idx = 0;
                        other_rect_idx = rect_idx;
                    }
                }
            }
            boxes = bounding_boxes;
            return ae::error_code::ae_error_free;
        }