Ein einfacher Algorithmus zur Prüfung auf Farbe: Gehen Sie das Bild Pixel für Pixel in einer verschachtelten for-Schleife durch (Breite und Höhe) und prüfen Sie, ob die RGB-Werte der Pixel gleich sind. Wenn dies nicht der Fall ist, hat das Bild Farbinformationen. Wenn Sie alle Pixel durchlaufen, ohne auf diese Bedingung zu stoßen, dann haben Sie ein Graustufenbild.
Überarbeitung mit einem komplexeren Algorithmus:
In der ersten Version dieses Beitrags habe ich einen einfachen Algorithmus vorgeschlagen, der davon ausgeht, dass Pixel Graustufen sind, wenn die RGB-Werte der einzelnen Pixel gleich sind. So RGBs von 0,0,0 oder 128,128,128 oder 230,230,230 würden alle als grau testen, während 123,90,78 nicht. Einfach.
Hier ist ein Codeschnipsel, der auf eine Abweichung von Grau testet. Die beiden Methoden sind ein kleiner Teil eines komplexeren Prozesses, sollten aber genug Rohcode liefern, um bei der ursprünglichen Frage zu helfen.
/// <summary>
/// This function accepts a bitmap and then performs a delta
/// comparison on all the pixels to find the highest delta
/// color in the image. This calculation only works for images
/// which have a field of similar color and some grayscale or
/// near-grayscale outlines. The result ought to be that the
/// calculated color is a sample of the "field". From this we
/// can infer which color in the image actualy represents a
/// contiguous field in which we're interested.
/// See the documentation of GetRgbDelta for more information.
/// </summary>
/// <param name="bmp">A bitmap for sampling</param>
/// <returns>The highest delta color</returns>
public static Color CalculateColorKey(Bitmap bmp)
{
Color keyColor = Color.Empty;
int highestRgbDelta = 0;
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
if (GetRgbDelta(bmp.GetPixel(x, y)) <= highestRgbDelta) continue;
highestRgbDelta = GetRgbDelta(bmp.GetPixel(x, y));
keyColor = bmp.GetPixel(x, y);
}
}
return keyColor;
}
/// <summary>
/// Utility method that encapsulates the RGB Delta calculation:
/// delta = abs(R-G) + abs(G-B) + abs(B-R)
/// So, between the color RGB(50,100,50) and RGB(128,128,128)
/// The first would be the higher delta with a value of 100 as compared
/// to the secong color which, being grayscale, would have a delta of 0
/// </summary>
/// <param name="color">The color for which to calculate the delta</param>
/// <returns>An integer in the range 0 to 510 indicating the difference
/// in the RGB values that comprise the color</returns>
private static int GetRgbDelta(Color color)
{
return
Math.Abs(color.R - color.G) +
Math.Abs(color.G - color.B) +
Math.Abs(color.B - color.R);
}
1 Stimmen
Die Überprüfung des Bildtyps wird nicht ausreichen, da dieser auf 24 oder 32 Bit eingestellt ist (da Sie in Farbe scannen). Wahrscheinlich müssen Sie jedes einzelne Pixel überprüfen. Wenn R == G == B in allen Pixeln ist, handelt es sich um ein Graustufenbild, andernfalls ist es wahrscheinlich ein Farbbild.
1 Stimmen
Ein Gedanke: Auch wenn der Scanner theoretisch R == G == B liefert, ist es möglich, dass es bei der JPEG-Kompression einige Pixel gibt, bei denen dies nur fast der Fall ist? Bedenken Sie, dass JPEG ein verlustbehafteter Komprimierungsalgorithmus ist. Vielleicht nimmt sich JPEG einige Freiheiten bei den Farben der nahegelegenen Pixel. Aber ich gestehe, ich bin kein JPEG-Experte. Aber ich würde wissen wollen, wie es funktioniert, bevor ich mich auf R == G == B verlasse.
0 Stimmen
Ja, ich würde mich nur ungern auf genau r==g==b verlassen, denn selbst wenn jpg keine Verfälschungen vornimmt (und ich wette, das tut es), müssten Ihr Scanner und Ihr Original ebenfalls perfekt sein, was ich in vielen Fällen für unwahrscheinlich halte.
0 Stimmen
Das stimmt. Ich hatte nicht an die Pixelabweichungen gedacht (die natürlich beim Scannen auftreten). Interessantes Problem.
1 Stimmen
@Dave: Ich sollte es früher getan haben, aber... heute Morgen in meine Antwort eingefügt ein Code-Snippet, das tatsächlich die höchste Pixel-RGB-Delta eines Bildes zurückgeben wird. Wie Sie das Delta interpretieren, bleibt Ihnen überlassen. Sie können auf 0 (echte und vollständige Graustufen) oder etwas größer als Null testen, um einige Farbinformationen zu berücksichtigen.