c++ - 使用 SIMD 进行 HOG 优化

标签 c++ opencv simd dlib simd-library

有几种尝试使用 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/

相关文章:

opencv - 使轮廓适合圆

c++ - SSE 和 AVX 内在函数混合

c++ - std::string 析构函数中的访问冲突仅在调试中

c++ - QWidget继承的类如何创建线程?

c++ - 如果只将非虚拟、非重载的成员函数添加到类中,是否需要用户重新编译?

c++ - 在 C++ 中打印变量名的通用方法

python - OpenCV - 最佳图像识别算法

eclipse - 使用 eclipse 来查找 opencv native 库不起作用

c - 使用 SSE 以最快的速度实现自然指数函数

c++ - 两个 SSE2 打包 double 的最优无分支条件选择