Scanner de codes à barres Code 39

10

Le code 39 , développé en 1974, est l'une des symbologies ou types de codes-barres les plus couramment utilisés, bien que ce soit le système UPC / EAN qui soit le plus souvent utilisé dans les ventes au détail. Les codes à barres du code 39 peuvent coder des lettres majuscules, des chiffres et certains symboles et sont faciles à imprimer à partir d'un logiciel informatique à l'aide d'une police spéciale. Cela a conduit à leur utilisation commerciale et industrielle généralisée (par exemple, badges d'identification d'entreprise, suivi des actifs, automatisation des usines).

Créez le programme ou la fonction la plus courte pour lire un code-barres Code 39 dans n'importe quelle orientation à partir d'une image en niveaux de gris de 512 x 512 pixels; le code-barres peut ne pas être aligné horizontalement ou verticalement.

  • Votre programme doit accepter un format de fichier image standard et produire les données encodées dans le code-barres comme sa sortie standard ou sa valeur de retour (n'incluant aucun caractère de début / fin).
  • Aucune image ne contient plus d'un code-barres Code 39 valide, et aucun code-barres ne code un caractère espace (ASCII 32).
  • Si aucun code à barres Code 39 valide n'est affiché dans l'image, le programme doit générer un seul point d'interrogation ( ?).

J'ai préparé une implémentation de référence JavaScript et une suite de tests d'images au format PNG, avec et sans codes-barres valides. L'implémentation de référence, qui ne réussit que 3 des 46 cas de test dans les navigateurs Web les plus récents, est destinée à montrer un algorithme de décodage possible, non strictement conforme à la spécification ci-dessus.

Une soumission valide passe au moins 80% de ces tests (37/46) et ne prend pas plus d'une minute pour le faire pour chaque image sur un processeur raisonnablement rapide (par exemple quad-core 2,6 GHz). Mon implémentation de référence passe 93% des tests et traite chaque image en 10 secondes (sur mon ordinateur de bureau exécutant Google Chrome).

(Cette question a été proposée sur Meta le 28 mai 2011.)

Veuillez vous lever
la source
Il semble y avoir un bug dans votre générateur de code-barres - il met un grand espace entre les caractères au lieu d'un étroit.
Keith Randall
@Keith: L'écart entre les caractères (I) ne doit pas nécessairement être égal à la largeur d'une barre étroite (X), bien qu'il le soit souvent. Les soumissions valides devraient pouvoir lire les codes-barres où I ≤ 3X. Mon générateur de cas de test randomise intentionnellement l'écart entre les caractères. adams1.com/39code.html
PleaseStand
un code à barres Code 39 avec un écart entre les caractères entre 1X et 3X peut être lu par la plupart des scanners courants? Je vais en témoigner et voir si cela fonctionne de cette façon . Soit dit en passant, à mes yeux, l'intercap ne peut qu'agrandir la taille d'impression du Code 39, alors pourquoi devrions-nous élargir son écart entre les caractères?

Réponses:

5

Python, 899 caractères

import sys,random
raw_input()
X,Y=map(int,raw_input().split())
input()
I=[' x'[v<'~']for v in sys.stdin.read()]
M={196:' ',168:'$',148:'*',388:'.',52:'0',97:'2',49:'4',112:'6',292:'8',73:'B',25:'D',88:'F',268:'H',28:'J',67:'L',19:'N',82:'P',262:'R',22:'T',193:'V',145:'X',208:\
'Z',42:'%',138:'+',133:'-',162:'/',289:'1',352:'3',304:'5',37:'7',100:'9',265:'A',328:'C',280:'E',13:'G',76:'I',259:'K',322:'M',274:'O',7:'Q',70:'S',385:'U',448:'W'\
,400:'Y'}
N=500
for w in' '*30000:
 a,b,c,d=eval('random.random(),'*4);A=''.join(I[int((a+(c-a)*i/N)*X)+X*int((b+(d-b)*i/N)*Y)]for i in range(N)).lstrip();T=A.count(' x')+1;K=A.count('x')/T;L=A.count\
(' ')/T;s='';z=c=0
 while A:
  z*=2;y=A.find(' ')
  if y<0:y=len(A)
  z+=y>K;A=A[y:]
  z*=2;y=A.find('x')
  if y<0:y=len(A)
  z+=y>L;A=A[y:];c+=2
  if c>9:
   if z/2in M:s+=M[z/2];z=c=0
   else:break
 if s and'*'==s[0]and'*'==s[-1]and'*'!=s:print s[1:-1];break

Ce code prend une image au format pnm en entrée, donc je l'exécute normalement comme:

pngtopnm s01.png | ./barcode.py

Le code lui-même choisit simplement de nombreuses lignes de balayage aléatoires et essaie de faire correspondre les pistes en noir et blanc sur cette ligne de balayage aux modèles de code39. Il est aléatoire de sorte qu'il peut parfois ne pas trouver de codes-barres. (J'obtiens un taux d'échec de faux négatifs d'environ 20% sur les images de test.) Quand il échoue, cela prend environ une minute pour fonctionner, quand il réussit, il le fait souvent beaucoup plus rapidement que cela. Je n'ai jamais vu de faux positif.

Keith Randall
la source
M=dict(zip('UK.-RQA+HGYXON*TEDJ1/87$%540WVML SCBIZPF3296',[385,259,...]))
ugoren