我想知道是否有人可以说明我可以做的改进,使这个合成算法更快 . 做什么是将3个图像分割成第一个图像红色通道,第二个图像绿色通道和第三个图像蓝色通道,并将它们合成为一个新图像 . 现在它起作用但速度极慢 . 我想到它必须对所有图像组件进行逐像素处理的原因 .
过程是:
对于所有图像:提取相应的R G和B值 - >合成为1个图像 - >保存新图像 .
foreach (Image[] QRE2ImgComp in QRE2IMGArray)
{
Globals.updProgress = "Processing frames: " + k + " of " + QRE2IMGArray.Count + " frames done.";
QRMProgressUpd(EventArgs.Empty);
Image RedLayer = GetRedImage(QRE2ImgComp[0]);
QRE2ImgComp[0] = RedLayer;
Image GreenLayer = GetGreenImage(QRE2ImgComp[1]);
QRE2ImgComp[1] = GreenLayer;
Image BlueLayer = GetBlueImage(QRE2ImgComp[2]);
QRE2ImgComp[2] = BlueLayer;
Bitmap composite = new Bitmap(QRE2ImgComp[0].Height, QRE2ImgComp[0].Width);
Color Rlayer,Glayer,Blayer;
byte R, G, B;
for (int y = 0; y < composite.Height; y++)
{
for (int x = 0; x < composite.Width; x++)
{
//pixelColorAlpha = composite.GetPixel(x, y);
Bitmap Rcomp = new Bitmap(QRE2ImgComp[0]);
Bitmap Gcomp = new Bitmap(QRE2ImgComp[1]);
Bitmap Bcomp = new Bitmap(QRE2ImgComp[2]);
Rlayer = Rcomp.GetPixel(x, y);
Glayer = Gcomp.GetPixel(x, y);
Blayer = Bcomp.GetPixel(x, y);
R = (byte)(Rlayer.R);
G = (byte)(Glayer.G);
B = (byte)(Blayer.B);
composite.SetPixel(x, y, Color.FromArgb((int)R, (int)G, (int)B));
}
}
Globals.updProgress = "Saving frame...";
QRMProgressUpd(EventArgs.Empty);
Image tosave = composite;
Globals.QRFrame = tosave;
tosave.Save("C:\\QRItest\\E" + k + ".png", ImageFormat.Png);
k++;
}
这里参考红色通道滤波器方法对蓝色和绿色相对相同:
public Image GetRedImage(Image sourceImage)
{
Bitmap bmp = new Bitmap(sourceImage);
Bitmap redBmp = new Bitmap(sourceImage.Width, sourceImage.Height);
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
Color pxl = bmp.GetPixel(x, y);
Color redPxl = Color.FromArgb((int)pxl.R, 0, 0);
redBmp.SetPixel(x, y, redPxl);
}
}
Image tout = (Image)redBmp;
return tout;
}
2 回答
我完全同意Yahia在提高绩效的答案中列出的观点 . 我想再补充一点关于性能的观点 . 您可以使用.Net Framework的
Parallel
类来并行执行for循环 . 以下示例使用LockBits
方法和Parallel
类来提高性能(假设每像素32位(PixelFormat.Format32bppArgb)):希望,这个答案为您提供了改进代码的起点 .
Move these
outside the for-loops!
其他非常重要的一点:
avoid using GetPixel - it is VERY SLOW!
Checkout LockBits等 - 这就是通常在.NET中进行像素级访问的方式
考虑使用第三方库(免费或商业)......有几个内置了一些优化方法来做你想要实现的...