Frage

Ich scanne Dokumente auf JPG -Bilder. Der Scanner muss alle Seiten als Farbe oder alle Seiten als Schwarzweiß scannen. Da viele meiner Seiten Farbe haben, muss ich alle Seiten als Farbe scannen. Nachdem das Scannen abgeschlossen ist, möchte ich die Bilder mit .NET untersuchen und versuchen, zu erkennen, welche Bilder schwarz und weiß sind, damit ich diese Bilder in Graustufen umwandeln und speichern kann.

Weiß jemand, wie man ein Graustufenbild mit .NET erkennt?

Lass es mich wissen, bitte.

War es hilfreich?

Lösung

Ein einfacher Algorithmus zum Testen auf Farbe: Gehen Sie das Bildpixel mit Pixel in einer verschachtelten Schleife (Breite und Höhe) und testen Sie, ob die RGB -Werte des Pixels gleich sind. Wenn dies nicht der Fall ist, hat das Bild Farbinformationen. Wenn Sie es ganz durch alle Pixel schaffen, ohne diesen Zustand zu begegnen, haben Sie ein graues Maßstabbild.

Überarbeitung mit einem komplexeren Algorithmus:

In der ersten Drehzahl dieses Beitrags habe ich einen einfachen Algorithmus vorgeschlagen, der davon ausgeht, dass Pixel Graustufen sind, wenn die RGB jedes Pixels gleich sind. Also würden RGBs von 0,0,0 oder 128.128.128 oder 230.230.230 als grau testen, während 123,90,78 dies nicht tun würden. Einfach.

Hier ist ein Codeausschnitt, der eine Abweichung von Gray testet. Die beiden Methoden sind ein kleiner Unterabschnitt eines komplexeren Prozesses, sollten jedoch genügend Rohcode bereitstellen, um die ursprüngliche Frage zu unterstützen.

/// <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);
}

Andere Tipps

Wenn Sie dafür keine Bibliothek finden können, können Sie versuchen, eine große Anzahl (oder alle) der Pixel für ein Bild zu greifen und zu prüfen, ob ihre R-, G- und B -Werte innerhalb eines bestimmten Schwellenwerts liegen (was Sie möglicherweise empirisch festlegen könnten , oder haben als Einstellung) voneinander. Wenn dies der Fall ist, ist das Bild Graustufen.

Ich würde definitiv den Schwellenwert für einen Test etwas größer als 0 machen ... also würde ich zum Beispiel nicht r = g testen, sondern (ABS (RG) <e), wo e Ihr Schwellenwert ist. Auf diese Weise können Sie Ihre falsche Farbe positiv halten ... wie ich vermute, dass Sie sonst eine anständige Nummer erhalten, es sei denn, Ihre Originalbild- und Scan -Techniken geben genau Graustufen.

Ein schnelleres Versión. Test mit einem Schwellenwert von 8. funktionieren gut für meine

Verwenden:

bool grayScale;
Bitmap bmp = new Bitmap(strPath + "\\temp.png");
grayScale = TestGrayScale(bmp, 8);
if (grayScale)
   MessageBox.Show("Grayscale image");


/// <summary>Test a image is in grayscale</summary>
/// <param name="bmp">The bmp to test</param>
/// <param name="threshold">The threshold for maximun color difference</param>
/// <returns>True if is grayscale. False if is color image</returns>
public bool TestGrayScale(Bitmap bmp, int threshold)
{
    Color pixelColor = Color.Empty;
    int rgbDelta;

    for (int x = 0; x < bmp.Width; x++)
    {
        for (int y = 0; y < bmp.Height; y++)
        {
            pixelColor = bmp.GetPixel(x, y);
            rgbDelta = Math.Abs(pixelColor.R - pixelColor.G) + Math.Abs(pixelColor.G - pixelColor.B) + Math.Abs(pixelColor.B - pixelColor.R);
            if (rgbDelta > threshold) return false;
        }
    }
    return true;
}

Hast du einen schnelleren?

Da JPEG für Metadaten unterstützt wird, sollten Sie zunächst überprüfen, ob Ihre Scanner -Software einige spezielle Daten zu gespeicherten Bildern platziert und ob Sie sich auf diese Informationen verlassen können.

Das Antwort Ich habe im Python -Bereich gepostet könnte hilfreich sein. Bilder, die Sie im Internet finden, dass ein Mensch Graustufen häufig nicht identische R-, G-, B -Werte aufweist. Sie benötigen eine Berechnung der Varianz und einer Art Stichprobenprozess, damit Sie keine Million Pixel überprüfen müssen. Die Lösung, die Paul angegeben hat, basiert auf dem maximalen Unterschied, sodass ein einzelnes rotes Pixelartefakt eines Scanners ein Graustufenbild in Nichtgräblingskala verwandeln kann. Die Lösung, die ich veröffentlichte, erhielt 99,1% Präzision und 92,5% erinnern sich auf 13.000 Bilder.

Ich denke, dass dieser Ansatz den geringsten Code erfordern sollte, er wurde auf JPEGs getestet. Bimage unten ist ein Byte -Array.

 MemoryStream ms = new MemoryStream(bImage);
 System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
 if (returnImage.Palette.Flags == 2)
 {
      System.Diagnostics.Debug.WriteLine("Image is greyscale");
 }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top