C#标准化RGB并创建新图像

时间:2013-10-23 14:47:07

标签: c# image rgb brightness normalizing

我正在尝试创建一个接受图像的程序,递归遍历每个像素,对像素进行标准化并重新创建一个看起来与原始图像相同的新图像,但是已经标准化了像素。

    public void parseJpeg(String jpegPath)
    {
        var normalizedRed = 0.0;
        var normalizedGreen = 0.0;
        var normalizedBlue = 0.0;
        Bitmap normalizedImage = null;

        var image = new Bitmap(jpegPath);
        normalizedImage = new Bitmap(image.Width, image.Height);
        for (int x = 0; x < image.Width; ++x)
        {
            for (int y = 0; y < image.Height; ++y)
            {
                Color color = image.GetPixel(x, y);

                double exponent = 2;
                double redDouble = Convert.ToDouble(color.R);
                double blueDouble = Convert.ToDouble(color.B);
                double greenDouble = Convert.ToDouble(color.G);

                double redResult = Math.Pow(redDouble, exponent);
                double blueResult = Math.Pow(blueDouble, exponent);
                double greenResult = Math.Pow(greenDouble, exponent);

                double totalResult = redResult + blueResult + greenResult;                    

                normalizedRed = Convert.ToDouble(color.R) / Math.Sqrt(totalResult);
                normalizedGreen = Convert.ToDouble(color.G) / Math.Sqrt(totalResult);
                normalizedBlue = Convert.ToDouble(color.B) / Math.Sqrt(totalResult);


                Color newCol = Color.FromArgb(Convert.ToInt32(normalizedRed), Convert.ToInt32(normalizedGreen), Convert.ToInt32(normalizedBlue));

                normalizedImage.SetPixel(x, y, newCol);                                                                
            }                
        }

        normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg"); 
        resultsViewBox.AppendText("Process completed.\n");
    }

使用上面的代码产生所有黑色像素,我不明白为什么。当它标准化时,它设置RGB = 1.标准化后,如何设置具有新标准化值的像素?

当我执行下面的代码时,我在预览中得到一个黑蓝图像,但是当我打开文件时它是空白的。这比我之前获得的更好,这是所有黑色像素。这仅适用于一个图像。所以我不确定它向前迈进了多少。

public void parseJpeg(String jpegPath)
    {
        Bitmap normalizedImage = null;           

        var image = new Bitmap(jpegPath);
        normalizedImage = new Bitmap(image.Width, image.Height);
        for (int x = 0; x < image.Width; ++x)
        {
            for (int y = 0; y < image.Height; ++y)
            {
                Color color = image.GetPixel(x, y);

                float norm = (float)System.Math.Sqrt(color.R * color.R + color.B * color.B + color.G * color.G);

                Color newCol = Color.FromArgb(Convert.ToInt32(norm));

                normalizedImage.SetPixel(x, y, newCol);
            }
        }

        normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg");
        resultsViewBox.AppendText("Process completed.\n");
    }

我找到了我想要做的代码: http://www.lukehorvat.com/blog/normalizing-image-brightness-in-csharp/

    public void parseJpeg(String jpegPath)
    {
        var image = new Bitmap(jpegPath);
        normalizedImage = new Bitmap(image.Width, image.Height);


        for (int x = 0; x < image.Width; ++x)
        {
            for (int y = 0; y < image.Height; ++y)
            {
                float pixelBrightness = image.GetPixel(x, y).GetBrightness();
                minBrightness = Math.Min(minBrightness, pixelBrightness);
                maxBrightness = Math.Max(maxBrightness, pixelBrightness);
            }
        }

        for (int x = 0; x < image.Width; x++)
        {
            for (int y = 0; y < image.Height; y++)
            {
                Color pixelColor = image.GetPixel(x, y);
                float normalizedPixelBrightness = (pixelColor.GetBrightness() - minBrightness) / (maxBrightness - minBrightness);
                Color normalizedPixelColor = ColorConverter.ColorFromAhsb(pixelColor.A, pixelColor.GetHue(), pixelColor.GetSaturation(), normalizedPixelBrightness);

                normalizedImage.SetPixel(x, y, normalizedPixelColor);
            }
        }

        normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg");
        resultsViewBox.AppendText("Process completed.\n");
    }

3 个答案:

答案 0 :(得分:0)

您正在为图像中的每个像素创建一个新的位图并保存文件。移动

normalizedImage = new Bitmap(image.Width, image.Height);

在你的循环前行到

normalizedImage.Save("C:\\Users\\username\\Desktop\\test1.jpeg");

在你的循环后行。

您的规范化算法似乎不正确。假设您的原始颜色为红色(255,0,0)然后您的totalResult将为65025,而您的normalizedRed将为255 / sqrt(65025),即1,为您提供新的标准化颜色为(1,0,0),基本上是黑色。

答案 1 :(得分:0)

就像注意一样,如果你在外观之外定义所有双打,然后在循环中分配它们而不是每次迭代定义和删除8个双打中的每一个,你的代码将运行得更快

答案 2 :(得分:0)

您应该使用亮度或亮度因子来实现标准化,而不是弄乱颜色。这是一个已经回答的问题的链接,可以帮助您。您可以将每个RGB像素转换为HSL并将L因子缩小:

How do I normalize an image?

您共享的代码实际上是HSL操作的减少版本。