帮我把以下函数翻译成C++ def py_nms(dets, thresh): """Pure Python NMS baseline.""" # x1、y1、x2、y2、以及score赋值 # (x1、y1)(x2、y2)为box的左上和右下角标 x1 = dets[:, 0] y1 = dets[:, 1] x2 = dets[:, 2] y2 = dets[:, 3] scores = dets[:, 4] # 每一个候选框的面积 areas = (x2 - x1 + 1) * (y2 - y1 + 1) # order是按照score降序排序的 order = scores.argsort()[::-1] # print("order:",order) keep = [] while order.size > 0: i = order[0] keep.append(i) # 计算当前概率最大矩形框与其他矩形框的相交框的坐标,会用到numpy的broadcast机制,得到的是向量 xx1 = np.maximum(x1[i], x1[order[1:]]) yy1 = np.maximum(y1[i], y1[order[1:]]) xx2 = np.minimum(x2[i], x2[order[1:]]) yy2 = np.minimum(y2[i], y2[order[1:]]) # 计算相交框的面积,注意矩形框不相交时w或h算出来会是负数,用0代替 w = np.maximum(0.0, xx2 - xx1 + 1) h = np.maximum(0.0, yy2 - yy1 + 1) inter = w * h # 计算重叠度IOU:重叠面积/(面积1+面积2-重叠面积) ovr = inter / (areas[i] + areas[order[1:]] - inter) # 找到重叠度不高于阈值的矩形框索引 inds = np.where(ovr <= thresh)[0] # print("inds:",inds) # 将order序列更新,由于前面得到的矩形框索引要比矩形框在原order序列中的索引小1,所以要把这个1加回来 order = order[inds + 1] return keep
时间: 2024-01-24 17:04:24 浏览: 27
以下是将该函数翻译为 C++ 的代码,需要注意的是,由于该函数使用了 numpy 库,因此需要先引入该库,并使用对应的函数来替换原函数中的 numpy 函数。
```c++
#include<iostream>
#include<vector>
#include<numeric> // for iota
#include<algorithm> // for sort
using namespace std;
vector<int> py_nms(vector<vector<float>> dets, float thresh) {
// 定义变量
vector<float> x1, y1, x2, y2, scores, areas;
for (auto det: dets) {
x1.push_back(det[0]);
y1.push_back(det[1]);
x2.push_back(det[2]);
y2.push_back(det[3]);
scores.push_back(det[4]);
areas.push_back((det[2] - det[0] + 1) * (det[3] - det[1] + 1));
}
// 对 scores 进行降序排序,返回的是排序后的下标
vector<int> order(scores.size());
iota(order.begin(), order.end(), 0);
sort(order.begin(), order.end(), [&](int i, int j) {return scores[i] > scores[j];});
vector<int> keep;
while (order.size() > 0) {
int i = order[0];
keep.push_back(i);
// 计算交集的坐标,使用 max 和 min 函数代替 np.maximum 和 np.minimum 函数
vector<float> xx1, yy1, xx2, yy2;
for (int j = 1; j < order.size(); j++) {
xx1.push_back(max(x1[i], x1[order[j]]));
yy1.push_back(max(y1[i], y1[order[j]]));
xx2.push_back(min(x2[i], x2[order[j]]));
yy2.push_back(min(y2[i], y2[order[j]]));
}
vector<float> w = vector<float>(xx1.size()), h = vector<float>(xx1.size());
transform(xx1.begin(), xx1.end(), xx2.begin(), w.begin(), [](float a, float b) {return max(float(0), b - a + 1);});
transform(yy1.begin(), yy1.end(), yy2.begin(), h.begin(), [](float a, float b) {return max(float(0), b - a + 1);});
vector<float> inter = vector<float>(w.size());
transform(w.begin(), w.end(), h.begin(), inter.begin(), multiplies<float>());
// 计算 IOU,使用 max 函数代替 np.maximum 函数
vector<float> ovr = vector<float>(inter.size());
for (int j = 0; j < inter.size(); j++) {
ovr[j] = inter[j] / (areas[i] + areas[order[j+1]] - inter[j]);
}
// 找到重叠度不高于阈值的矩形框索引
vector<int> inds;
for (int j = 0; j < ovr.size(); j++) {
if (ovr[j] <= thresh) {
inds.push_back(j);
}
}
// 更新 order 序列
vector<int> new_order(inds.size());
transform(inds.begin(), inds.end(), new_order.begin(), [&](int ind) {return order[ind+1];});
order = new_order;
}
return keep;
}
```
需要注意的是,该 C++ 代码中使用了 `transform` 函数来代替原函数中的 numpy 广播机制,`multiplies<float>()` 函数来代替 `*` 运算符。此外,为了方便排序,我们引入了 `<numeric>` 头文件中的 `iota` 函数,该函数用于生成一个序列(从 0 开始),并将其存储到一个 vector 中。