如何在C#中使用灰卡进行色彩平衡

发布于 2024-09-27 07:36:40 字数 2121 浏览 1 评论 0原文

我需要对包含 18% 灰卡的图像进行色彩平衡。用户将此图像加载到应用程序中,然后单击灰卡。从这里我需要有关算法的帮助来平衡图像的颜色。我发现一些文章提到了进行矩阵变换,我已经尝试过,但没有成功(图像被洗掉或变成一种颜色或另一种颜色)。我现在的代码是:

        int sampleSize = 20;  // The square around the user's click on the gray card
        int rVal = 0, gVal = 0, bVal = 0;
        int count = 0;
        for (int x = 0; x < sampleSize - 1; x++)
        {
            for (int y = 0; y < sampleSize - 1; y++)
            {
                System.Drawing.Color c = grayCardArea.GetPixel(x, y);
                if (c.R > 0)
                {
                    rVal += c.R;
                    gVal += c.G;
                    bVal += c.B;
                    rs.Add(c.R);
                    count++;
                }
            }
        }
        grayCardGraphics.Dispose();

        int rAvg = 0, gAvg = 0, bAvg = 0;
        rAvg = (int)Math.Round((decimal)rVal / (count));
        gAvg = (int)Math.Round((decimal)gVal / (count));
        bAvg = (int)Math.Round((decimal)bVal / (count));

        // 117 is a value I found online for the neutral gray color of the gray card
        float rDiff = (117 / (float)rAvg);
        float gDiff = (117 / (float)gAvg);
        float bDiff = (117 / (float)bAvg);

        float[][] ptsArray = 
            { 
            new float[] {rDiff, 0, 0, 0, 0},
            new float[] {0, gDiff, 0, 0, 0},
            new float[] {0, 0, bDiff, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {0, 0, 0, .0f, 1}
            };
        // Create a ColorMatrix
        ColorMatrix clrMatrix = new ColorMatrix(ptsArray);

        // Create ImageAttributes
        ImageAttributes imgAttribs = new ImageAttributes();
        // Set color matrix
        imgAttribs.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
        // Draw image with ImageAttributes
        outputImageGraphics.DrawImage(srcImage, new System.Drawing.Rectangle(0, 0, srcImage.Width, srcImage.Height),
            0, 0, srcImage.Width, srcImage.Height,
            GraphicsUnit.Pixel, imgAttribs);

查看保存的输出图像副本显示图像的奇怪转换。

非常感谢任何帮助!

I need to color balance an image that has an 18% gray card in it. The user loads this image into the application, then clicks on the gray card. From here is where I need help with an algorithm to color balance the image. I've found a few articles that mention doing a matrix transform, which I've tried, but without success (the image washes out or turns one color or another). The code I have now is:

        int sampleSize = 20;  // The square around the user's click on the gray card
        int rVal = 0, gVal = 0, bVal = 0;
        int count = 0;
        for (int x = 0; x < sampleSize - 1; x++)
        {
            for (int y = 0; y < sampleSize - 1; y++)
            {
                System.Drawing.Color c = grayCardArea.GetPixel(x, y);
                if (c.R > 0)
                {
                    rVal += c.R;
                    gVal += c.G;
                    bVal += c.B;
                    rs.Add(c.R);
                    count++;
                }
            }
        }
        grayCardGraphics.Dispose();

        int rAvg = 0, gAvg = 0, bAvg = 0;
        rAvg = (int)Math.Round((decimal)rVal / (count));
        gAvg = (int)Math.Round((decimal)gVal / (count));
        bAvg = (int)Math.Round((decimal)bVal / (count));

        // 117 is a value I found online for the neutral gray color of the gray card
        float rDiff = (117 / (float)rAvg);
        float gDiff = (117 / (float)gAvg);
        float bDiff = (117 / (float)bAvg);

        float[][] ptsArray = 
            { 
            new float[] {rDiff, 0, 0, 0, 0},
            new float[] {0, gDiff, 0, 0, 0},
            new float[] {0, 0, bDiff, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {0, 0, 0, .0f, 1}
            };
        // Create a ColorMatrix
        ColorMatrix clrMatrix = new ColorMatrix(ptsArray);

        // Create ImageAttributes
        ImageAttributes imgAttribs = new ImageAttributes();
        // Set color matrix
        imgAttribs.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
        // Draw image with ImageAttributes
        outputImageGraphics.DrawImage(srcImage, new System.Drawing.Rectangle(0, 0, srcImage.Width, srcImage.Height),
            0, 0, srcImage.Width, srcImage.Height,
            GraphicsUnit.Pixel, imgAttribs);

Viewing a saved copy of the outputImage shows an odd transformation of the image.

Any help is greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

姐不稀罕 2024-10-04 07:36:40

我的公司 Atalasoft 有一个免费的 .NET Imaging SDK,其中有一个名为 LevelsCommand 的类,我认为它可以满足您的需求。

http://atalasoft.com/photofree

代码类似于

AtalaImage img = new AtalaImage("filename");
LevelsCommand cmd = new LevelsCommand(/* ... */ ); //  need to pass in leveling colors
img = cmd.Apply(img).Image;
img.Save("filename-new", new PngEncoder(), null); // or could be new JpegEncoder() or something else

您应该在文件名上使用正确的扩展名来指示格式。

My company, Atalasoft, has a free .NET Imaging SDK, with a class called LevelsCommand, that I think will do what you want.

http://atalasoft.com/photofree

Code is something like

AtalaImage img = new AtalaImage("filename");
LevelsCommand cmd = new LevelsCommand(/* ... */ ); //  need to pass in leveling colors
img = cmd.Apply(img).Image;
img.Save("filename-new", new PngEncoder(), null); // or could be new JpegEncoder() or something else

You should use proper extensions on filenames to indicate the format.

我还不会笑 2024-10-04 07:36:40

您的第一个假设似乎是图像首先正确曝光,并且使灰卡读取 117, 117, 117 将解决问题。我的建议是不要管曝光,只调整色偏。您可能会发现不同的颜色模型很有用——例如,HSL。灰卡的饱和度应始终为零。

或者,我有一个示例灰色目标读数 71、72、60。这有点温暖。按理说,更正确的读数应该是 67,67,67 或 (R+G+B)/3。因为图像有点曝光不足,所以我就这样保留了它,但在不改变图像密度的情况下实现了真正的中性。

我希望这能为您获得正确的颜色提供一些帮助。

Your first assumption appears to be that the image was properly exposed in the first place and that making the gray card read 117, 117, 117 will solve the problem. My advice is to leave the exposure alone and adjust just the color cast. You might find a different color model useful -- e.g., HSL. The saturation of a gray card should always be zero.

Alternatively, I have an example gray target reading 71, 72, 60. This is a bit warm. It would stand to reason that a more correct reading would be 67,67,67 or (R+G+B)/3. Because the image is a bit underexposed, I left it that way, but achieved a true neutral without altering the density of the image.

I hope this provides some help along your path toward getting the color right.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文