Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Binarisation d'une image

+1 vote

Je souhaiterais binariser (mettre en noir et blanc) ce code barre :
enter image description here

mais problème avec mon programme je n'arrive pas à obtenir des barres droites, auriez vous une solution pour remédier à ce problème ?

def bin(img):
    nimg=deepcopy(img)
    (largeur,hauteur,ncouleur)=img.shape
    for i in range(largeur):
        for j in range(hauteur):
            a=0.33*nimg[i][j][0]+0.33*nimg[i][j][2]+0.33*nimg[i][j][2]
            for k in range(3):
                if a>0.55:
                    nimg[i][j][k]=1
                else :
                    nimg[i][j][k]=0
    mpimg.imsave('code 2',nimg)
    plt.imshow(nimg)
    plt.show()
demandé 22-Dec-2016 par Quentin
edité 22-Dec-2016 par boblinux

donne un screenshot ce sera deja plus clair

enter image description here

enter image description here

Voici le code et l'image que j'obtiens en l'appliquant.

Peux-tu formater et indenter correctement ton code ?

def bin(img):
nimg=deepcopy(img)
(largeur,hauteur,ncouleur)=img.shape
for i in range(largeur):
     for j in range(hauteur):
          a=0.33*nimg[i][j][0]+0.33*nimg[i][j][1]+0.33*nimg[i][j][2]
          for k in range(3):
                if a>0.55:
                   nimg[i][j][k]=1
                else :
                   nimg[i][j][k]=0
mpimg.imsave('code 2',nimg)
plt.imshow(nimg)
plt.show()

Pas sûr de comprendre ta question, quand tu veux des "barres droites" il est question d'orientation des barres ?
Peux-tu décrire le résultat que tu souhaites obtenir ?
J'ai plus l'impression que c'est un sujet de traitement d'image que de python. (ton code à l'air de faire son job !)

en fait avec mon code les barres sont pixelisés et donc ne sont plus droites, il y a des pixels qui dépassent de part et d'autres de certaines barres :/
(l'objectif est de réaliser un programme de lecture de code barre)

C'est quoi tes libs? scipy? matplotlib?

2 Réponses

+4 votes

Pillow peut te faire ça.

class PIL.ImageEnhance.Color(image) Adjust image color balance.

This class can be used to adjust the colour balance of an image, in a
manner similar to the controls on a colour TV set. An enhancement
factor of 0.0 gives a black and white image. A factor of 1.0 gives the
original image.

répondu 23-Dec-2016 par max (888 points)
+1 vote

Vu que tu récupères les dimensions via l'attribut .shape, j'imagine que ton objet est chargé dans un array Numpy.
Dans ce cas là je t'encourage à utiliser directement les fonctions de numpy pour largement simplifier (et accélérer) ton traitement. Beaucoup son intégrées comme méthodes des np.array.

import numpy as np

def bin(img, threshold=0.55):
    """Docstring"""
    #----- bloc 1 : copie
    #nimg=deepcopy(img)  # inutile ici, numpy va créer une copie directement pour nous

    #----- bloc 2 : moyenne des couleurs pixel à pixel
    #(largeur,hauteur,ncouleur)=img.shape
    #for i in range(largeur):
    #    for j in range(hauteur):
    #        a=0.33*nimg[i][j][0]+0.33*nimg[i][j][1]+0.33*nimg[i][j][2]
    mean_img = img.mean(axis=-1)  # remplace l'itération pixel à pixel pour moyenner les couleurs

    #----- bloc 3 : binarisation
    #          for k in range(3):
    #              if a>0.55:
    #                  nimg[i][j][k]=1
    #              else :
    #                  nimg[i][j][k]=0
    nimg = mean_img > threshold  # créé directement le masque binaire en fonction du seuil

    #----- oneliner : voir 1.)
    nimg = img.mean(axis=-1) > threshold

    #----- bloc 4 : barres droites, voir 2.)
    largeur, hauteur, couleurs = img.shape
    ones = np.ones((hauteur, 1))  # créé une image de même hauteur sur 1 pixel de large
    section = nimg[hauteur // 2, :]  # récupère une section de la largeur à mi-hauteur
    final_img = section * ones  # le broadcasting est automatique

    #----- bloc 5 : sauvegarde
    mpimg.imsave('code 2',nimg)
    plt.imshow(nimg)
    plt.show()

1.) En une ligne lisible tu créé une masque binaire à partir de ton image moyennée sur

2.) Pour avoir des "barres droites", si ton image principale est bien calibrée (prise de face, sans distorsion, ...) tu peux simplement utiliser le broadcasting de numpy. C'est à dire dans ton cas étaler en hauteur une ligne qui passe par toutes les barres.
En récupérant une section de tes barres à mi-hauteur (simple extraction en indexing) et en multipliant ça avec un np.array de "1" avec la bonne hauteur mais une largeur de 1 pixel, c'est automatique.

Sinon il y a d'autres solutions plus poussées pour identifier des codes barres, mais ça dépend de la finalité de ton code.

En espérant que ça t'aide (et que la réponse ne vienne pas trop tard).

répondu 13-Fev par Crus-T (114 points)

Non merci beaucoup c'est toujours bien de voir une autre méthode ! :)

Je n'ai pas très bien compris l'histoire de broadcasting par contre ?
C'est un module directement dans la bibliothèque numpy qui permet de redresser une image ?

L'objectif final est d'arriver à localiser le code-barre sur une image quelque soit sa position puis de l'extraire et de le decoder. La partie sur le decodage est déjà faite je suis entrain d'essayer de trouver comment l'isoler dans une image ^^

Le broadcasting est seulement une fonctionnalité de Numpy, qui permet d'étirer une image sur une dimension. Si tu peux isoler une ligne de pixels dans un code barre, qui passerait par toutes les barres, alors en utilisant le broadcasting tu peux étirer cette ligne pour générer une image dont les barres seront parfaitement droites.

Mais au final je pense que ce n'est pas ce que tu cherches. Tu pourrais regarder du côté d'openCV, une librairie pour laquelle il y a un tuto de détection de code barre. La finalité du tuto est juste d'afficher une bounding box autour du code barre, mais tu peux parfaitement récupérer les coordonnées du rectangle et lui appliquer une rotation de manière à le redresser.
Si besoin, toutes les étapes devraient être transposables vers les librairies Scipy, Numpy et Scikit-image.

...