4

作为我自己的教育练习,我正在编写一个可以平均一堆图像的应用程序。这通常用于天文摄影以减少噪音。

我正在使用的库是 Magick++,我已经成功地实际编写了应用程序。但是,不幸的是,它的速度很慢。这是我正在使用的代码:

for(row=0;row<rows;row++)
{
    for(column=0;column<columns;column++)
    {
        red.clear(); blue.clear(); green.clear();
        for(i=1;i<10;i++)
        {
            ColorRGB rgb(image[i].pixelColor(column,row));
            red.push_back(rgb.red());
            green.push_back(rgb.green());
            blue.push_back(rgb.blue());
        }
        redVal = avg(red);
        greenVal = avg(green);
        blueVal = avg(blue);
        redVal = redVal*MaxRGB; greenVal = greenVal*MaxRGB; blueVal = blueVal*MaxRGB;
        Color newRGB(redVal,greenVal,blueVal);
        stackedImage.pixelColor(column,row,newRGB);
    }
}

该代码通过遍历每个像素并将每个通道的像素强度添加到双向量中来平均 10 个图像。函数avg然后将向量作为参数并对结果进行平均。然后在stackedImage中的相应像素处使用该平均值——这是结果图像。它工作得很好,但正如我所提到的,我对速度不满意。在 Core i5 机器上需要 2 分 30 秒。这些图像是 8 兆像素和 16 位 TIFF。我知道它有很多数据,但我看到它在其他应用程序中做得更快。

是我的循环很慢还是pixelColor(x,y)是访问图像中像素的缓慢方法?有更快的方法吗?

4

3 回答 3

4

为什么要使用向量/数组?

为什么不

double red=0.0, blue=0.0, green=0.0;
for(i=1;i<10;i++)
{
   ColorRGB rgb(image[i].pixelColor(column,row));
   red+=rgb.red();
   blue+=rgb.blue();
   green+=rgb.green();
}
red/=10;
blue/=10;
green/=10;

这避免了每个像素对矢量对象进行 36 次函数调用。

PixelCache通过使用整个图像而不是原始Image对象,您可以获得更好的性能。请参阅 Image在线 Magick++ 文档的“低级图像像素访问”部分

然后内循环变成

PixelPacket* pix = cache[i]+row*columns+column;
red+= pix->red;
blue+= pix->blue;
green+= pix->green;

现在,您还删除了对 PixelColor 的 10 个调用、10 个 ColorRGB 构造函数和每个像素的 30 个访问器函数。

注意,这都是理论;我没有测试过任何一个

于 2011-03-16T18:04:39.887 回答
1

评论:

  • 为什么要对和red使用向量?因为 using可以执行重新分配和瓶颈处理。相反,您可以只分配一次三个 10 种颜色的数组。bluegreenpush_back
  • 您不能rgb在循环之外声明以减轻不必要的构造和破坏吗?
  • Magick++ 没有平均图像的方法吗?
于 2011-03-16T16:13:23.243 回答
0

以防万一其他人想要平均图像以减少噪音,并且不觉得有太多的“教育练习” ;-)

ImageMagick 可以对一系列图像进行平均,如下所示:

convert image1.tif image2.tif ... image32.tif -evaluate-sequence mean result.tif

您还可以通过将mean上述命令中的单词更改为您想要的任何内容来进行中值过滤和其他操作,例如:

convert image1.tif image2.tif ... image32.tif -evaluate-sequence median result.tif

您可以通过以下方式获取可用操作的列表:

identify -list evaluate

输出

Abs
Add
AddModulus
And
Cos
Cosine
Divide
Exp
Exponential
GaussianNoise
ImpulseNoise
LaplacianNoise
LeftShift
Log
Max
Mean
Median
Min
MultiplicativeNoise
Multiply
Or
PoissonNoise
Pow
RightShift
RMS
RootMeanSquare
Set
Sin
Sine
Subtract
Sum
Threshold
ThresholdBlack
ThresholdWhite
UniformNoise
Xor
于 2016-06-03T14:46:06.293 回答