Barcode dekodieren
-
Hallo an alle,
es gibt da draußen erstaunlich wenige freie Libs, die Barcodes, im speziellen DataMatrix dekodieren können. Von den wenigen, die es gibt, kann man sagen, dass die nicht mal sonderlich gut sind. Ich habe nun ZXing (C++ Port) und libdmtx ausprobiert und bei relativ guten Bildern sind die nicht sonderlich zuverlässig. Das Problem ist unter anderem, dass die Modulgrößen (Größe einer einzelnen Zelle) nicht zu 100% gleich sind. Das hat bei Lasern z. B. etwas mit dem Brennprozess zu tun. Ein ähnliches Problem haben Drucker. D. h., dass schwarze Module tendenziell größer sind als weiße. Das lässt sich durch entsprechende Tricks teils unterbinden, aber da habe ich als Entwickler kein Einfluss drauf.
Ich habe mir deshalb überlegt, dass ich eine Art Dekodier-Vorverarbeitung mache. Ich habe an eine Kontursuche gedacht, in der ich über Statistiken die Durchschnittsgröße einer einzelnen Zelle ermittle. Z. B. 10 x 10 Pixel. Dann würde ich quasi mit einem 10 x 10 Raster durch den Barcode wandern und den Mittelwert innerhalb dieses Rasters bestimmen. Ist der Mittelwert niedrig, dann kann ich von einer schwarzen Farbe ausgehen, ansonsten von einer weißen. Und hier kommt nun der Clou: Ich erstelle ein neues, artifizielles Bild und würde an der entsprechenden Position ein Modul mit der entsprechenden Farbe hinkopieren. Am Ende sollte ich dann theoretisch einen perfekt generierten Barcode haben.Haltet ihr die Idee für gut oder gibt es klügere Möglichkeiten? Ich habe schon einiges ausprobiert wie z. B. das Bild mit einem Hochpassfilter schärfen oder das Bild selbst zu binarisieren und es der Lib übergeben. Eine weitere Möglichkeit: Das Bild herunter zu skalieren, um die Zellgrößen-Unterschiede zu minimieren. Teils hat das tatsächlich etwas gebracht, aber ich war nie zu 100% zufrieden.
Eine weitere Möglichkeit wäre eine proprietärere Lib. Diese muss allerdings auch unter ARM kompilierbar sein und man sollte nicht pro Gerät Lizenzgebühren zahlen müssen. Hat da jemand Erfahrungen?
Danke im Voraus,
Steffo
-
Ganz wichtig sind imho die Finder Patterns. Man zentralprojiziert (x=x/z+BildschirmXMitte; y=y/z+BildschirmYMitte) zwei gleich lange, senkrechte Linien und
verschiebt sie und dreht (die Drehformel steht in den Artikeln, man braucht nur die Achsen noch zu vertauschen) sie vorher durchprobierend an ihrem Berührpunkt um drei Achsen (Linien bleiben Linien, daher braucht man nur die Endpunkte zu drehen und kann mit einem Linienalgorithmus ( erhöhe je Schritt Koordinaten in eine Richtung um ein Pixel, in die andere um einen Bruchwert) verbinden. Zerlegt man Texturen in Linien gleicher Farbe, läuft die Grafik schneller, nur mal erwähnt). Dann summiert man den Betrag der Pixeldifferenzen an derselben Stelle zum Bild mit dem Data-Matrix-Code auf. Bei geringen Differenzen hat man die Positionierung und Drehung des Data-Matrix-Codes wahrscheinlich gefunden (man kann alle durchprobieren und den Verweis auf den besten Treffer solange beibehalten, bis eventuell noch ein besserer kommt). Dann wäre der Code ja eine Ebene. Durch die iteriert man und verschiebt und dreht jeden Punkt entsprechend und projiziert ihn erneut, um den Punkt auf dem Kamerabild zu finden. Den Wert des Kamerabilds kopiert man anschließend in ein 2D-Array. [Die Achsendrehungen führt man anschließend mit den Punkten im Array rückwärts aus, sodaß es parallel ist zu den Koordinatenachsen und kann es auch noch so verschieben, daß es entsprechend groß ist an der benötigten Stelle. Dann hat man die Perspektive in Draufsicht verwandelt. Nochmal projizieren ins vorläufige Bild. ] Oder: man skaliert halt das 2D-Array um.
Das kann man dann vorher weichzeichnen oder sonstwie filtern und hat beim Kopieren hinterher immer einen Schwellwert für Schwarz und weiß. So setzt man dann die Pixel an der entsprechenden Stelle des aufbereiteten Bilds, das man der Bibliothek übergibt?
Habe nur alle Programmteile geschrieben ( z.B. sogar ein Programm, das rotierte, verschieden lange Linien über die Unscharfmaske legt, vergleicht, leert und somit ein Bitmap in Linienparameter konvertiert, die es im Fall großer Treffgenauigkeit dann ausgibt). Zusammengebaut und für diese Anwendung getestet habe ich die noch nicht.
Man muß halt wissen, daß das Kamerabild ein 3D-Grafik-Abbild von einer hoffentlich flachen Ebene ist (die Wölbungen durch Papierknitterung zu simulieren und da dann noch rumzuprobieren, ist Zukunftsmusik und sowas zu vergleichen geht wahrscheinlich nur noch mit evolutionären Algorithmen in einer angemessenen Zeit ) und dann halt die Sache mit dem Schwellwert, Fuzzy-Logic und weichzeichnen (Mittelwerte mit benachbarten Pixeln bilden).
Weiter bin ich mit meinem Latein am Ende.
-
@Klagenderlamer Vielen Dank, für dein Beitrag!
Mit Finder Pattern meinst du den, der hier beschrieben ist? Das Finden des Barcodes ist für mich kein Problem. Das habe ich schon gelöst. Aber obwohl ich wirklich ein relativ gutes und ausgeschnittenes Bild übergebe, haben die Libs teils Probleme. Deswegen hatte ich eben daran gedacht, den Barcode neu zu generieren.