图像处理代码性能优化及优化后结果异常问题求助
图像处理代码优化问题:结果异常与性能提升需求
我有一段可正常运行但执行缓慢的图像处理代码,尝试用LockBits和并行处理优化后,代码无法输出预期结果。目前有一段可正常运行的新代码,但执行时长约400毫秒,仍存在性能瓶颈,需要进一步提速,同时排查优化后结果异常的问题。
原可运行但缓慢的代码
private void Form1_Load() { last_action = "Form1_Load"; Bitmap image = new Bitmap(pictureBox1.Image); int width = image.Width; int height = image.Height; int div = 8; int scopeLen = width / div; int[][] bwColorScope = new int[256][]; int[][] bColorScope = new int[256][]; int[][] gColorScope = new int[256][]; int[][] rColorScope = new int[256][]; for (int i = 0; i < 256; i++) { bwColorScope[i] = new int[scopeLen + 1]; bColorScope[i] = new int[scopeLen + 1]; gColorScope[i] = new int[scopeLen + 1]; rColorScope[i] = new int[scopeLen + 1]; } for (int l = 0; l < scopeLen; l++) { for (int x = l * div; x < (l + 1) * div; x++) { for (int y = 0; y < height; y++) { Color pixel = image.GetPixel(x, y); int grayValue = (int)(pixel.R * 0.3 + pixel.G * 0.59 + pixel.B * 0.11); bwColorScope[255 - grayValue][l] += 1; bColorScope[255 - pixel.B][l] += 1; gColorScope[255 - pixel.G][l] += 1; rColorScope[255 - pixel.R][l] += 1; } } } width = bwColorScope[0].Length; height = bwColorScope.Length; Bitmap scopeImage = new Bitmap(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int value = Math.Min(bwColorScope[y][x], 255); if (value < 50) { scopeImage.SetPixel(x, y, Color.Transparent); continue; } Color color = Color.FromArgb(value, value, value); scopeImage.SetPixel(x, y, color); } } Bitmap scopeImage1 = new Bitmap(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int value = Math.Min(bColorScope[y][x], 255); if (value < 50) { scopeImage1.SetPixel(x, y, Color.Transparent); continue; } Color color = Color.FromArgb(value, value, 255); scopeImage1.SetPixel(x, y, color); } } Bitmap scopeImage2 = new Bitmap(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int value = Math.Min(gColorScope[y][x], 255); if (value < 50) { scopeImage2.SetPixel(x, y, Color.Transparent); continue; } Color color = Color.FromArgb(value, 255, value); scopeImage2.SetPixel(x, y, color); } } Bitmap scopeImage3 = new Bitmap(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int value = Math.Min(rColorScope[y][x], 255); if (value < 50) { scopeImage3.SetPixel(x, y, Color.Transparent); continue; } Color color = Color.FromArgb(255, value, value); scopeImage3.SetPixel(x, y, color); } } Bitmap bitmap = new Bitmap(scopeImage.Width, scopeImage.Height); using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawImage(scopeImage, 0, 0); ImageAttributes imageAttributes = new ImageAttributes(); ColorMatrix colorMatrix2 = new ColorMatrix(); colorMatrix2.Matrix33 = .3f; imageAttributes.SetColorMatrix(colorMatrix2, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); g.DrawImage(scopeImage1, new Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, imageAttributes); g.DrawImage(scopeImage2, new Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, imageAttributes); g.DrawImage(scopeImage3, new Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, imageAttributes); } pictureBox2.Image = bitmap; }
尝试的优化代码(结果异常)
private void Form1_Load() { last_action = "Form1_Load"; Bitmap image = new Bitmap(pictureBox1.Image); // 创建新位图确保未被锁定 int width = image.Width; int height = image.Height; int div = 8; int scopeLen = width / div; // 创建存储颜色数据的数组 int[][] bwColorScope = new int[256][]; int[][] bColorScope = new int[256][]; int[][] gColorScope = new int[256][]; int[][] rColorScope = new int[256][]; for (int i = 0; i < 256; i++) { bwColorScope[i] = new int[scopeLen + 1]; bColorScope[i] = new int[scopeLen + 1]; gColorScope[i] = new int[scopeLen + 1]; rColorScope[i] = new int[scopeLen + 1]; } // 锁定图像位以加快访问速度 BitmapData bmpData = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unsafe { byte* ptr = (byte*)bmpData.Scan0; for (int l = 0; l < scopeLen; l++) { Parallel.For(l * div, (l + 1) * div, x => { for (int y = 0; y < height; y++) { byte* pixel = ptr + (x + y * width) * 4; int grayValue = (int)(pixel[2] * 0.3 + pixel[1] * 0.59 + pixel[0] * 0.11); Interlocked.Increment(ref bwColorScope[255 - grayValue][l]); Interlocked.Increment(ref bColorScope[255 - pixel[0]][l]); Interlocked.Increment(ref gColorScope[255 - pixel[1]][l]); Interlocked.Increment(ref rColorScope[255 - pixel[2]][l]); } }); } } image.UnlockBits(bmpData); // 创建并更新频谱图像 Bitmap[] scopeImages = new Bitmap[4]; for (int i = 0; i < 4; i++) { scopeImages[i] = new Bitmap(width, height); Parallel.For(0, height, y => { for (int x = 0; x < width; x++) { int value = 255; if (i == 0) value = Math.Min(bwColorScope[y][x], 255); else if (i == 1) value = Math.Min(bColorScope[y][x], 255); else if (i == 2) value = Math.Min(gColorScope[y][x], 255); else if (i == 3) value = Math.Min(rColorScope[y][x], 255); if (value < 50) { scopeImages[i].SetPixel(x, y, Color.Transparent); } else { Color color = i == 1 ? Color.FromArgb(value, value, 255) : i == 2 ? Color.FromArgb(value, 255, value) : i == 3 ? Color.FromArgb(255, value, value) : Color.FromArgb(value, value, value); scopeImages[i].SetPixel(x, y, color); } } }); } // 合并频谱图像 Bitmap resultBitmap = new Bitmap(scopeImages[0].Width, scopeImages[0].Height); using (Graphics g = Graphics.FromImage(resultBitmap)) { g.DrawImage(scopeImages[0], 0, 0); ImageAttributes imageAttributes = new ImageAttributes(); ColorMatrix colorMatrix2 = new ColorMatrix(); colorMatrix2.Matrix33 = .3f; imageAttributes.SetColorMatrix(colorMatrix2, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); for (int i = 1; i < 4; i++) { g.DrawImage(scopeImages[i], new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), 0, 0, resultBitmap.Width, resultBitmap.Height, GraphicsUnit.Pixel, imageAttributes); } } pictureBox2.Image = resultBitmap; }
当前可用但仍需提速的新代码
private void Form1_Load() { last_action = "Form1_Load"; Bitmap cimg = new Bitmap(pictureBox1.Image); int div = 1; int scopeLen = cimg.Width / div; int[,] bwColorScope = new int[scopeLen + 1, 256]; int[,] bColorScope = new int[256, scopeLen + 1]; int[,] gColorScope = new int[256, scopeLen + 1]; int[,] rColorScope = new int[256, scopeLen + 1]; for (int l = 0; l < scopeLen; l++) { for (int x = l * div; x < (l + 1) * div; x++) { for (int y = 0; y < 256; y++) { Color pixelColor = cimg.GetPixel(x, y); bColorScope[255 - pixelColor.B, l]++; gColorScope[255 - pixelColor.G, l]++; rColorScope[255 - pixelColor.R, l]++; bwColorScope[l, 255 - pixelColor.R]++; } } } int width = bColorScope.GetLength(1); int height = bColorScope.GetLength(0); Bitmap bwColorScopeImage = new Bitmap(width, height); Bitmap bchannelImage = new Bitmap(width, height); Bitmap rchannelImage = new Bitmap(width, height); Bitmap gchannelImage = new Bitmap(width, height); if (!dim) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { bwColorScopeImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, bwColorScope[x, y]), 255, 255, 255)); bchannelImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, bColorScope[y, x]), 0, 0, 255)); rchannelImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, rColorScope[y, x]), 255, 0, 0)); gchannelImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, gColorScope[y, x]), 0, 255, 0)); } } } else { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int colorValue = 255 - y; bwColorScopeImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, bwColorScope[x, y]), colorValue, colorValue, colorValue)); bchannelImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, bColorScope[y, x]), colorValue, colorValue, 255)); rchannelImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, rColorScope[y, x]), 255, colorValue, colorValue)); gchannelImage.SetPixel(x, y, Color.FromArgb(Math.Min(255, gColorScope[y, x]), colorValue, 255, colorValue)); } } } pictureBox2.Image = new Bitmap(bwColorScopeImage.Width, bwColorScopeImage.Height); using (Graphics g = Graphics.FromImage(pictureBox2.Image)) { g.DrawImage(bwColorScopeImage, Point.Empty); g.DrawImage(bchannelImage, Point.Empty); g.DrawImage(rchannelImage, Point.Empty); g.DrawImage(gchannelImage, Point.Empty); } }
输出对比
- 预期图像:灰度与蓝、绿、红三色通道叠加的频谱图,各通道分布层次清晰,符合像素统计规律
- 优化代码错误输出图像:通道分布混乱,颜色叠加逻辑失效,与预期结果差异显著
内容的提问来源于stack exchange,提问作者user22731523
相关产品推荐
相关产品推荐

