作为我自己的一项教育练习,我正在编写一个可以对一堆图像进行平均的应用程序。这通常用于天文摄影以减少噪点。
我使用的库是 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);
}
}
代码通过遍历每个像素并将每个 channel 的像素强度添加到一个double vector 中来平均 10 个图像。然后函数 avg 将 vector 作为参数并对结果进行平均。然后在 stackedImage 中的相应像素处使用此平均值 - 这是结果图像。它工作得很好,但正如我提到的,我对速度不满意。在 Core i5 机器上需要 2 分 30 秒。图像是 8 兆像素和 16 位 TIFF。我知道它有很多数据,但我看到它在其他应用程序中完成得更快。
是我的循环太慢了还是 pixelColor(x,y) 访问图像像素的方式很慢?有没有更快的方法?
最佳答案
为什么要使用 vector/数组?
为什么不
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;
这避免了对每个像素的 vector 对象调用 36 次函数。
通过使用整个图像的 PixelCache
而不是原始的 Image
对象,您可以获得更好的性能。请参阅 online Magick++ documentation for Image 的“低级图像像素访问”部分
那么内循环就变成了
PixelPacket* pix = cache[i]+row*columns+column;
red+= pix->red;
blue+= pix->blue;
green+= pix->green;
现在您还删除了对每个像素的 10 个 PixelColor 调用、10 个 ColorRGB 构造函数和 30 个访问函数。
请注意,这都是理论;我还没有测试过任何一个
关于c++ - Magick++ 中的快速/高效像素访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5327638/