1

私はARMに取り組んでおり、画像のダウンサンプリングを最適化しようとしています.OpenCV cv::resizeを使用しました.1280 * 960から400 * 300までの速度は約3msです.OpenMPを使用して高速化しようとしています. 、しかし、forステートメントを並列に入れている間、画像は歪んでいます。プライベート変数とスレッド間の共有データに関連していることはわかっていますが、問題が見つかりません。

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 ;
        }
    }

}
4

2 に答える 2

2

temp[offset++] を temp[i*w2 + j] に置き換えてみませんか?

オフセットには複数の問題があります。1 つには、競合状態があります。さらに悪いことに、OpenMP は各スレッドに非常に異なる i 値と j 値を割り当てているため、メモリの隣接しない部分を読み取っています。それがあなたのイメージが歪んでいる理由です。

OpenMP 以外にも、コードを高速化する方法がいくつかあります。ARM はわかりませんが、Intel では SSE で大幅に高速化できます。さらに、固定浮動小数点を試すこともできます。双一次補間の両方でスピードアップが見られました。fastcpp.blogspot.no/2011/06/bilinear-pixel-interpolation-using-sse.html

于 2013-03-16T08:15:29.760 に答える
2

offsetあなたの問題は変数だと思います。多くのスレッドが同時に動作する可能性があるため、どのスレッドが最初にオフセットを更新するかはわかりません。これが、結果の画像が歪む理由です。

より良い戦略は、結果の画像ピクセルを反復することです。結果のピクセルごとに、ソース イメージのピクセルの座標を見つけ、補間を実行し、結果を書き込みます。このようにして、各スレッドが異なるピクセルと正しいピクセルで確実に動作するようにします。

于 2013-03-15T11:26:13.313 に答える