1

独自の画像処理コードがあります。画像上を歩き、画像の統計を計算します。私が話している種類のコードの例を以下に示しますが、これは最適化が必要なアルゴリズムではありません。

私の質問は、これらの種類のタイトなループをプロファイリングして、どこが遅いかを判断するためのツールは何ですか?Sleepy、Windows Performance Analyzerはすべて、どのメソッド/関数が遅いかを特定することに重点を置いています。私はすでにどの関数が遅いかを知っています、私はそれを最適化する方法を理解する必要があります。

void BGR2YUV(IplImage* bgrImg, IplImage* yuvImg)
{
    const int height    = bgrImg->height;
    const int width     = bgrImg->width;
    const int step      = bgrImg->widthStep;
    const int channels  = bgrImg->nChannels;

    assert(channels == 3);
    assert(bgrImg->height == yuvImg->height);
    assert(bgrImg->width == yuvImg->width);
    // for reasons that are not clear to me, these are not the same.
    // Code below has been modified to reflect this fact, but if they 
    // could be the same, the code below gets sped up a bit.
//  assert(bgrImg->widthStep == yuvImg->widthStep);
    assert(bgrImg->nChannels == yuvImg->nChannels);

    const uchar* bgr = (uchar*) bgrImg->imageData;
          uchar* yuv = (uchar*) yuvImg->imageData;

    for (int i = 0; i < height; i++) 
    {
        for (int j = 0; j < width; j++) 
        {
            const int ixBGR = i*step+j*channels;
            const int b = (int) bgr[ixBGR+0];
            const int g = (int) bgr[ixBGR+1];
            const int r = (int) bgr[ixBGR+2];

            const int y = (int) (0.299 * r + 0.587 * g + 0.114 * b);
            const double di = 0.596 * r - 0.274 * g - 0.322 * b;
            const double dq = 0.211 * r - 0.523 * g + 0.312 * b;
            // Do some shifting and trimming to get i & q to fit into uchars.
            const int iv = (int) (128 + max(-128.0, min(127.0, di)));
            const int q = (int) (128 + max(-128.0, min(127.0, dq)));

            const int ixYUV = i*yuvImg->widthStep + j*channels;
            yuv[ixYUV+0] = (uchar)y;
            yuv[ixYUV+1] = (uchar)iv;
            yuv[ixYUV+2] = (uchar)q;
        }
    }
}
4

1 に答える 1

1

コードを共有できないので、いくつかの一般的な提案があります。まず、プロファイラーはコードのどの部分に時間がかかっているかを示し、より高度なプロファイラーは速度を向上させるためのいくつかの変更を提案できることを覚えておいてください。しかし、一般的に、アルゴリズムの最適化は、コードを微調整するよりもはるかに高速になります。共有しているサンプルコードの場合、効率的または高速のRGBからYUVへの変換をグーグルで検索すると、速度を大幅に向上させる多数のメソッド(ルックアップテーブルの使用からSSE2およびGPUの使用率まで)が見つかります。それらのいずれかを提案することができます。

したがって、メソッドのどの部分が遅いかがわかったら、次の2つの手順に従うことができます。

  1. アルゴリズムの最適化:アルゴリズムが何をしているのかを理解し、より最適化されたアルゴリズムを考え出すようにしてください。グーグルはあなたの友達です。誰かがすでにそのアルゴリズムを最適化することを考えており、アイデア/コードを世界と共有している可能性があります。を通して、多くの場合、あなたはあなたが持っている制約を考慮する必要があります。たとえば、コードを高速化するための最も簡単ですが最も効果的な画像処理方法は、画像のサイズを可能な限り小さくすることです。経験則として、コード/アルゴリズムで行われたすべての仮定に疑問を投げかけることです。たとえば、800x600の画像を処理する必要がありますか?または、精度を損なうことなくサイズを320x240に縮小できますか?3チャンネル画像の処理は必要ですか?または同じことがグレースケール画像で達成できますか?私はあなたがその考えを理解したと思います。

  2. 実装の最適化:いくつかの高度なプロファイリングツールは、手頃な価格のコードを見つけるために試みることができるコードを微調整する方法を提案することができます。同意できない人もいるかもしれませんが、そのようなツールを使用する必要はないと思います。多くの場合、画像処理の正確な値は必要ありません。たとえば、ダブルフロートによる正確な計算の代わりに、たとえば整数によるフィルター応答の大まかな近似を使用できます。SIMD命令と最近のGPUは、画像処理方法の最適化に完全に適していることが示されています。可能であれば、それを考慮する必要があります。ループや特定の操作を最適化する方法をいつでもグーグルで検索できます。そして、できることの1つは、コードを小さな論理部分に分割し、それらを共有してアルゴリズムやメソッドが明らかにならないように変更することです。

于 2012-05-09T04:55:56.737 に答える