以下是格式化后的代码,增加了可读性并修复了一些小错误:
```cpp
void nms_boxes(std::vector<cv::Rect2f> &boxes,
std::vector<float> &confidences,
float confThreshold,
float nmsThreshold,
std::vector<int> &indices) {
struct BBOX {
cv::Rect2f box;
float confidence;
int index;
};
std::vector<BBOX> bboxes;
int i, j;
// 转换 boxes 和 confidences 到 BBOX 格式
for (i = 0; i < boxes.size(); i++) {
BBOX bbox;
bbox.box = boxes[i];
bbox.confidence = confidences[i];
bbox.index = i;
bboxes.push_back(bbox);
}
// 根据置信度进行排序
std::sort(bboxes.begin(), bboxes.end(), [](const BBOX &a, const BBOX &b) {
return a.confidence > b.confidence;
});
int updated_size = bboxes.size();
for (i = 0; i < updated_size; i++) {
if (bboxes[i].confidence < confThreshold)
continue;
indices.push_back(bboxes[i].index);
for (j = i + 1; j < updated_size;) {
float iou = get_iou_value(bboxes[i].box, bboxes[j].box);
if (iou > nmsThreshold) {
bboxes.erase(bboxes.begin() + j);
updated_size--;
// 不需要 j--,因为 j 已经在正确的位置上
} else {
j++; // 仅当没有删除元素时才增加 j
}
}
}
}
```
### 代码解释:
1. **结构体定义**:定义了一个 `BBOX` 结构体来存储边界框、置信度和索引。
2. **转换和存储**:遍历输入的 `boxes` 和 `confidences`,将它们转换为 `BBOX` 结构体并存储到 `bboxes` 向量中。
3. **排序**:使用 `std::sort` 和自定义比较函数按置信度降序排序 `bboxes`。
4. **非极大值抑制(NMS)**:遍历排序后的 `bboxes`,应用置信度阈值过滤,然后对剩余的边界框执行NMS。如果两个边界框的交并比(IoU)大于阈值,则删除后者。
5. **索引存储**:将保留的边界框的索引添加到 `indices` 向量中。
6. **删除操作**:在NMS过程中,如果需要删除元素,使用 `erase` 从 `bboxes` 中删除元素,并更新 `updated_size`。
请注意,`get_iou_value` 函数需要你自行实现,它应该计算两个边界框之间的IoU值。此外,确保 `cv::Rect2f` 是正确处理的,如果 `Rect_f` 是自定义类型,需要替换为 `cv::Rect2f` 或相应的类型。