-2

現在、17 枚の画像 (24 ビット、1200 x 1600) を読んでいます。17 枚の画像を読み取るには、約 0.078 秒かかります。ただし、サイズが 5760000 のこのメモリ ブロックを白黒の画像サイズ 192000 に変換して、ラプラシアンの edge_detection を実行したいと考えています。現在、私は次の方法を使用しています。

images.resize(rows * cols);
images.reserve(rows * cols);

for(int z = 0; z < rows * cols; z ++){
    pix.blue = (int) *(pChar + z * 3);
    pix.green = (int) *(pChar + z * 3 + 1);
    pix.red = (int) *(pChar + z * 3 + 2);
    pix.black_white = pix.blue * .11 + pix.green * .59 + pix.red *.3;
    images.at(z).black_white = pix.blue * .11 + pix.green * .59 + pix.red *.3;
}

ただし、pChar メモリ ブロックを読み取り、1920000 のベクトル サイズに書き込むというこのプロセスでは、17 枚の画像を読み取るのに合計 2.262 秒かかります。これにアプローチできるより速い方法はありますか?

以下の別のコードを使用してみましたが、pChar2 は VS2010 のデバッグ モードで badptr があることを伝え続けます: (data_grey、pChar、pChar2 変数は unsigned char * です)

pChar = (unsigned char*) malloc (sizeof(char)*3*rows*cols);
pChar2 = (unsigned char*) malloc (sizeof(char) * rows * cols);
fread(pChar, sizeof(char), 3*rows*cols, bmpInput);
images.at(i).data = pChar;

for(int z = 0; z < rows * cols; z ++){
    pix.blue = (int) *(pChar + z * 3);
    pix.green = (int) *(pChar + z * 3 + 1);
    pix.red = (int) *(pChar + z * 3 + 2);
    pix.black_white = pix.blue * .11 + pix.green * .59 + pix.red *.3;
    pChar2 += (unsigned char) pix.black_white;
}
    images.at(i).data_grey = pChar2;

私の考えでは、pChar2 メモリ ブロックに間違った方法で書き込んでいる可能性があります。しかし、この2番目の方法ははるかに高速だったので、どうすれば修正できるのか疑問に思っていました. images.at(i).data_grey 用に白黒のメモリ ブロックがあれば理想的です。私は主にこれをやりたいと思っていますが、ベクトルよりもはるかに高速でしたが、ベクトルベースのコードで何か間違ったことをしたため、比較すると非常に遅くなりましたか? (個人的にはベクトルの方が使いやすいと思いますが、速度が本当に必要な場合は、より高速であると思われる場合はメモリブロックの操作に対処します)

4

2 に答える 2

0

あなたがする必要があるのは変わることだと思います

pChar2 += (unsigned char) pix.black_white;

pChar2[z] = (unsigned char) pix.black_white;

あなたがやろうとしていることをしようとしていると仮定します(pChar2が指しているメモリブロックに値を割り当ててから、ポインタを次の8ビットメモリブロックに移動しますか?)

于 2013-06-04T03:36:40.190 に答える
0

境界チェック要素アクセサーを使用しないでくださいat()。範囲外のインデックスを使用すると例外をスローする必要があるため、毎回インデックスをチェックします。最初にベクトルのサイズを変更したため、これは決して起こらないはずです。

そのため、代わりに非境界チェック operator を使用する必要があります[]

C 配列のようにベクトルに直接書き込むこともできます。一部の純粋主義者はこれに腹を立てるかもしれませんが、ベクトルを使用しても問題ないと思います。

images.resize(rows*cols);
unsigned char *bwPixel = &images[0];

for( ... )
{
    // ...
    *bwPixel++ = (unsigned char) (pix.blue * .11 + pix.green * .59 + pix.red *.3);
}
于 2013-06-04T03:37:37.843 に答える