Dieser Artikel beschreibt den Beispielcode von Java, um die Hauptfarbe in einem Farbbild zu erhalten. Teilen Sie es für Ihre Referenz wie folgt weiter:
1: Grundlegende Ideen
Für ein Farbbild im RGB -Farbraum möchten wir viele Male über das Programm mehrere Hauptfarben des Bildes erhalten. Bei allgemeinen Bildern wird jedoch an der Farbübergang Pixelmischung erreicht. Daher kann das direkte Scannen der Pixelwerte des Bildes zu Hunderten verschiedener Farbwerte führen. Tatsächlich kann das Bild nur 3 bis 4 Hauptfarben haben. So entfernen Sie diese gemischten Farben und extrahieren die Hauptfarben dieser 3 bis 4 genau. Gemäß den Eigenschaften des allgemeinen Bildes kann das Bild nicht unterschiedliche Farbwerte an der Grenze derselben Farbe mischen, kann als eine der Kanteneigenschaften des Bildes angesehen werden. Daher kann der Extrakt dieser gemischten Pixel gemäß einem einfachen Kantengradientenalgorithmus erreicht werden, um das Ausgangspixelwert -Array zu erhalten und dann jeden Pixelwert zu scannen, um nach den Pixeln um den angegebenen Radius -Parameter R zu suchen und Null zu finden, und der Wert des Pixelpunkts, der dem Mitte -Pixel als Pixel -Wert verwendet wird, wird als Pixel -Wert verwendet. Nach Abschluss des Scans kann das Pixelarray ausgegeben werden und dann kann das Array linear gescannt werden, um den Hauptfarb -RGB -Wert des Bildes zu erhalten.
Zwei: Implementierungsschritte
1. Geben Sie ein Bild -Array ein, um das Farbbild zu graut.
2. Berechnen Sie für das Graustufenbild den Bildgradienten und verwenden Sie hier den Sobol -Operator.
3. Für jeden Pixelpunkt ungleich Null scannen Sie im Bereich des Radius R und finden Sie den nächsten ursprünglichen Pixelwert von Null;
4. Scannen Sie einfach das erhaltene Array, um die Hauptfarbe zu erhalten.
Der Parameter R besteht darin, den am besten geeigneten Wert gemäß verschiedenen Anwendungsszenarien zu finden. Theoretisch, je größer das Bild ist, desto größer ist der Wert von R, andernfalls ist der Algorithmus ungenau.
Drei: Originalbild und Betriebseffekt
Originalbild
Nach dem Laufen des Algorithmus werden vier Hauptfarben extrahiert
Vier: Quellcode für Algorithmus -Implementierung
public static bufferedImage removeBlendpixel (bufferedImage Bild, int raidus) {int width = image.getWidth (); int height = image.getheight (); int [] pixels = new int [width * Höhe]; getrgb (Bild, 0, 0, Breite, Höhe, Pixel); // Verarbeitungsergebnis erstellen erstellen buffeedImage resultimg = createCompatibledStimage (Bild, NULL); setRGB (Ergebnis, 0, 0, Breite, Höhe, Pixel); // Verarbeitungsergebnis erstellen erstellen buffeedImage resultimg = createCompatibledStimage (Bild, NULL); setRGB (Ergebnis, 0, 0, Breite, Höhe, Pixel); // Graustufen- und Gradienten -Byte [] Graydata = getGrayData (Pixel, Breite, Höhe); Byte [] BinaryData = getGrident (Graydata, Breite, Höhe); int index = 0; für (int row = 1; Zeile <Höhe - 1; Zeile ++) {für (int col = 1; col <width - 1; col ++) {index = row * width+col; int pixel = (binaryData [index] & 0xff); if (pixel> 0) {// radius scan operation int mindis = integer.max_value; int minrow = -1; int mincol = -1; int nr = 0; int nc = 0; int index2 = 0; für (int subrow = -raidus; subrow <= raidus; subrow ++) {nr = row+subrow; if (nr <0 || nr> = Höhe) {Fortsetzung; } für (int subcol = -raidus; subcol <= raidus; subcol ++) {nc = col+subcol; if (nc <0 || nc> = width) {Fortsetzung; } index2 = nr * width + nc; int value = (binaryData [index2] & 0xff); if (value == 0) {int distance = distanceColor (image.getRGB (nc, nr), image.getRGB (col, row)); if (distanz <mindis) {mindis = distanz; minrow = nr; Mincol = NC; }}}} resultimg.setrgb (col, row, image.getRGB (mincol, minrow)); }}} return resultimg; } public static int distanceColor (int rgb, int rgb2) {// farbene ein int r1 = (rgb >> 16) & 0xff; int g1 = (rgb >> 8) & 0xff; int b1 = rgb & 0xff; // Färben Sie zwei int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; // Entfernung int rr = r1 - r2; int gg = g1 - g2; int bb = b1 - b2; int sum = (int) math.sqrt (rr * rr + gg * gg + bb * bb); Rückgabesumme; } public static byte [] getGrayData (int [] Inpixel, int width, int height) {// Bildgrauskalte Byte [] outpixels = new Byte [Breite * Höhe]; int index = 0; für (int row = 0; Zeile <Höhe; Zeile ++) {int tr = 0, tg = 0, tb = 0; für (int col = 0; col <width; col ++) {index = row * width+col; Tr = (Inpixel [Index] >> 16) & 0xff; tg = (Inpixel [index] >> 8) & 0xff; TB = Inpixel [Index] & 0xff; int grau = (int) (0,299 * tr + 0,587 * TG + 0,114 * TB); Outpixel [index] = (byte) (grau & 0xff); }} return -Überpixel; } public static byte [] getGrident (Byte [] Inpixel, int width, inthohe) {byte [] outpixels = new Byte [Breite * Höhe]; int index = 0; für (int row = 0; Zeile <Höhe; Zeile ++) {int tr = 0; für (int col = 0; col <width; col ++) {if (row == 0 || col == 0 || (row == Höhe - 1) || (col == width - 1)) {index = row * width+col; Outpixel [index] = (byte) (0x00); weitermachen; } int xg = 0, yg = 0; für (int sr = -1; sr <= 1; sr ++) {für (int sc = -1; sc <= 1; sc ++) {int nRow = row+sr; int ncol = col + sc; if (nrow <0 || nrow> = Höhe) {nrow = 0; } if (ncol <0 || ncol> = width) {ncol = 0; } index = nrow * width + ncol; TR = (Inpixel [Index] & 0xff); xg + = x_sobel [sr + 1] [sc + 1] * tr; yg + = y_sobel [sr + 1] [sc + 1] * tr; }} index = row * width + col; int g = (int) math.sqrt (xg * xg + yg * yg); Outpixel [index] = (byte) (clamp (g) & 0xff); }} return -Überpixel; } Die konstanten Werte, die definiert werden müssen, sind wie folgt:
public static final int [] [] x_sobel = new int [] [] {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}; public static final int [] [] y_sobel = new int [] [] {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; public static final int block_pixel_radius = 5; Die Gradientenerfassung verwendet den Sobol -Operator. Der Code zum Scannen des BufferedImage -Objekts nach der Verarbeitung, um die Hauptfarbe zu erhalten, lautet wie folgt:
int width = result.getWidth (); int Höhe = result.getheight (); Karte <Integer, Integer> colorIndexmap = new Hashmap <Integer, Integer> (); für (int row = 0; Zeile <Höhe; Zeile ++) {für (int col = 0; col <width; col ++) {int pixelvalue = result.getRGB (col, row); if (! colorIndexmap.containsKey (pixelvalue)) {colorIndexmap.put (pixelvalue, pixelvalue); }}} // jetzt pixel value // result system.out.println ("Anzahl von color =" + colorIndexmap.size ()) scannen; return colorIndexmap.Keyset (). TOARRAY (New Integer [0]); Der Testcode lautet wie folgt:
public static void main (String [] args) {Datei file = new File ("d: //gloomyfish//bigmonkey.png"); Datei resultFile = neue Datei ("d: //gloomyfish//result.png"); try {bufferedImage image = imageio.read (Datei); Bufferedimage result = removeBlendpixel (Bild, block_pixel_radius); Imageio.Write (Ergebnis, "PNG", resultFile); Integer [] Farben = ExtractColors (Ergebnis); System.out.println ("Gesamtfarben:" + colors.length); } catch (ioException e) {e.printstacktrace (); }}Hinweis: Der Hauptschlüssel besteht darin, die richtige Größe des zu verarbeitenden Bildes einzugeben. Diese Radiusgröße hängt mit der tatsächlichen Größe des Bildes zusammen, und der Algorithmus kann noch einen Schritt weiter in eine Version optimiert werden, die nicht vom Radius -Parameter abhängt, bis Sie ein Pixel gleich Null finden.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.