web-dev-qa-db-fra.com

Augmente la luminosité de l'image sans débordement

J'ai eu un problème en essayant d'augmenter la luminosité de l'image.

Voici l'image d'origine:

 enter image description here

L'image que je voulais obtenir est la suivante:

 enter image description here

Maintenant, augmentez la luminosité avec le code suivant:

    image = cv2.imread("/home/wni/vbshare/tmp/a4_index2.png",0)

    if sum(image[0])/len(image[0])<200:
        new = np.where((255-image)<image,255,image*2)
    else:
        new = image
    return new

Et j'ai l'image suivante:

 enter image description here

Ainsi, la luminosité de certains points semble déborder.

Et j'ai essayé de changer le seuil de 200 à un autre nombre, par exemple. 125, 100, 140 .etc Cependant, la luminosité de l’image reste presque noire ou déborde.

Env:

Python: 2.7.10

Ouverture: 3.2.0

Toute suggestion pour cela est appréciée.

Merci.

10
Wesley

Voici mon coup pour un algorithme simple pour nettoyer cette image particulière. Ne hésitez pas à jouer avec elle et Tweak le plus loin pour obtenir le résultat souhaité.

NB: Le code affiché doit fonctionner à la fois avec les branches 2.4.x et 3.x de OpenCV.

Étape 0

Chargez l'image d'entrée en niveaux de gris.

img = cv2.imread('paper.jpg',0)

Étape 1

Dilater l'image, afin de supprimer le texte. Cette étape aide dans une certaine mesure à préserver le code à barres.

dilated_img = cv2.dilate(img, np.ones((7,7), np.uint8)) 

 Dilated

Étape 2

Flou médian du résultat avec un noyau de taille correcte pour supprimer davantage tout texte.

Cela devrait nous donner une assez bonne image de fond contenant toutes les ombres et/ou la décoloration.

bg_img = cv2.medianBlur(dilated_img, 21)

 Blurred

Étape 3

Calculez la différence entre l'original et l'arrière-plan que nous venons d'obtenir. Les bits identiques seront en noir (différence proche de 0), le texte en blanc (différence importante).

Puisque nous voulons du noir sur blanc, nous inversons le résultat.

diff_img = 255 - cv2.absdiff(img, bg_img)

 Inverted Difference

Étape 4

Normaliser l'image, afin que nous utilisions la plage dynamique complète.

norm_img = diff_img.copy() # Needed for 3.x compatibility
cv2.normalize(diff_img, norm_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

 Normalized

Étape 5

À ce stade, nous avons encore le papier un peu gris. Nous pouvons tronquer cela et normaliser l'image.

_, thr_img = cv2.threshold(norm_img, 230, 0, cv2.THRESH_TRUNC)
cv2.normalize(thr_img, thr_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

 Gray Trimmed

Terminé...

Eh bien, au moins pour moi;) Vous voudrez probablement le recadrer et faire ce que vous désirez en post-traitement.


Remarque: il peut être intéressant de passer à une précision supérieure (16+ bit int ou float) après avoir obtenu l’image de différence, afin de réduire au minimum les erreurs d’arrondi dans les normalisations répétées.

20
Dan Mašek

Ce dont vous avez besoin est seuillage . Cela vous permettra de définir tout ce qui n'est pas très sombre sur blanc pur et de définir le matériau très sombre sur un noir droit (ou toute autre couleur). Cela devrait vous aider à démarrer:

cutoff_val = 100 # everything above this is set to set_color
set_color = 255 
ret,thresh_img = cv2.threshold(image,cutoff_val,set_color,cv2.THRESH_BINARY)

Après avoir joué avec cela, vous pouvez obtenir de meilleurs résultats en utilisant seuillage adaptatif .

Voir ce bon tutoriel faire ce que vous voulez en gros - et en prime, il comprend un tutoriel sur le gauchissement pour obtenir également une région rectangulaire pour le papier!

Edit: j'ai obtenu de très bons résultats avec votre image combinant seuillage puis seuillage adaptatif.

cutoff_val = 150 # everything above this is set to the cutoff val
set_color = 255 # if 
ret,thresh_img = cv2.threshold(image,cutoff_val,set_color,cv2.THRESH_TRUNC)
window_sz = 3
thresh_img2 = cv2.adaptiveThreshold(thresh_img,set_color,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
            cv2.THRESH_BINARY,window_sz,2)
2