1

この投稿では、OpenCV を使用して画像を転置する方法について説明しましたが、ここでさらに詳しく説明します。画像がグレースケールの場合、C++ を使用して画像 (またはマトリックス) を転置する最速の方法は何ですか? 私の解決策は次のとおりです。

        // image data is stored in an image buffer image*buffer_

    unsigned char *mem = (unsigned char *) malloc(image.bufferSize_);

    int height = image.Height();
    int width = image.Width();
    for(int i=0; i<height; i++)
    {
        unsigned char *ptr =image.buffer_+i*width;
        for(int j=0; j<width; j++)
            *(mem+j*height+i) = *(ptr+j);
    }


    memcpy(image.buffer_,mem,image.bufferSize_);
    free(mem);

上記のコードに関するいくつかの説明: 基本的な画像情報と画像ピクセルを含む画像オブジェクトを作成します ( image.buffer_)。イメージ ピクセルが に格納されるimage.buffer_場合、イメージ ピクセルは行ごとに保持されると想定します。上記のコードをさらに改善するためのアイデアはありますか?

4

1 に答える 1

1

malloc/free 部分に触れずに、コピー部分は次のようになります。

    size_t len = image.bufferSize_,
           len1 = len - 1;

    unsigned char *src = image.buffer_,
                  *dest = mem,
                  *end = dest + len;

    for(size_t i = 0; i < len; i++)
    {
        *dest++ = *src;  // dest moves to next row
        src += height;   // src moves to next column

        // src wraps around and moves to next row
        if (src > end) src -= len1;
    }

これは、列方向の宛先反復子と行方向のソース反復子を持つことと同じです。

実際にテストしなくても、これはより高速になると思います。内側のループでオフセット計算に 3 つの操作があるのに対し、あなたのバージョンでは 4 つです (さらに、両方のバージョンで 2 つの逆参照操作があります)。

編集

もう1つの改善と修正:

    //...
    unsigned char *src = image.buffer_,
                  *src_end = src + len,
                  *dest = mem,
                  *dest_end = dest + len;

    while (dest != dest_end)
    {
        *dest++ = *src;  // dest moves to next row
        src += height;   // src moves to next column

        // src wraps around and moves to next row
        if (src > src_end) src -= len1;
    }

これにより、反復ごとに(ループ内で)もう1つの操作が節約i++されます。forまた、以前srcと間違って比較しましたend

于 2013-09-18T10:42:51.303 に答える