You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

图像处理代码性能优化及优化后结果异常问题求助

图像处理代码优化问题:结果异常与性能提升需求

我有一段可正常运行但执行缓慢的图像处理代码,尝试用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 14:18:08