有几种尝试使用 SIMD 指令优化 HOG 描述符的计算:OpenCV , Dlib , 和 Simd .它们都使用标量代码将结果幅度添加到 HOG 直方图中:
float histogram[height/8][width/8][18];
float ky[height], kx[width];
int idx[size];
float val[size];
for(size_t i = 0; i < size; ++i)
{
histogram[y/8][x/8][idx[i]] += val[i]*ky[y]*kx[x];
histogram[y/8][x/8 + 1][idx[i]] += val[i]*ky[y]*kx[x + 1];
histogram[y/8 + 1][x/8][idx[i]] += val[i]*ky[y + 1]*kx[x];
histogram[y/8 + 1][x/8 + 1][idx[i]] += val[i]*ky[y + 1]*kx[x + 1];
}
size
的值取决于实现,但通常含义是相同的。
我知道 histogram calculation with using of SIMD 的问题没有简单有效的解决方法。但在这种情况下,我们的直方图尺寸较小 (18)。它可以帮助优化 SIMD 吗?
最佳答案
我找到了解决方案。它是一个时间缓冲器。首先我们将直方图求和到临时缓冲区(这个操作可以向量化)。然后我们将缓冲区的总和添加到输出直方图(这个操作也可以向量化):
float histogram[height/8][width/8][18];
float ky[height], kx[width];
int idx[size];
float val[size];
float buf[18][4];
for(size_t i = 0; i < size; ++i)
{
buf[idx[i]][0] += val[i]*ky[y]*kx[x];
buf[idx[i]][1] += val[i]*ky[y]*kx[x + 1];
buf[idx[i]][2] += val[i]*ky[y + 1]*kx[x];
buf[idx[i]][3] += val[i]*ky[y + 1]*kx[x + 1];
}
for(size_t i = 0; i < 18; ++i)
{
histogram[y/8][x/8][i] += buf[i][0];
histogram[y/8][x/8 + 1][i] += buf[i][1];
histogram[y/8 + 1][x/8][i] += buf[i][2];
histogram[y/8 + 1][x/8 + 1][i] += buf[i][3];
}
关于c++ - 使用 SIMD 进行 HOG 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43316459/