我在图像中生成了很多边界框。如何合并图像中的重叠边界框?
例如,
_________________ ________________________
| | | |
| —————————|———— | |
| | | | | |
———————|—————————— | ——> | |
| | | |
| ————————|—————— | |
—————|———————— | | |
| | | |
| | | |
———————————————— ________________________
我知道使用rectangle 1 | rectangle 2
生成一个新矩形。
它可以通过以下方法检测并合并它们(来自Efficient way to combine intersecting bounding rectangles)
if((rect1 & rect2) == rect1) ... // rect1 is completely inside rect2; do nothing.
else if((rect1 & rect2).area() > 0) // they intersect; merge them.
newrect = rect1 | rect2;
... // remove rect1 and rect2 from list and insert newrect.
但我指的是当三个或四个矩形重叠时如何判断哪个矩形重叠。我虽然可以使用重叠区域来判断它们是否重叠。
这还有什么有效的方法吗? 非常感谢你。
答案 0 :(得分:0)
这是一个快速伪代码
答案 1 :(得分:0)
此功能获取图像的轮廓并返回所需的合并框:
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;
}
编辑: 你可以忽略关于生成边界框的第一部分,因为你已经有了它们。
答案 2 :(得分:-1)
按区域对边界框进行排序:最大的框是更可能重叠的框。
如果不这样做,你可以通过对所有矩形进行联合来绘制所有矩形的“效率不高”。 您可能希望标记重叠框图像以仅选择重叠的图像并丢弃其余图像。
通过使用一种z缓冲区来存储每个像素上绘制的矩形,在这个想法下可能会有一些技巧?
答案 3 :(得分:-1)
这是我用于你的问题的代码,你也可以用它来享受:
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