c++ - 使用 OpenMP 优化双线性插值

标签 c++ opencv parallel-processing openmp hpc

我在 ARM 上工作,我正在尝试优化图像的下采样,我使用了 OpenCV cv::resize 及其缓慢的 ~3ms 用于 1280*960 到 400*300,我正在尝试使用 OpenMP为了加速它,但是在放置平行语句时,图像被扭曲了。我知道这与线程之间的私有(private)变量和共享数据有关,但我找不到问题。

void  resizeBilinearGray(uint8_t *pixels, uint8_t *temp, int w, int h, int w2, int h2) {

    int A, B, C, D, x, y, index, gray ;
    float x_ratio = ((float)(w-1))/w2 ;
    float y_ratio = ((float)(h-1))/h2 ;
    float x_diff, y_diff;
    int offset = 0 ;


#pragma omp parallel for
    for (int i=0;i<h2;i++) {
        for (int j=0;j<w2;j++) {
            x = (int)(x_ratio * j) ;
            y = (int)(y_ratio * i) ;
            x_diff = (x_ratio * j) - x ;
            y_diff = (y_ratio * i) - y ;
            index = y*w+x ;

            // range is 0 to 255 thus bitwise AND with 0xff
            A = pixels[index] & 0xff ;
            B = pixels[index+1] & 0xff ;
            C = pixels[index+w] & 0xff ;
            D = pixels[index+w+1] & 0xff ;

            // Y = A(1-w)(1-h) + B(w)(1-h) + C(h)(1-w) + Dwh
            gray = (int)(
                        A*(1-x_diff)*(1-y_diff) +  B*(x_diff)*(1-y_diff) +
                        C*(y_diff)*(1-x_diff)   +  D*(x_diff*y_diff)
                        ) ;

            temp[offset++] = gray ;
        }
    }

}

最佳答案

为什么不尝试用 temp[i*w2 + j] 替换 temp[offset++]?

您的偏移量有多个问题。一方面,它有竞争条件。但更糟糕的是,OpenMP 为每个线程分配了非常不同的 i 和 j 值,因此它们正在读取内存的非相邻部分。这就是为什么您的图像失真的原因。

除了 OpenMP 之外,您还可以尝试其他几种加速代码的方法。我不知道 ARM,但在 Intel 上你可以通过 SSE 获得很大的加速。此外,您可以尝试固定 float 。我在双线性插值中发现了两者的加速。 fastcpp.blogspot.no/2011/06/bilinear-pixel-interpolation-using-sse.html

关于c++ - 使用 OpenMP 优化双线性插值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15430243/

相关文章:

c++ - 我想在文本框中显示值,而不单击按钮。只需更新值

c++ - std::thread 到 std::async 会带来巨大的性能提升。怎么可能?

python-3.x - 使用 cv2 加载 png 时出错 - 结果数组为空

Python 和 OpenCV - 改进我的车道检测算法

linux - GNU 并行运行的作业似乎不是并行的

c - 如何使用 Pthreads 并行化我的 n 皇后拼图?

c++ - 在返回 shared_ptr 的函数中返回新的东西

c++ - Winforms RichTextBox 作为 istream

c++ - 如何将两个 remap() 操作合并为一个?

r - 我可以嵌套 parallel:::parLapply() 吗?