简体   繁体   English

比较像素中的RGB颜色并将其原始颜色更改为最接近的颜色

[英]Compare RGB colors in a pixel and change its original color to the closest one

I need help for my assignment. 我的任务需要帮助。 Basically, this is what I want to do: 基本上,这就是我想要做的:

  • Load an image to a PictureBox 将图像加载到PictureBox
  • Calculate the difference between 255 (the maximum value) and the R value in each pixel, and the difference between 255 and G value, and also for B value 计算每个像素中255(最大值)和R值之间的差值,以及255和G值之间的差值,以及B值的差值
  • From the calculation above, the least absolute value will indicate that the pixel's color is closer to that color (ex: (255-R value) has the smallest absolute value, so the pixel is closer to that color) 从上面的计算中,最小绝对值将指示像素的颜色更接近该颜色(例如:(255-R值)具有最小的绝对值,因此像素更接近该颜色)
  • Change the pixel color to the closer color (in example above, it means change it to Red) 将像素颜色更改为更接近的颜色(在上面的示例中,表示将其更改为红色)
  • Display the result in the output picturebox 在输出图片框中显示结果

As the result, I will obtain the image with those three primary colors. 结果,我将获得具有这三种基色的图像。

I have written the code like this: 我写了这样的代码:

    Bitmap img = new Bitmap(InputPictureBox.Image);
        byte R, G, B;
        Color pixelColor;
        for (int x = 0; x < img.Width; x++)
        {
            for (int y = 0; y < img.Height; y++)
            {
                pixelColor = img.GetPixel(x, y);
                R = (byte) Math.Abs(pixelColor.R - 255);
                G = (byte) Math.Abs(pixelColor.G - 255);
                B = (byte) Math.Abs(pixelColor.B - 255);

                if (R < G && R < B)
                {
                    pixelColor = Color.Red;
                }
                else if (G < R && G < B)
                {
                    pixelColor = Color.Green;
                }
                else if (B < R && B < G)
                {
                    pixelColor = Color.Blue;
                }
            }
        }
  OutputPictureBox.Image = img;

The problem is that the color image then turn to be inverted. 问题是彩色图像然后转向反转。 So, what is wrong in my code? 那么,我的代码有什么问题? I assume that the if statements don't work, but I don't know why. 我假设if语句不起作用,但我不知道为什么。 Am I wrong? 我错了吗?

One more question related to my code above, can it actually work by simply calculating the gap of R/G/B value like that OR it absolutely has to be done by using euclidean distance? 还有一个问题与我上面的代码有关,它实际上可以通过简单地计算R / G / B值的差距来实现,或者它必须通过使用欧几里德距离完成吗?

If you don't mind please show me how to fix this or maybe how the code should be written. 如果您不介意,请告诉我如何解决这个问题或者如何编写代码。 I ever read a quite similar question, but the given answer still didn't give me a clue. 我读过一个非常相似的问题,但给出的答案仍然没有给我一些线索。

Your code actually works, although there is a bit of overthinking put into it. 你的代码实际上是有效的,尽管有一些过度的思考。

Try this: 试试这个:

The code has been moved to the Update section at the bottom of the post 代码已移至 帖子底部的“更新” 部分

Result: 结果:

结果


I've removed the overthinking part. 我已经删除了过度思考的部分。

  • There's no reason (at least from reading your question) why you need to invert the color component values; 没有理由(至少从阅读你的问题)为什么你需要反转颜色分量值;

    1. Simply doing R = pixelColor.R is enough; 简单地做R = pixelColor.R就足够了;

    2. And through this you don't have to think of it as "which has the least amount of red", but rather, " if it has the most amount of red, it's red !" 通过这个,您不必将其视为“红色含量最少 ”,而是“ 如果红色含量最多则为 红色 !”

  • As LightStriker pointed out : You are missing (it is nowhere in your code) the code to set new value back into the image; 正如LightStriker指出的那样 :您缺少(代码中没有任何地方)将新值设置回图像的代码;

    1. This is accomplished using img.SetPixel(x, y, pixelColor) . 这是使用img.SetPixel(x, y, pixelColor)
  • I've added an else clause to match pixels where no single color component is greater than both others. 我添加了一个else子句来匹配没有单个颜色分量大于其他颜色分量的像素。

    1. For example, Yellow (255, 255, 0) would not be matched by your rules; 例如,黄色(255,255,0)将不符合您的规则;

    2. Using the version in this answer, it gets replaced by a Black pixel. 使用此答案中的版本,它将被Black像素替换。


Update: per the comments below asking for additional clarification. 更新:根据以下评论要求进一步澄清。 Here's how you would add more conditional statements: 以下是添加更多条件语句的方法:

// NEW (start) --------------------------------------------------
Color[] randomizedColors = new Color[] { Color.Red, Color.Green, Color.Blue };
Random randomizer = new Random();
// NEW (end) --------------------------------------------------

Bitmap img = new Bitmap(InputPictureBox.Image);
byte R, G, B;
Color pixelColor;

// NEW (start) --------------------------------------------------
Func<int, Color> ColorRandomizer = (numberOfColors) =>
{
    if (numberOfColors > randomizedColors.Length)
    {
        numberOfColors = randomizedColors.Length;
    }
    return randomizedColors[randomizer.Next(numberOfColors)];
};
// NEW (end) --------------------------------------------------

for (int x = 0; x < img.Width; x++)
{
    for (int y = 0; y < img.Height; y++)
    {
        pixelColor = img.GetPixel(x, y);
        R = pixelColor.R;
        G = pixelColor.G;
        B = pixelColor.B;

        if (R > G && R > B)
        {
            pixelColor = Color.Red;
        }
        else if (G > R && G > B)
        {
            pixelColor = Color.Green;
        }
        else if (B > R && B > G)
        {
            pixelColor = Color.Blue;
        }
// NEW (start) --------------------------------------------------
        else if (pixelColor == Color.Yellow)
        {
            // 2 = Red or Green
            pixelColor = ColorRandomizer(2);
        }
        else if (pixelColor = Color.FromArgb(152, 152, 152))
        {
            // 3 = Red, Green, or Blue
            pixelColor = ColorRandomizer(3);
        }
        /* else if (pixelColor = Some_Other_Color)
        {
            // 3 = Red, Green, or Blue
            pixelColor = ColorRandomizer(3);
        } */
// NEW (end) --------------------------------------------------
        else
        {
            pixelColor = Color.Black;
        }
        img.SetPixel(x, y, pixelColor);
    }
}

OutputPictureBox.Image = img;

With this updated code, add all colors that should be picked randomly to the randomizedColors array. 使用此更新的代码,将随机选取的所有颜色添加到randomizedColors数组中。 Use the lambda function, ColorRandomizer , to assist in choosing a color randomly; 使用lambda函数ColorRandomizer来帮助随机选择颜色; keep in mind that this function will randomly pick between the first element and the one specified. 请记住,此函数将在第一个元素和指定的元素之间随机选择。

Following is inverting all the colors. 以下是反转所有颜色。

R = (byte) Math.Abs(pixelColor.R - 255);
G = (byte) Math.Abs(pixelColor.G - 255);
B = (byte) Math.Abs(pixelColor.B - 255);

You can use: 您可以使用:

R = (byte) pixelColor.R;
G = (byte) pixelColor.G;
B = (byte) pixelColor.B;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 C# 中将 RGB 颜色转换为最接近的 ACI 颜色 - Converting RGB Colors to closest ACI Color in C# 比较c#中的RGB颜色 - Compare RGB colors in c# 灰度到 RGB:像素颜色设置错误值 - Grayscale to RGB: Pixel color is set with wrong value 获取特定颜色的 RGB 颜色范围 - Getting RGB color range for specific colors 将图像中的每个像素设置为与颜色列表最接近的匹配 - Setting every pixel in image to closest match from a list of Colors Unity:我无法更改图像的不透明度或在 RGB 中更改其颜色 - Unity : I can't change the opacity of an image or change its color in RGB 将一个像素与所有像素进行比较 - compare one pixel with all pixels 如何比较颜色对象并在颜​​色 [] 中获得最接近的颜色? - How to compare Color object and get closest Color in an Color[]? 在 Xamarin 中,如何在 1 秒内更改按钮的背景颜色并再次将其恢复为原始颜色? - In Xamarin, how can I change the background color of a button for just 1 second and return it again to its original color? 具有一种十六进制或 RGB 颜色代码。 以此为基础,需要根据 C# 中的百分比生成更亮和更暗的渐变颜色 - Having one color code either in hexadecimal or RGB. Keeping this as base, need to generate lighter & darker gradient colors based on percentage in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM