Los códigos de barras, Qr y Datamatrix están cada vez más extendidos. Tienen infinidad de aplicaciones, quizás la más extendida y primera que se viene a la mente es cualquier etiqueta o embase.  Lo vemos en supermercados, ropa, farmacia, facturas, extractos, correspondencia, correos, Amazon, documentación clínica, administrativa, contratos, banca y un largo etcétera.

¿Porque se utilizan estos códigos? por la automatización de procesos y trabajos. Si bien el ojo humano no interpreta esos códigos como algo más que barras, puntos y figuras, la informática y con ella, todo lo susceptible de programación hacen que sean códigos resistentes, legibles rápidamente, muy eficientes, sin lugar al error o con mínimas posibilidades de error.

Pues bien, vamos a ver cómo implementar su lectura desde Python.

ZBar

La mejor librería en estos casos es con diferencia ZBar.

De código abierto, disponible para C++, Python, Ruby y Perl.

Instalando la lib ZBar en Ubuntu

No nos detendremos a comentar la instalación, como siempre sudo apt-get …

sudo apt-get install libzbar-dev libzbar0

pyZBar

pyzbar nos permitirá utilizar esta magnífica librería desde Python.

Instalando pyzbar

pip3 install pyzbar

* quizás sea interesante echar un vistazo a pip y pip3, porque utilizar uno u otro, ¿es lo mismo?

OpenCV

El trabajo con imágenes se simplifica enormemente con openCV

sudo apt-get install python-opencv

Leyendo con ZBar desde Python

Bien, ya tenemos todo lo que necesitamos, vamos al código.

Creamos la función tifrbar, tiene como parámetros el nombre del archivo tiff origen y el archivo txt de salida.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Aug 29 12:11:22 2018
@author: altaruru
"""

import pyzbar.pyzbar as pyzbar
import numpy as np
import cv2

def tifrbar(tifname, txtname):    
    try:
        # carga imagen
        tifimg = cv2.imread(tifname)
        # carga códigos de barras de la imagen en lista
        lstbc = pyzbar.decode(tifimg)
        # recorre objetos encontrados
        fptxt = open(txtname, 'w')    
        for bc in lstbc: 
            npoint = bc.polygon
            # estamos buscando un area rectangular, si hay más de 4 puntos intenta una aproximación
            if len(npoint) > 4 : 
              hull = cv2.convexHull(np.array([point for point in npoint], dtype=np.float32))
              hull = list(map(tuple, np.squeeze(hull)))
            else : 
              hull = npoint
            n = len(hull)
            if (n>0):
                # código válido
                slinea="%s|%s\n" % (bc.data, bc.type)
                print(slinea)
                fptxt.write(slinea)
        fptxt.closed
        return True
    except:
        # si hay algún error...
        print("ERROR de lectura, tifrbar")
    return False

Y añadimos nuestra función de prueba:

def test():    
    spathfile="/home/altaruru/pysrc/imgs/factdge.tif"
    spathtxt="/home/altaruru/pysrc/imgs/factdge.txt"
    tifrbar(spathfile, spathtxt)

test()

Ejecutamos y… Nuestro archivo txt con los códigos leídos:

b'8470006583203'|EAN13
b'FFS21BFZGH89191'|CODE128
b'8470007295662'|EAN13
b'B776741667GG665'|CODE128

A partir de aquí cualquier implementación es posible, guardar en BD, indexar, separar documentos, …

Saludos y Altaruru!!!!

Referencias

Un comentario sobre «Leyendo códigos de Barras y QRs desde Python con ZBar y OpenCV»

  1. Fredd

    Hola!! esta muy claro, muchas gracias.

    ¿Podrías poner los archivos de ejemplo?. Porque estoy intentando pero no tengo éxito si bien no me marca ningún error.

Deja tu comentario