Eigen::ArrayXXd windows(D * H * W * anchors.size(), 6); //Eigen::MatrixXd windows(D * H * W * anchors.size(), 6); int index = 0; Eigen::VectorXd oz(D), oh(H), ow(W); for (int z = 0; z < D; ++z) { oz[z] = offset + z * stride; } for (int y = 0; y < H; ++y) { oh[y] = offset + y * stride; } for (int x = 0; x < W; ++x) { ow[x] = offset + x * stride; } // 计算 anchor box 的坐标 for (int z = 0; z < D; ++z) { for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { for (int a = 0; a < anchors.size(); ++a) { windows.row(index) << oz[z], oh[y], ow[x], anchors[a][0], anchors[a][1], anchors[a][2]; ++index; } } } } return windows;用eigen内部的方法重新写一下,减低循环复杂度
时间: 2024-03-06 07:51:32 浏览: 128
可以使用 Eigen::Tensor 代替循环实现计算所有 anchor boxes 的位置和大小。具体实现如下:
```
Eigen::Tensor<double, 2> oz = (Eigen::Tensor<double, 1>(D) * stride + offset).reshape(D, 1);
Eigen::Tensor<double, 2> oh = (Eigen::Tensor<double, 1>(H) * stride + offset).reshape(1, H);
Eigen::Tensor<double, 2> ow = (Eigen::Tensor<double, 1>(W) * stride + offset).reshape(1, 1, W);
Eigen::Tensor<double, 3> anchors_tensor(1, anchors.size(), 3);
for (int a = 0; a < anchors.size(); ++a) {
anchors_tensor(0, a, 0) = anchors[a][0];
anchors_tensor(0, a, 1) = anchors[a][1];
anchors_tensor(0, a, 2) = anchors[a][2];
}
Eigen::Tensor<double, 3> oz_tensor = oz.broadcast(Eigen::array<Eigen::Index, 3>({ 1, H, W }));
Eigen::Tensor<double, 3> oh_tensor = oh.broadcast(Eigen::array<Eigen::Index, 3>({ D, 1, W }));
Eigen::Tensor<double, 3> ow_tensor = ow.broadcast(Eigen::array<Eigen::Index, 3>({ D, H, 1 }));
Eigen::Tensor<double, 4> windows_tensor = Eigen::Tensor<double, 4>(D, H, W, anchors.size(), 6);
windows_tensor.chip(0, 3) = oz_tensor.reshape(D, H, W, 1).broadcast(Eigen::array<Eigen::Index, 4>({ 1, 1, 1, anchors.size() }));
windows_tensor.chip(1, 3) = oh_tensor.reshape(D, H, W, 1).broadcast(Eigen::array<Eigen::Index, 4>({ 1, 1, 1, anchors.size() }));
windows_tensor.chip(2, 3) = ow_tensor.reshape(D, H, W, 1).broadcast(Eigen::array<Eigen::Index, 4>({ 1, 1, 1, anchors.size() }));
windows_tensor.chip(3, 3) = anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 }));
windows_tensor.chip(4, 3) = anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 })).chip(0, 2) * anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 })).chip(0, 2) / anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 })).chip(0, 1);
windows_tensor.chip(5, 3).setConstant(0.5);
Eigen::ArrayXXd windows = windows_tensor.reshape(D * H * W * anchors.size(), 6).shuffle(Eigen::array<int, 2>({ 1, 0 })).matrix();
```
这段代码首先使用 Eigen::Tensor 构造 oz、oh 和 ow 三个张量,分别表示 D、H 和 W 个方向上 anchor boxes 的中心坐标。然后,代码使用 anchors 数组构造一个张量 anchors_tensor,用于表示所有 anchor boxes 的宽高和宽高比。
接下来,代码使用 broadcast() 方法将 oz、oh 和 ow 三个张量分别扩展到与 anchors_tensor 相同的维度。然后,代码使用 chip() 方法将扩展后的张量拼接成一个四维张量 windows_tensor,其中第四维有 6 个元素,分别表示中心坐标和宽高比。最后,代码使用 reshape() 和 shuffle() 方法将 windows_tensor 转换成一个二维矩阵 windows,并返回该矩阵。
相比于原来的循环实现,使用 Eigen::Tensor 的实现方式可以减少循环嵌套的层数,提高计算效率。
阅读全文