1

我有一些专有的图像处理代码。它遍历图像并计算图像的一些统计数据。我正在谈论的这种代码的示例可以在下面看到,尽管这不是需要优化的算法。

我的问题是,有什么工具可以用来分析这些紧密的循环,以确定哪里慢?昏昏欲睡,Windows 性能分析器都更专注于识别哪些方法/函数很慢。我已经知道什么功能很慢,我只需要弄清楚如何优化它。

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 利用率)可以显着提高速度,我敢肯定没有一个分析器可以建议其中任何一个。

因此,一旦您知道该方法的哪一部分速度较慢,您就可以按照以下两个步骤进行操作:

  1. 算法优化:了解算法在做什么,并尝试提出更优化的算法。谷歌是你的朋友,很可能有人已经考虑过优化该算法并与世界分享想法/代码。通过,您通常应该考虑您拥有的约束。例如,加速代码的最简单但最有效的图像处理方法是将图像的大小减小到尽可能小。一个好的经验法则是质疑代码/算法中所做的每一个假设。例如,是否需要处理 800x600 的图像?或者可以在不影响准确性的情况下将尺寸减小到 320x240?是否需要处理三通道图像?或者同样可以用灰度图像实现?我想你应该已经明白了。

  2. 实施优化:一些高级分析工具可以建议如何调整代码,您可以尝试找到一个负担得起的代码。有些人可能不同意,但我认为没有必要使用这些工具。通常不需要图像处理精确值,例如,可以使用整数对滤波器响应的粗略近似来代替双浮点数的精确计算。SIMD 指令和最近的 GPU 已被证明非常适合优化图像处理方法。如果可能的话,你应该考虑到这一点。你总是可以谷歌如何优化循环或一些特定的操作。毕竟你可以做的一种可能性是将你的代码分解成更小的逻辑部分并改变它,这样算法或方法就不会通过共享这些部分来揭示。

于 2012-05-09T04:55:56.737 回答