java-forum.org - Java programmieren aus Leidenschaft
Java 6 Einstieg und professioneller Einsatz
Alter Preis: 34,90 EUR
Jetzt: 0,00 EUR

zzgl. Versandkosten

Zurück   java-forum.org - Java programmieren aus Leidenschaft > Java - Programmierung > Allgemeine Java-Themen

Allgemeine Java-Themen Allgemeine Themen, die nicht in andere Fachforen und nicht zu den Java Basics passen

Thema geschlossen    
Themen-Optionen Thema durchsuchen Ansicht
Alt 07.10.2009, 12:31   #1 (permalink)
Stammbenutzer
Kilobyte
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Standard Barcodes in Bild erkennen

Hallo,

zu dem Geburtstag vom Barcode (siehe Google-Logo: http://www.google.de/logos/barcode09.gif) habe ich auch eine Frage, die Barcode betrifft:

Wie kann ich einen Barcode auf einem Bild finden? Das Auslesen des Barcodes ist eine andere Sache, um die man sich kümmern muss, sobald man erst einmal einen Barcode gefunden hat. Super wäre es, wenn man dann nur noch einen Ausschnitt des Bildes hätte; dann kann man den Barcode aus diesem "Scannerstreifen" auslesen - wäre super. Hier noch ein Beispiel:


Das zu erkennende Bild.


Es wurde der Barcode erkannt und nur ein Streifen herausgefiltert.

Aber wie ich den Barcode am Besten aus einem Bild erkenne, ist mir zweifelhaft ....

Vielen Dank für's lesen,
data89
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 07.10.2009, 12:43   #2 (permalink)
Stammbenutzer
Viertel Megabyte
 
Benutzerbild von Geeeee
 
Registriert seit: 17.02.2009
Fachbeiträge: 484
Abgegebene Danke: 4
Erhielt 24 Danke für 23 Beiträge
Über Korrelation könnte man die Elemente herausfinden. Natürlich müsste man dann noch die einzelnen Bars auslesen, wenn man sie eingegrenzt hat. Stelle mir da einen schönen Umfang vor
Leider kann ich gerade deine Bilder nicht sehen (proxy) und schauen was du da gezeigt hast.
__________________
KirbyDance
<(*.*<) <(*.*<) ^(*.*)^ ^(*.*)^ (>*.*)> (>*.*)>
Geeeee ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 07.10.2009, 14:02   #3 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Wie machen die das hier: ||| | ||| | || CODECHECK.INFO : Login

Es gibt einen Bereich, in dem der Strichcode ist. Drin wird er erkannt. Aber was ist die Logik dahinter?
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 07.10.2009, 15:16   #4 (permalink)
Stammbenutzer
CD-R 74
 
Benutzerbild von ARadauer
 
Registriert seit: 16.09.2006
Fachbeiträge: 6.762
Abgegebene Danke: 28
Erhielt 529 Danke für 496 Beiträge
Wie viel Erfahrung hast du mit Bildverarbeitung?

Ich würds mal mit dem einfachen Erkennen der senkrechten Linien versuchen. Also mit einfacher Kantenerkennung kommt man sicher schon weit.

Wenn nicht, mal ein paar mal ein Opening und Closing anwenden und mal schaun, was man mit Korrelation findet...
__________________
Welches ist das beste Buch für Anfänger? Das: Java von Kopf bis Fuss
Nach den ersten Schritten? Das: Der Weg zum Java-Profi
ARadauer ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 07.10.2009, 15:19   #5 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Zitat: ARadauer
Beitrag anzeigen
Wie viel Erfahrung hast du mit Bildverarbeitung?
Ich habe mich bereits erfolgreich mit der Erkennung von Gesten von Personen beschäftigt. D.h. Positionsbestimmung der Hände und des Kopfes, Dreieck durchgelegt und erkannt, wenn eine Hand oder so gehoben wird ...

Zitat: ARadauer
Beitrag anzeigen
Ich würds mal mit dem einfachen Erkennen der senkrechten Linien versuchen. Also mit einfacher Kantenerkennung kommt man sicher schon weit.
Höre ich immer wieder, aber hab immer noch nicht wirklich verstanden was das ist. Bei meinem ersten (und einizigen Projekt; Erkennung von Gesten) habe ich einfach nur die Hautfarbenen Pixel rausgefischt und dann Punktwolken zusammengefasst, die dann die Punkte waren.

Wer googeln kann ist klar im Vorteil - hab rausgefunden was es bedeutet!

Zitat: ARadauer
Beitrag anzeigen
Wenn nicht, mal ein paar mal ein Opening und Closing anwenden und mal schaun, was man mit Korrelation findet...
Was ist das?

Danke,
data89

Geändert von data89 (07.10.2009 um 15:30 Uhr) Grund: Kantenerkennung, Sobel erarbeitet
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 07.10.2009, 20:28   #6 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Anbei findet Ihr einen Versuch, der jedoch nicht funktioniert! Es kommt irgend ein wirrer Kram raus. Grundidee: Alle Farbwerte für jede Spalte mitteln und daraus eine "Linie" erstellen. Dann abgrenzen was ausgefüllt und was nicht ausgefüllt ist und in ein boolean-Array schreiben. Dann daraus die 43 Blöcke extrahieren, anhand der Prüfgruppen (Anfang, Mitte, Ende) die Breite vom weißen Bereich für 1 LE bestimmen und auf die anderen 8 Gruppen (mit jeweils 4 Blöcken) anwenden und die Zahl nach schauen.

Wie kann man das besser machen?

Irgendwie bin ich von diesem Scanner http://www.codecheck.info/images/Scanner.swf fasiziert! Der liest ja wirklich viele EAN-8 Codes ein ... das gibt's ja gar nicht ( - doch bei Roller .... das war was anderes )
Wie funktioniert der wohl?

Danke für Eure Hilfe vorab,
beste Grüße,
data89

P.S.: Achso, ich arbeite mit EAN-8.
Angehängte Dateien
Dateityp: txt Scan.txt (10,8 KB, 9x aufgerufen)
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 07.10.2009, 20:38   #7 (permalink)
Stammbenutzer
Megabyte
 
Benutzerbild von mogel
 
Registriert seit: 04.12.2007
Fachbeiträge: 1.045
Abgegebene Danke: 57
Erhielt 56 Danke für 54 Beiträge
prinzipell sollte nur der Barcode auf dem Bild sein ... pauschal ein Binärfilter verwenden ... dann kannst Du mittig auf Y anfangen und X durchlaufen bis Du einen Punkt erwischt hast ... nur erstellst Du von dem Punkt aus eine Punktwolke ... über diese Punktwolke erstellst Du eine Regressionsgerade ... anhand dieser Gerade kannst Du das Bild drehen das es korrekt ausgerichtet ist ... nun kannst Du den Barcode auslesen
__________________
http://www.fantasya-pbem.de - Fantasy-Multiplayer-Strategie - Runden basiert - Twitter
Rechtschreibfehler unterliegen der LGPL - Semantikfehler stehen unter AGPL
mogel ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 07:03   #8 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Aber wie werde ich die einzelnen Graustufen los? Ich muss ja die richtigen Abstände einlesen!
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 07:51   #9 (permalink)
Stammbenutzer
Megabyte
 
Benutzerbild von mogel
 
Registriert seit: 04.12.2007
Fachbeiträge: 1.045
Abgegebene Danke: 57
Erhielt 56 Danke für 54 Beiträge
Zitat: data89
Beitrag anzeigen
Ich habe mich bereits erfolgreich mit der Erkennung von Gesten von Personen beschäftigt.
die Aussage wiederspricht sich mit

Zitat: data89
Beitrag anzeigen
Aber wie werde ich die einzelnen Graustufen los? Ich muss ja die richtigen Abstände einlesen!
die Fehlen da einfache Grundlagen ... eine Hand zu erkennen ist schon der etwas gehobenere Ansatz ... werde mich aber nochmal selber Quoten

Zitat: mogel
Beitrag anzeigen
... pauschal ein Binärfilter verwenden ...
vieleicht hilfts, mogel
__________________
http://www.fantasya-pbem.de - Fantasy-Multiplayer-Strategie - Runden basiert - Twitter
Rechtschreibfehler unterliegen der LGPL - Semantikfehler stehen unter AGPL
mogel ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 08:48   #10 (permalink)
Stammbenutzer
Viertel Megabyte
 
Benutzerbild von Geeeee
 
Registriert seit: 17.02.2009
Fachbeiträge: 484
Abgegebene Danke: 4
Erhielt 24 Danke für 23 Beiträge
Will einfach nochmal das Wort Sobeloperator für die Kantenerkennung in den Thread werfen.
EDIT: argh, sehe gerade, dass du Sobel bei dir in einem Editgrund angegeben hast
__________________
KirbyDance
<(*.*<) <(*.*<) ^(*.*)^ ^(*.*)^ (>*.*)> (>*.*)>
Geeeee ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 09:43   #11 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Zitat: Geeeee
Beitrag anzeigen
Will einfach nochmal das Wort Sobeloperator für die Kantenerkennung in den Thread werfen.
EDIT: argh, sehe gerade, dass du Sobel bei dir in einem Editgrund angegeben hast
Wenn ich den anwende bekomme ich an der Stelle wo der Barcode ist ein "Kantengewuschel"!

===========================
EDIT:

Ich habe diese Seite hier gefunden: BaToo - Bar Code Toolkit : Documentation - Algorithm browse Dort wird der Algorithmus beschrieben. Teile verstehe ich (und habe ich mir auch so in etwa gedacht) aber andere Teile verstehe ich nicht:
Zitat:
By applying slightly different recognition parameters along each individual scanline (i.e., the binarization threshold that categorizes pixels into either black or white), the overall recognition accuracy can also be improved.
Was ist hier gemeint? Die Festsetzung des Wertes zur Entscheidung was schwarz und was weiß ist? Und wie setzt man den Wert fest?

Hier ist der Kommentar des Algorithmusses (zwei 's'?):
Code:
/** 
 *  This class manages the recognition of a barcode, using several scanlines.
 *  It runs the recognition along several scanlines and combines the results of
 *  the different runs.
 *  <p>
 *  Central to the combination of the results of the different scanlines is a three dim. array,
 *  referenced as "possible_numbers", containing information about the occurence of a certain 
 *  digit at a specific position in the EAN13 code.
 *  <p>	         
 *  The first dimension has 13 entries and represents the position in the EAN13 code.
 *  The second dimension has 10 entries and works like a stack for the digits recognized
 *  at that position in the EAN13 code. <br>
 *  The third dimension has two elements: <br> 0 = specifies the digit itself (0..9), 
 *                                        <br> 1 = the amount of this digit's occurence  
 *                                                  at that position in the EAN13 code (0..#scanlines)
 *  <p><p>                                          
 *  Here is an example. Assume, we have 19 scanlines, and along these scanline the following 
 *  information is recognized: (This has been a pretty blurry barcode image... :-)
 *  <p>
 *   Scanline 0 result: ????????????<br>
 *   Scanline 1 result: ????????????<br>
 *   Scanline 2 result: ????????????<br>
 *   Scanline 3 result: ????????????<br>
 *   Scanline 4 result: ????????????<br>
 *   Scanline 5 result: ????????????<br>
 *   Scanline 6 result: 3?6???3?????<br>
 *   Scanline 7 result: ????????????<br>
 *   Scanline 8 result: ?????4??????<br>
 *   Scanline 9 result: ????????????<br>
 *   Scanline 10 result: ????????????<br>
 *   Scanline 11 result: 612?97017840<br>
 *   Scanline 12 result: ???7????8???<br>
 *   Scanline 13 result: 6122970178?0<br>
 *   Scanline 14 result: ????????????<br>
 *   Scanline 15 result: ????????????<br>
 *   Scanline 16 result: ????????????<br>
 *   Scanline 17 result: ????????????<br>
 *   Scanline 18 result: ????????????<br>
 *   Scanline 19 result: ????????????<br>
 *   <p><p>
 *   The possible_numbers-array will contain the following information.
 *   (Index of third dim. = 0 => Here we see information about the recognized digits.)
 *   The array has already been sorted using the sortDigits() method. This means
 *   that the digits that have been detected most at a certain position are on top.
 *   <p>
 *   detected digits: possible_numbers[][][0]
 *   <p>
 *   0 :   6  1  2  7  9  7  0  1  7  8  4  0 <br> 
 *   1 :   3  x  6  2  x  4  3  x  8  x  x  x <br>
 *   2 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   3 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   4 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   5 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   6 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   7 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   8 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   9 :   x  x  x  x  x  x  x  x  x  x  x  x <br> 
 *   <p>
 *   Index of third dim. = 1 => Here we see information about the occurence of the
 *   digits.
 *   <p>
 *   # of their occurence: possible_numbers[][][1]
 *   <p>
 *   0 :   2  2  2  1  2  2  2  2  2  2  1  2 <br>  
 *   1 :   1  0  1  1  0  1  1  0  1  0  0  0 <br> 
 *   2 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   3 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   4 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   5 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   6 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   7 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   8 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   9 :   0  0  0  0  0  0  0  0  0  0  0  0 <br> 
 *   <p> 
 *   Below is a run of the detectValidBarcode() method that tries to detect a valid
 *   barcode. If no code can be recognized directly, we are trying all possible
 *   combinations of the recognized digits starting with the "most likely" combination.
 *   This is intended as a last try. The need to try different combinations of the recognized digits
 *   should occur very seldom, or at least with only very few alternatives for 
 *   specific digits. As a prositive effect, we get the chance to recognize a barcode that
 *   couldn't be recognized before, as a negative consequence, we can get a EAN13 number
 *   that is correct, according to the checksum, but that doesn't match the 
 *   barcode on the image.
 *   <p>
 *   Trying to find a valid code: (detectValidBarcode()-method)
 *   <p>
 *   CHECK: 6 1 2 7 9 7 0 1 7 8 4 0  ckecksum_digit:5 <br>
 *   CHECK: 6 1 2 7 9 7 0 1 8 8 4 0  ckecksum_digit:2 <br>
 *   CHECK: 6 1 2 7 9 7 3 1 7 8 4 0  ckecksum_digit:6 <br>
 *   CHECK: 6 1 2 7 9 7 3 1 8 8 4 0  ckecksum_digit:3 <br>
 *   CHECK: 6 1 2 7 9 4 0 1 7 8 4 0  ckecksum_digit:8 <br>
 *   CHECK: 6 1 2 7 9 4 0 1 8 8 4 0  ckecksum_digit:5 <br>
 *   CHECK: 6 1 2 7 9 4 3 1 7 8 4 0  ckecksum_digit:9 <br>
 *   CHECK: 6 1 2 7 9 4 3 1 8 8 4 0  ckecksum_digit:6 <br>
 *   CHECK: 6 1 2 2 9 7 0 1 7 8 4 0  ckecksum_digit:0 <br>
 *   <p>
 *   RESULT: 612297017840                                                                         
 *   <p>            
 *   
 *  @author Robert Adelmann
 *  @version 1.0
 */
Also was ist in dem 3-D-Array?

Geändert von data89 (08.10.2009 um 10:08 Uhr)
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 10:30   #12 (permalink)
Stammbenutzer
Megabyte
 
Benutzerbild von mogel
 
Registriert seit: 04.12.2007
Fachbeiträge: 1.045
Abgegebene Danke: 57
Erhielt 56 Danke für 54 Beiträge
Zitat: data89
Beitrag anzeigen
Wenn ich den anwende bekomme ich an der Stelle wo der Barcode ist ein "Kantengewuschel"!
ist auch klar ... Du hast keine Kanten sondern Flächen ... da durchaus 2 (oder auch 3) Bits nebeneinander gesetzt sind im Barcode ... mal abgesehen davon - ein einfaches Bit würde Dir auch 2 Kanten Liefern (Flankenübergang von 0->1 und 1->0) ... damit hast Du aber immer noch nichts gewonnen - im Gegenteil nun hast Du doppelt soviele Linien

Zitat:
Was ist hier gemeint? Die Festsetzung des Wertes zur Entscheidung was schwarz und was weiß ist? Und wie setzt man den Wert fest?
ich quote mich mal pauschal selber

Zitat: mogel
Beitrag anzeigen
... pauschal ein Binärfilter verwenden ...
letzter Versuch, mogel
__________________
http://www.fantasya-pbem.de - Fantasy-Multiplayer-Strategie - Runden basiert - Twitter
Rechtschreibfehler unterliegen der LGPL - Semantikfehler stehen unter AGPL
mogel ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 10:45   #13 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Zitat: mogel
Beitrag anzeigen
letzter Versuch, mogel
In dem Beispiel wird ja auch mit einem Binärfilter gearbeitet: erst in Grauwerte umwandeln und dann Thresholding benutzen. Fertig ist die Scannerlinie.

Wenn ich das auf mein Webcambild anwende, kommt das heraus:


Jetzt muss ich mehrere Scannerlinien drüberlegen, den EAN mehrmals einlesen und dann abgleichen und eine Mehrheitsentscheidung vornhemen. Wenn ich das gemacht habe, dann muss ich noch ein bisschen Code/Performance verbessern.

So müsste es jetzt aber funktionieren, oder???

data89
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 10:59   #14 (permalink)
Stammbenutzer
Viertel Megabyte
 
Benutzerbild von Geeeee
 
Registriert seit: 17.02.2009
Fachbeiträge: 484
Abgegebene Danke: 4
Erhielt 24 Danke für 23 Beiträge
Ich wollte in die Richtung Kantenerkennung nur gehen, damit er den Barcode richtig rotiert bekommt und dann auslesen kann.
__________________
KirbyDance
<(*.*<) <(*.*<) ^(*.*)^ ^(*.*)^ (>*.*)> (>*.*)>
Geeeee ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 11:06   #15 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Okay, aber das mit dem Rotieren lasse ich weg. Der benutzer sieht später auf dem Bildschirm ein Visier (roter Bereich mit Mittellinie) und muss dann den Barcode dort zentrieren und einmal ablichten. Ich denke, dass man so viel vom Benutzer verlangen kann ...

Wenn man den Barcode auf einem statischen Bild sucht, dann benötigt man das. Außerdem sieht mein Testbild scheußlich aus und eignet sich eher weniger (durch die Verzerrungen):


data89
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 11:42   #16 (permalink)
Stammbenutzer
Megabyte
 
Benutzerbild von mogel
 
Registriert seit: 04.12.2007
Fachbeiträge: 1.045
Abgegebene Danke: 57
Erhielt 56 Danke für 54 Beiträge
Zitat: data89
Beitrag anzeigen
So müsste es jetzt aber funktionieren, oder???
ja ... im Idealfall nicht X-mal über die selber Zeile sondern mal oben mal unten ... allerdings wirst Du mit Deinem Beispiel Probleme bekommen - es ist verzerrt ... wenn Du jetzt x-mal über die gleiche Zeile gehst (dann ist die Zerrung egal), bekommst Du auch x-mal exakt das gleiche raus ... damit reicht es wenn Du nur 1 mal den Scanner bemühst
__________________
http://www.fantasya-pbem.de - Fantasy-Multiplayer-Strategie - Runden basiert - Twitter
Rechtschreibfehler unterliegen der LGPL - Semantikfehler stehen unter AGPL
mogel ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 08.10.2009, 15:12   #17 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Also hier mein Ergebnis. Aber irgendwie klappt das immer noch nicht ...

BcodeReader.java
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
 
import javax.imageio.ImageIO;
 
public class BcodeReader {
 
    public BcodeReader(int[][] image, int scanlines) {
        
        // check the size of scanlines
        if (scanlines > image.length) {
            scanlines = image.length;
        }
        
        int[][] barcodes = new int[scanlines][8];
        int bcnt = 0;
        
        // scan the complete barcode
        for (int i = 0; i < scanlines; i++) {
            int height = (image.length/scanlines)*i;
        
            // get the line of colors
            int[] scanline = BcodeReader.getColorFromRGB(image[i]);
            // read the fields
            int[][] fields = BcodeReader.getFields(scanline);
            
            int[] code = new EAN8().recognize(fields, 1, fields.length-1);
            
            if (code != null) {
                System.out.println(java.util.Arrays.toString(code));
                    
                barcodes[bcnt] = code;
                bcnt++;
                
            }
        }
        
        int[] eanFinal = new int[8];
        
        for (int i = 0; i < eanFinal.length; i++) {
            
            int[] alleDieserStelle = new int[barcodes.length];
            for (int j = 0; j < barcodes.length; j++) {
                alleDieserStelle[j] = barcodes[j][i];
            }
            
            eanFinal[i] = BcodeReader.getNumber(alleDieserStelle);
            
            
        }
        
        System.out.println(java.util.Arrays.toString(eanFinal));
        
    }
    
    private static int getNumber(int[] candidates) {
        
        int[][] bewertung = new int[candidates.length][2];
        int bewcnt = 0;
        
        for (int i = 0; i < candidates.length; i++) {
            
            boolean contains = false;
            for (int j = 0; j < bewertung.length; j++) {
                if (bewertung[j][0] == candidates[i]) {
                    bewertung[j][1]++;
                    contains = true;
                }
            }
            
            if (!contains) {
                bewertung[bewcnt][0] = candidates[i];
                bewertung[bewcnt][1] = 1;
                bewcnt++;
            }
            
        }
        
        int highestIndex = 0;
        int highestNumber = 0;
        
        for (int i = 0; i < bewertung.length; i++) {
            
            if (bewertung[i][0] > highestNumber) {
                highestNumber = bewertung[i][0];
                highestIndex = i;
            }
            
        }
        
        
        return bewertung[highestIndex][0];
    }
    
    private static int[][] getFields(int[] scanline) {
        
        // check 
        if (scanline.length < 1) {
            return null;
        }
        
        /*
         * temp contains on
         *  0: the value (0 or 255)
         *  1: the number of fields
         */
        int[][] temp = new int[scanline.length][2];
        
        int fcnt = 0;
        int last_value = scanline[0];
        int last_fields = 1;
        for (int i = 1; i < scanline.length; i++) {
            if ((scanline[i] == last_value) && (i < scanline.length - 1)) {
                last_fields++;
            } else {
                
                temp[fcnt][0] = last_value;
                temp[fcnt][1] = last_fields;
                
                fcnt++;
                last_value = scanline[i];
                last_fields = 0;
            }
        }
        
        int[][] fields = new int[fcnt][2];
        for (int i = 0; i < fields.length; i++) {
            fields[i] = temp[i];
        }
        
        return fields;
    }
    
    private static int[] getColorFromRGB(int[] rgb_array) {
        
        int[][] line = new int[rgb_array.length][3];
        
        for (int i = 0; i < rgb_array.length; i++) {
            Color c = new Color(rgb_array[i]);
            
            line[i][0] = c.getRed();
            line[i][1] = c.getGreen();
            line[i][2] = c.getBlue();
        }
        
        return BcodeReader.transformPathToBW(line);
    }
    
    
    
    
    
    
    private static int[] transformPathToBW(int[][] line) {
 
        int w = line.length;
        int bw_line[] = new int[w];
        bw_line[0] = 255;
 
        // create greyscale values:
        int grey_line[] = new int[w];
        int average_illumination = 0;
        for (int x = 0; x < w; x++) {
            grey_line[x] = (line[x][0] + line[x][1] + line[x][2]) / 3;
            average_illumination = average_illumination + grey_line[x];
        }
        average_illumination = average_illumination / w;
 
        // perform the binarization:
        int range = w / 20;
 
        // temp values:
        int moving_sum;
        int moving_average;
        int v1_index = -range + 1;
        int v2_index = range;
        int v1 = grey_line[0];
        int v2 = grey_line[range];
        int current_value;
        int comparison_value;
 
        // initialize the moving sum:
        moving_sum = grey_line[0] * range;
        for (int i = 0; i < range; i++)
            moving_sum = moving_sum + grey_line[i];
 
        // apply the adaptive thresholding algorithm:
        for (int i = 1; i < w - 1; i++) {
            if (v1_index > 0) v1 = grey_line[v1_index];
            if (v2_index < w) v2 = grey_line[v2_index];
            else v2 = grey_line[w - 1];
            moving_sum = moving_sum - v1 + v2;
            moving_average = moving_sum / (range << 1);
            v1_index++;
            v2_index++;
 
            current_value = (grey_line[i - 1] + grey_line[i]) >>> 1;
 
            // decide if the current pixel should be black or white: 
            comparison_value = (3 * moving_average + average_illumination) >>> 2;
            if ((current_value < comparison_value - 3)) bw_line[i] = 0;
            else bw_line[i] = 255;
        }
 
        // filter the values: (remove too small fields)         
 
        if (w >= 640) {
            for (int x = 1; x < w - 1; x++) {
                if ((bw_line[x] != bw_line[x - 1]) && (bw_line[x] != bw_line[x + 1])) bw_line[x] = bw_line[x - 1];
            }
        }
        return bw_line;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    public static void main(String[] args) {
        
        try {
            
            BufferedImage image = ImageIO.read(new File("barcode.png"));
            
            int w = image.getWidth();
            int h = image.getHeight();
            int[] rgbs = new int[w*h];
            image.getRGB(0, 0, w, h, rgbs, 0, w);
            
            int[][] img = new int[h][w];
            int totcnt = 0;
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    img[i][j] = rgbs[totcnt];
                    totcnt++;
                }
            }
            
            new BcodeReader(img, 1);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        
    }
    
}
EAN8.java
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
public class EAN8 implements Barcode {
 
    public static int FIELD_LENGTH = 43;
 
    public static int[] NUMBERSPACE = new int[]{
        3211,
        2221,
        2122,
        1411,
        1132,
        1231,
        1114,
        1312,
        1213,
        3112
    };
    
    
    @Override
    public int[] recognize(int[][] fields, int start, int end) {
 
        // check
        
        int[] result = new int[8];
        
        if ((end - start) != FIELD_LENGTH ||
                start < 0 || end > (fields.length - 1)) {
            return null;
        }
 
        int white_length = 0;
        int black_length = 0;
        
 
        black_length = Math.round(((float)fields[start + 0][1] + fields[start + 2][1] + fields[end - 0][1] 
                           + fields[end - 2][1] + fields[start + 20][1] + fields[start + 22][1])/6.0f);
        white_length = Math.round(((float)fields[start + 0][1] + fields[end - 1][1] + fields[start + 19][1]
                           + fields[start + 21][1] + fields[start + 23][1])/5.0f);
 
        result[0] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 3][1])/white_length) + "")+
                (Math.round(((double)fields[start + 4][1])/black_length) + "")+
                (Math.round(((double)fields[start + 5][1])/white_length) + "")+
                (Math.round(((double)fields[start + 6][1])/black_length) + "")
        ));
        
        result[1] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 7][1])/white_length) + "")+
                (Math.round(((double)fields[start + 8][1])/black_length) + "")+
                (Math.round(((double)fields[start + 9][1])/white_length) + "")+
                (Math.round(((double)fields[start + 10][1])/black_length) + "")
        ));
        
        result[2] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 11][1])/white_length) + "")+
                (Math.round(((double)fields[start + 12][1])/black_length) + "")+
                (Math.round(((double)fields[start + 13][1])/white_length) + "")+
                (Math.round(((double)fields[start + 14][1])/black_length) + "")
        ));
        
        result[3] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 15][1])/white_length) + "")+
                (Math.round(((double)fields[start + 16][1])/black_length) + "")+
                (Math.round(((double)fields[start + 17][1])/white_length) + "")+
                (Math.round(((double)fields[start + 18][1])/black_length) + "")
        ));
        
        result[4] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 24][1])/white_length) + "")+
                (Math.round(((double)fields[start + 25][1])/black_length) + "")+
                (Math.round(((double)fields[start + 26][1])/white_length) + "")+
                (Math.round(((double)fields[start + 27][1])/black_length) + "")
        ));
        
        result[5] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 28][1])/white_length) + "")+
                (Math.round(((double)fields[start + 29][1])/black_length) + "")+
                (Math.round(((double)fields[start + 30][1])/white_length) + "")+
                (Math.round(((double)fields[start + 31][1])/black_length) + "")
        ));
        
        result[6] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 32][1])/white_length) + "")+
                (Math.round(((double)fields[start + 33][1])/black_length) + "")+
                (Math.round(((double)fields[start + 34][1])/white_length) + "")+
                (Math.round(((double)fields[start + 35][1])/black_length) + "")
        ));
        
        result[7] = Integer.parseInt(((String)
                (Math.round(((double)fields[start + 36][1])/white_length) + "")+
                (Math.round(((double)fields[start + 37][1])/black_length) + "")+
                (Math.round(((double)fields[start + 38][1])/white_length) + "")+
                (Math.round(((double)fields[start + 39][1])/black_length) + "")
        ));
        
 
        int[] eanCode = new int[8];
        for (int i = 0; i < eanCode.length; i++) {
            eanCode[i] = this.lookUpNumber(result[i]);
        }
        
        return eanCode;
    }
 
    
    public int lookUpNumber(int ean) {
        
        for (int i = 0; i < EAN8.NUMBERSPACE.length; i++) {
            if (EAN8.NUMBERSPACE[i] == ean) {
                return i;
            }
        }
        return -1;
    }
    
    
}
Barcode.java
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
public interface Barcode {
 
    public int[] recognize(int[][] fields, int start, int end);
 
}
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Alt 10.10.2009, 10:07   #18 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Benutzerbild von data89
 
Registriert seit: 08.08.2008
Fachbeiträge: 126
Abgegebene Danke: 1
Erhielt 0 Danke für 0 Beiträge
Standard Noch eine wichtige Frage

Hallo,

ich habe das jetzt mit dem Barcode hinbekommen und das funktioniert auch via JMF mit meiner Webcam. Aber: da das Bild so groß ist werden manchmal auch Barcodes erkannt, wo garkeine vorhanden sind.

Gibt es einen einfachen Mechanismus, mit dem man feststellen kann, ob ein Barcode im Bild befindlich ist?

data89
data89 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Thema geschlossen    

Stichworte
barcodes , erkennen , image , java , recognition

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Firefox, Spielmit.com und ein Java Spiel! Glasiwong Java Basics - Anfänger-Themen 3 19.05.2012 06:28
Animation hinter transparentem Bild auf der GlassPane java2000 Spiele- und Multimedia-Programmierung 6 21.05.2008 19:34
Scalieren eines Bildes, abhängig von der Fenstergröße Java Basics - Anfänger-Themen 10 19.08.2006 20:14
Bilder mit unerwünschter Auflösung geschrieben (-> JAI) Reeny AWT, Swing, JavaFX & SWT 1 07.03.2006 13:21
Bild in einem JScrollPane anzeigen AWT, Swing, JavaFX & SWT 3 05.07.2004 13:11


Lesezeichen

Forumregeln
Es ist Ihnen erlaubt, neue Themen zu verfassen.
Es ist Ihnen erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:11 Uhr.


Powered by vBulletin® Version 3.8.6 (Deutsch)
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.2
Thanks for Smilies by smilies.4-user.de