AWT Farben in Bild ersetzen

mac21

Aktives Mitglied
Hallo,

ich stieß durch die SuFu (ja, hab sie wirklich benutzt ;) )
auf folgenden, alten Thread:
Farbe im Bild ersetzen

Habe den Code rauskopiert, und abgeändert, wie in Post #8 von tuxedo vorgeschlagen.
Folgender Code ersetzt alle Farben (außer schwarz, graustufen) durch weiß, sodass ein schwarzer Text vom farbigen Hintergrund befreit wird.

Code:
package colorSwap;

import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;


class ColorReplaceLookupTable extends LookupTable
{
    int faktor;
    private Color srcColor;
    private Color dstColor;

    public ColorReplaceLookupTable(Color srcColor, Color dstColor)
    {
        super(0,1);
        faktor = 150;
        this.srcColor = srcColor;
        this.dstColor = dstColor;
    }
    public int[] lookupPixel(int[] src, int[] dest)
    {
        if ((src[0] >= srcColor.getRed()-faktor && src[0] <= srcColor.getRed()+faktor) &&
            (src[1] >= srcColor.getGreen()-faktor && src[1] <= srcColor.getGreen()+faktor) &&
            (src[2] >= srcColor.getBlue()-faktor && src[2] <= srcColor.getBlue()+faktor))
        { }else{
            src[0] = dstColor.getRed();
            src[1] = dstColor.getGreen();
            src[2] = dstColor.getBlue();
        }
        return src;
    }



    public static void main(String args[]) throws Exception
    {
        BufferedImage img = ImageIO.read(new File("C://colorswap.jpg"));
        BufferedImage image = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
        image.getGraphics().drawImage(img, 0, 0, null);
        BufferedImageOp convertOp = new LookupOp(new ColorReplaceLookupTable(Color.BLACK, Color.WHITE), null);
        BufferedImage convertedImage = convertOp.filter(image, null );
        ImageIO.write(convertedImage, "jpg", new File("C://afterSwap.jpg"));
    }
}

den Wert für Faktor (ich weiß, dieser Variablenname ist schlecht gewählt) habe ich durch experimentieren auf 150 gesetzt.
Das Ergebnis ist okay, aber nicht optimal...

Mein Gedanke war:
Schwarz hat ja den RGB-Wert 0/0/0
Farbcodes - nützlich
und die angegebene Graustufen zwischen 0/0/0 und ~200/200/200

Passe ich nun die oben genannte Methode an auf folgendes:
Code:
 public int[] lookupPixel(int[] src, int[] dest)
    {
        if (src[0] <= 200 &&
            src[1] <= 200 &&
            src[2] <= 200)
        { }else{
            src[0] = dstColor.getRed();
            src[1] = dstColor.getGreen();
            src[2] = dstColor.getBlue();
        }
        return src;
    }

So werden auch teilweise Grüntöne im Bild belassen.
Logisch, weil zb: "Darkgreen" mit 0/100/0 in mein Muster passt.

Mein Kopf raucht... wie kann ich die r-, g- und b-Werte so einschränken, dass nur Schwarz/-Grautöne im Bild belassen werden?

Vielen Dank schon einmal
 

anti-held

Bekanntes Mitglied
Im Grunde ist Grau immer so, dass die Werte für Rot, Gelb und Blau nahezu gleich sind.
Also solltest du auf darauf überprüfen und noch dazu einen Threshold (wie bei dir der Faktor) einsetzen, um helle Grautöne bis Weiß wegzuschneiden.
 

mac21

Aktives Mitglied
Hallo anti-held,

genau so dachte ich mir das ja, Grautöne bestehen aus RGB(x=x=x).

ich habe den Code noch einmal geändert:
Das Programm lässt nun "NUR" die Töne mit GENAU den gleichen Werten für R, G und B im Bild,
das Ergebnis sieht so aus: farben.jpg

Wie kann ich das mit dem Treshold lösen?
Im Endeffekt müssen ja alle Töne, die identische R-, G- und B-Werte haben, und "ähnliche" Farbtöne belassen werden.

ColorReplaceLookupTable.java:
Java:
package colorSwap;

import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;


class ColorReplaceLookupTable extends LookupTable
{

    private Color srcColor;
    private Color dstColor;

    public ColorReplaceLookupTable(Color srcColor, Color dstColor)
    {
        super(0,1);
        this.srcColor = srcColor;
        this.dstColor = dstColor;
    }
      
 public int[] lookupPixel(int[] src, int[] dest)
    {
        if (
            (src[0] == src[1]) &&
            (src[1] == src[2]) &&
            (src[2] == src[0])
            )
        { }else{
            src[0] = dstColor.getRed();
            src[1] = dstColor.getGreen();
            src[2] = dstColor.getBlue();
        }
        return src;
    }


    public static void main(String args[]) throws Exception
    {
        BufferedImage img = ImageIO.read(new File("C://colorswap.jpg"));
        BufferedImage image = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
        image.getGraphics().drawImage(img, 0, 0, null);
        BufferedImageOp convertOp = new LookupOp(new ColorReplaceLookupTable(Color.BLACK, Color.WHITE), null);
        BufferedImage convertedImage = convertOp.filter(image, null );
        ImageIO.write(convertedImage, "jpg", new File("C://afterSwap.jpg"));
    }
}
 
Zuletzt bearbeitet:

anti-held

Bekanntes Mitglied
Dass die Werte für rgb alle genau gleich sind ist ja ich nur ein Sonderfall!
Versuche es doch damit, den Mittelwert zu bilden und zu überprüfen, ob alle Werte im Bereich von +-10 sind z.B.
Also wie oben erwähnt "nahezu gleich".
Und dann kannst du für dein Bild diesen Wert (10) so erhöhen oder verringern, bis das Ergebnis am besten ist.
 

mac21

Aktives Mitglied
Nachtrag: Hintergrund des ganzen ist folgendes Projekt:
Thread #162222

Das Problem, auf das ich stoße, wenn ich experimentiere mit den Farbwerten:
auf dem Fahrzeugschein gibt es einen mehrfarbigen Hintergrund, mit roten und grünen Farbtönen.
Diese wegzuschneiden wäre ja nun nicht sooooo schwer, das Problem ist ja:
Die farbigen Linien im Hintergrund "kreuzen" die schwarzen Texte, schneide ich die Farbtöne weg, so entsteht eine Frakturschrift, die kaum ein OCR-Programm richtig deuten kann.
siehe Bild: aaaa.jpg
 
Zuletzt bearbeitet:

mac21

Aktives Mitglied
@anti-held:

das habe ich durch folgende Funktion versucht:

Java:
 public int[] lookupPixel(int[] src, int[] dest)
    { int treshold = 20;
        if (
        		(
        				(src[0] == src[1]) &&
        			(src[1] == src[2]) &&
        			(src[2] == src[0])
        		)
        		||
        		(
        			((src[0] >= src[1]-treshold) && (src[0] <= src[1]+treshold)) &&
        			((src[1] >= src[2]-treshold) && (src[1] <= src[2]+treshold)) &&
        			((src[2] >= src[0]-treshold) && (src[2] <= src[0]+treshold))
        		)
        	)	
        { }else{
            src[0] = dstColor.getRed();
            src[1] = dstColor.getGreen();
            src[2] = dstColor.getBlue();
        }
        return src;
    }

Ergebnis bei (ja ich weiß, die sind unzensiert...)
10:
Anhang anzeigen 6847
15:
Anhang anzeigen 6848
20:
Anhang anzeigen 6849

Alle 3 Ergebnisse unbrauchbar, 20 ist schon wieder "zu grün"
 
Zuletzt bearbeitet:

anti-held

Bekanntes Mitglied
Leider kann ich deine Anhänge nicht sehen. idky

Dein Code ist so unübersichtlich.
Verwende doch mal so etwas:
Java:
	private static boolean isIn(int min, int max, int value){
		return value >= min && value <= max;
	}
	
	public static void main(String[] args) {

		int[] src = new int[3];
		int[] dest = new int[3];
		
		int threhold = 200;
		int difference = 10;
		int average = (src[0]+src[1]+src[2])/3;
		int max = average + difference;
		int min = average - difference;
		
		 if (threshold >= average && isIn(min, max, src[0]) && isIn(min,max,src[1]) && isIn(min, max, src[2])) {
			 dest[0] = src[0];
			 dest[1] = src[1];
			 dest[2] = src[2];
		 }

kann das so nicht testen...
Eine andere Lösung fällt mir leider auch nicht ein.
 
Zuletzt bearbeitet:

mac21

Aktives Mitglied
Danke für die Idee,
mal sehen, ob ich das nachvollziehen kann.
Threshold setzt einen Schwellenwert für den R- bzw. G- bzw. B-Wert auf 200.
difference ist die schwankung +-10
average ist klar, min und max auch.

da ich das ganze in die Methode "lookupPixel" gebaut habe, prüft er das ganze für jeden einzelnen Pixel.
liegt der farbdurchschnitt des pixels über 200, und liegen die R-, G- und B-Werte zwischen min und max, so wird
"die Farbe" dest durch "die Farbe" src ersetzt.
Das Array dest gebe ich dann zurück.

Java:
     public int[] lookupPixel(int[] src, int[] dest)
    {
    	int threshold = 200;
		int difference = 50;
		int average = (src[0]+src[1]+src[2])/3;
		int max = average + difference;
		int min = average - difference;
 
		 if (threshold >= average && isIn(min, max, src[0]) && isIn(min,max,src[1]) && isIn(min, max, src[2])) {
			 dest[0] = src[0];
			 dest[1] = src[1];
			 dest[2] = src[2];
		 }
		 else{
			 dest[0] = 255; //
			 dest[1] = 255; // --> Ergibt Weiß
			 dest[2] = 255; //
		 }
    	return dest;
    }

Problem: egal welchen Threshold und welche difference ich auch setze, das Ergebnis wird eine Frakturschrift, welche nicht gelesen werden kann.
 
Zuletzt bearbeitet:

anti-held

Bekanntes Mitglied
Die letzte Möglichkeit, die mir momentan noch einfällt wäre, iterativ in kleinen Stufen die Pixelfarben an Grau anzunähern, bis ein lesbarer Text entsteht.

1. Schritt, mit der oberen Methode testen, ob ein lesbarer Text entsteht. -> falls ja -> fertig
-> falls nicht: 2. Schritt, alle Pixel des Bildes (vor dem Entfernen der Farben), um einen kleinen Wert an Grau anzunähern (die RGB Werte sollen sich nähern)
Wiederholen ab Schritt 1
 

mac21

Aktives Mitglied
Das würde ich sehr gerne versuchen, evtl. reicht da ja schon.
Nur folgende Frage habe ich dazu:
"bis ein lesbarer Text entsteht", wie sollte ich das überprüfen?
Manuell ist schlecht... stell dir vor, ich habe einen Button, der die Farbwerte bei jedem Klick ein wenig an grau annähert.
Dann muss man im schlimmsten Fall hundertfach klicken, zwischen drin jedes mal die Texterkennung ausführen.

Das Programm kann ja nicht überprüfen, ob ein "lesbarer" Text vorliegt.
FALLS die Tess4J-Api aus einem gescannten Bereich einfach einen leeren String liefern würde, so könnte ich sagen:
"Das ist nicht lesbar (da String = "") --> erneuter Durchgang".

"Leider" erkennt Tesseract immer etwas...
und sei es aus "Nissan" --> "N´.-,.,-a#"
 

mac21

Aktives Mitglied
Naja dein Vorschlag war spitze, bin dir sehr dankbar für die Hilfe.

Es scheitert dabei an Tesseract...
Es GIBT so eine Software, "regisoft public", mit einem Zusatzmodul "Scan-Lösung für KFZ-Zulassungsstellen".
Mit einem Millionenbudget und hunderten hochqualifizierten Programmierern mit Kenntnissen in vielen Sprachen wäre das bestimmt möglich.

Problem ist nur, dass dieses Projekt meine Abschlussarbeit der FI/AE-Ausbildung werden soll.
Laut meinem Ausbilder...
scheint aber seeeehr knifflig für einen Azubi

Danke dennoch für die Hilfe!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T AWT Farben in einem Bild ändern AWT, Swing, JavaFX & SWT 8
B Bild bearbeiten mit Transparenz (spiegeln, Farben austauschen) AWT, Swing, JavaFX & SWT 8
W JavaFX Farben dynamisch anpassen AWT, Swing, JavaFX & SWT 4
L JavaFX Fehler beim setzen von Farben AWT, Swing, JavaFX & SWT 16
J AWT System Farben / java.awt.SystemColor funktioniert nicht AWT, Swing, JavaFX & SWT 4
M UIManager funktioniert nicht mit Farben AWT, Swing, JavaFX & SWT 9
M Swing UIManager funktioniert nicht mit Farben AWT, Swing, JavaFX & SWT 0
O keine ähnliche Farben durch Random in Java AWT, Swing, JavaFX & SWT 21
E JTable farben ändern AWT, Swing, JavaFX & SWT 2
T Kontrast zweier Farben vergleichen AWT, Swing, JavaFX & SWT 5
J Auf die im Look and Feel eingestellten Farben zugreifen AWT, Swing, JavaFX & SWT 2
M Swing Zweidimensionales Array mit Farben erzeugen AWT, Swing, JavaFX & SWT 16
A AWT HSB-Farben dynamisch berechnen AWT, Swing, JavaFX & SWT 5
C JTable: Mehrere Farben in einer Zelle darstellen AWT, Swing, JavaFX & SWT 10
T bei einem jtextfield Farben benutzen AWT, Swing, JavaFX & SWT 7
K Farben in JMenues AWT, Swing, JavaFX & SWT 2
K Farben bei JMenus AWT, Swing, JavaFX & SWT 5
D Farben JList AWT, Swing, JavaFX & SWT 4
F Farben in Textpane AWT, Swing, JavaFX & SWT 14
S Farben eienr JTextPane dynamisch zuweisen AWT, Swing, JavaFX & SWT 2
D ComboBox mit Farben aus java.awt.color AWT, Swing, JavaFX & SWT 4
T Die Schrift in verschiedenen Farben blinken zu lassen AWT, Swing, JavaFX & SWT 2
G Knoten im Jtree mit unterscheidlichen Farben darstellen AWT, Swing, JavaFX & SWT 5
T verschiedene Farben in einem Text/Editfeld AWT, Swing, JavaFX & SWT 11
C Farben in BufferedImage ändern ? AWT, Swing, JavaFX & SWT 2
V Farben setzen bei einigen Komponenten (JScrollBar, . AWT, Swing, JavaFX & SWT 3
M Farben im TextArea AWT, Swing, JavaFX & SWT 5
T extends JButton übernehmen Farben AWT, Swing, JavaFX & SWT 4
S RGB Farben addieren AWT, Swing, JavaFX & SWT 1
B JList Zeilen in verschiedenen Farben markieren. AWT, Swing, JavaFX & SWT 3
K JTextArea mit verschiedenen Farben betreiben [Chat] AWT, Swing, JavaFX & SWT 3
G JTextArea.append() in verschiedenen Farben AWT, Swing, JavaFX & SWT 2
M Image: Kontrast, Helligkeit und Farben ändern? AWT, Swing, JavaFX & SWT 15
Icewind Verschiedene Farben in einer JTextArea AWT, Swing, JavaFX & SWT 3
W Editor Syntax Farben AWT, Swing, JavaFX & SWT 2
R Farben ändern AWT, Swing, JavaFX & SWT 2
M JavaFX Mandelbrot-bild noch nicht optimiert AWT, Swing, JavaFX & SWT 7
berserkerdq2 Wie füge ich ein Bild in javafx mit dem Scenebuilder ein, das automatisch mitgezogen wird, wenn das Fenster vergrößert wird oder Vollbildmodus AWT, Swing, JavaFX & SWT 6
frager2345 Bild aus Dateien lesen und als Hintergrund verwenden AWT, Swing, JavaFX & SWT 2
T Bild in ein graphics füllen AWT, Swing, JavaFX & SWT 2
N imageIcon zeigt kein Bild an AWT, Swing, JavaFX & SWT 5
B Bild lädt nicht AWT, Swing, JavaFX & SWT 2
izoards Bild ausdrucken - PageFormat setzen geht nicht AWT, Swing, JavaFX & SWT 5
M Bild wird nicht geladen obwohl sie gefunden wird AWT, Swing, JavaFX & SWT 0
V JavaFX Bild leer und keine Fehlermeldung AWT, Swing, JavaFX & SWT 21
D JavaFX Bearbeitetes Bild wird nicht gespeichert AWT, Swing, JavaFX & SWT 9
D JavaFX Größe des Bild an ImageView anpassen AWT, Swing, JavaFX & SWT 3
M Bewegtes Bild im BorderLayout.CENTER AWT, Swing, JavaFX & SWT 6
C Falschfarbenbild (lineare Grauwertspreizung)aus Grauwert-Bild erstellen AWT, Swing, JavaFX & SWT 15
C Kleineres Bild an bestimmte Koordinaten setzen AWT, Swing, JavaFX & SWT 6
S Bild neu skalieren - Bild in Bild speichern? AWT, Swing, JavaFX & SWT 6
N Bild Drehen AWT, Swing, JavaFX & SWT 1
Hatsi09 Swing JPanel Bild einfügen AWT, Swing, JavaFX & SWT 14
J Bild von anderer Klasse will nicht laden AWT, Swing, JavaFX & SWT 1
M JavaFX Bild zur ImageView in einem Kreis anzeigen. AWT, Swing, JavaFX & SWT 4
T JFrame Bild einfügen AWT, Swing, JavaFX & SWT 9
M Combobox bild anklicken AWT, Swing, JavaFX & SWT 2
cool_brivk24 Swing ImageIcon lädt kein Bild AWT, Swing, JavaFX & SWT 12
L Bild nicht in der Mitte AWT, Swing, JavaFX & SWT 16
B JavaFX Bild um die eigene Achse drehen lassen AWT, Swing, JavaFX & SWT 0
J Swing Bild in Button AWT, Swing, JavaFX & SWT 11
I Bild über FXML (ImageView, Image) anzeigen AWT, Swing, JavaFX & SWT 1
T Image Loader lädt Bild nicht AWT, Swing, JavaFX & SWT 10
stroggi Swing Mehrere transparentes Objekte (Grafiken) über einem Bild (JLabel) darstellen AWT, Swing, JavaFX & SWT 4
P Kein Bild wird angezeigt bei ImageIcon AWT, Swing, JavaFX & SWT 16
T JavaFX Bild in Tabellenzelle AWT, Swing, JavaFX & SWT 2
Ksanatos Swing Bild (.jpg) einlesen und per Button wechseln AWT, Swing, JavaFX & SWT 9
S JPanel rotieren, Bild ist abgeschnitten, Clipping? AWT, Swing, JavaFX & SWT 0
MaxG. Swing Bild Button AWT, Swing, JavaFX & SWT 7
P Swing Bild Skallieren AWT, Swing, JavaFX & SWT 1
P Jframe Bild einfügen, Hintergrund Farbe ändern, und Button schrift Größe ändern AWT, Swing, JavaFX & SWT 2
A Swing Bild wird nicht mehr geladen AWT, Swing, JavaFX & SWT 4
A Swing Gemaltes Bild über saveDialog speichern unter AWT, Swing, JavaFX & SWT 15
R 2D-Grafik PNG Bild per Graphics auf JPanel AWT, Swing, JavaFX & SWT 9
S Bild mit ImageIcon auf GUI verkleinern AWT, Swing, JavaFX & SWT 3
I JFrame Bild strecken und auf Bildschirmgröße anpassen AWT, Swing, JavaFX & SWT 2
F Gezeichnetes als bild speichern AWT, Swing, JavaFX & SWT 4
B 2D-Grafik Bild farblich filtern AWT, Swing, JavaFX & SWT 2
B JavaFX ImageView neues Bild zuweisen AWT, Swing, JavaFX & SWT 19
A 2D-Grafik Bild wird nicht neu gezeichnet AWT, Swing, JavaFX & SWT 24
K Bild in JFrame AWT, Swing, JavaFX & SWT 2
S JavaFX Teil eines Bildes ausschneiden / als neues Bild nutzen AWT, Swing, JavaFX & SWT 8
B Swing Unterteiltes JFrame mit Bild in der Mitte AWT, Swing, JavaFX & SWT 4
I Applet BlueJ Applet - Bild mit if-Schleife zeichnen lassen AWT, Swing, JavaFX & SWT 16
Z Bildervorschau, MouseDragged das Bild verschieben AWT, Swing, JavaFX & SWT 1
M JavaFX Ein Bild ohne Rahmen fällt runter? AWT, Swing, JavaFX & SWT 2
G Anonyme Instanz von JXImageView erstellen und mit Bild initialisieren AWT, Swing, JavaFX & SWT 7
A JPanel Bild laden (Porblem mit Dateipfad) AWT, Swing, JavaFX & SWT 2
M JavaFX - Bild in Jar einbinden, sodass es auch außerhalb der IDE geladen wird. AWT, Swing, JavaFX & SWT 2
M Bild Beschreibung mit ImageIO speichern AWT, Swing, JavaFX & SWT 1
M "ImageIO.read()" liest Bild nicht richtig ein AWT, Swing, JavaFX & SWT 3
I Swing JLabel Bild für 1sec anzeigen lassen AWT, Swing, JavaFX & SWT 13
K Bild in Label wird nicht angezeigt AWT, Swing, JavaFX & SWT 5
C GUI öfters durchlaufen und hinterher Bild speichern AWT, Swing, JavaFX & SWT 1
E JavaFX Bild einfügen AWT, Swing, JavaFX & SWT 6
G paintComponents zerstückelt Bild AWT, Swing, JavaFX & SWT 0
C 2D Grafik ein Bild soll permanent durchlaufen AWT, Swing, JavaFX & SWT 2
1 Textfield: jede Buchstabe ein Bild AWT, Swing, JavaFX & SWT 2
C Bild Koordinaten AWT, Swing, JavaFX & SWT 6
M Bild aus JLabel resizen und speichern AWT, Swing, JavaFX & SWT 0

Ähnliche Java Themen

Neue Themen


Oben