Écrivez le code pour binariser tous les fichiers TIFF dans le dossier spécifié.
Il est vraiment facile de creuser un dossier. Il y avait une méthode appelée os.walk (). Il n'est pas nécessaire de créer une fonction comme finddir () et de l'appeler récursivement.
import os
for root, dirs,files in os.walk("."):
for f in files:
print(os.path.join(root, f))
C'est pourquoi j'ai pu afficher tous les fichiers du dossier actuel.
Avec os.walk (), vous pouvez obtenir tous les fichiers et tous les sous-répertoires sous le répertoire spécifié comme une liste de fichiers racine, dir,. Dans ce cas, les fichiers sont une liste de fichiers, donc récupérez-les un par un tout en les stockant dans une variable appelée f. Vous pouvez le joindre en tant que chemin de fichier à partir de la racine en faisant os.path.join ().
Exécute le traitement de binarisation pour tous les fichiers image dans le dossier spécifié.
import cv2
import os
import numpy as np
from matplotlib import pyplot as plt
for root,dirs,files in os.walk("img"):
for f in files:
if os.path.splitext(f)[1] == ".tiff":
img = cv2.imread(os.path.join(root, f), 0)
blur = cv2.GaussianBlur(img,(5,5),0)
ret,imgb = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
Pour le moment, tous les fichiers du dossier img avec l'extension ".tiff" peuvent être binarisés. Tout d'abord, en spécifiant 0 comme deuxième argument avec cv2.imread (), le fichier image est lu comme une image grise, puis le flou gaussien est appliqué avec cv2.GaussianBlur (). Après cela, binarisez avec cv2.THRESH_BINARY + cv2.THRESH_OTSU.
La valeur de retour de cv2.threshold () est une image binarisée cette fois, il s'agit donc d'un tableau à deux dimensions, et 0 ou 255 sont stockés pour chaque pixel. Par exemple, un motif à damier noir et blanc 3x3 ressemble à ceci.
([255,0,255],
[0,255,0]
[255,0,255])
L'image binarisée est une image noire sur fond blanc. Un pixel noir est un pixel dont l'élément est 0. Donc, si vous scannez tous ces pixels et comptez le nombre de pixels qui ont un signal, obtenez les tailles verticale et horizontale de l'image, et de (x, y) = (0,0), (x, y) Le processus sera répété jusqu'à = (max (x), max (y)).
Les coordonnées du fichier image sont en quelque sorte écrites comme (x, y) sur l'axe horizontal X axe vertical Y, mais les informations de pixel de l'image acquise sous la forme d'un tableau bidimensionnel de numpy sont de l'ordre de "ligne" et "colonne". Puisqu'il est décrit, lors de l'extraction du signal du pixel à la position de (x, y) = (300, 200) confirmée par ImageJ etc. à partir du tableau numpy, il est nécessaire de le spécifier comme tableau [200, 300]. .. Si vous y réfléchissez, vous pouvez le comprendre, mais je fais souvent une erreur.
Voici un affichage qui compte le nombre de pixels noirs d'une image binarisée noire sur fond blanc.
cnt=0
for x in range(0, imgb.shape[0]):
for y in range(0, imgb.shape[1]):
if imgb[x,y] == 0:
cnt += 1
print(cnt)
En réalité, il s'agit d'un tableau numpy, donc si vous voulez juste analyser tous les éléments, c'est un peu plus facile.
cnt =0
for val in imgb.flat:
if val == 0:
cnt += 1
print(cnt)
J'ai eu une erreur lorsque j'ai écrit l'incrément cnt comme cnt ++ comme d'autres langages.
Le code jusqu'à présent peut être résumé comme suit. Pour uniquement le fichier ".tiff" sous le dossier img, l'image est binarisée et le nombre de pixels avec un signal de 0 est compté.
import numpy as np
import cv2
from matplotlib import pyplot as plt
import os
for root,dirs,files in os.walk("img"):
for f in files:
if os.path.splitext(f)[1] == ".tiff":
img = cv2.imread(os.path.join(root, f), 0)
blur = cv2.GaussianBlur(img,(5,5),0)
ret,imgb = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cnt = 0
for val in imgb.flat:
if val == 0:
cnt += 1
print( f + ":\t" + str(cnt) )
Puisque le traitement ci-dessus est le dossier img fixe ou l'extension .tiff fixe, une série de traitements est résumée en tant que fonction afin que cela puisse être spécifié librement. Le premier argument est le dossier cible et le deuxième argument est l'extension du fichier cible.
import numpy as np
import cv2
from matplotlib import pyplot as plt
import os
def convert_and_count( dir, ext ):
for root,dirs,files in os.walk(dir):
for f in files:
if os.path.splitext(f)[1] == ext:
img = cv2.imread(os.path.join(root, f), 0)
blur = cv2.GaussianBlur(img,(5,5),0)
ret,imgb = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cnt = 0
for val in imgb.flat:
if val == 0:
cnt+=1
msg = f + ":\t" + str(cnt)
print( msg )
if __name__ == "__main__":
convert_and_count( "img", ".tiff" )
Si vous faites jusqu'à présent, le nid sera plus profond et les perspectives seront un peu pires. Puisque python exprime les blocs par le nombre de retraits, le nid devient de plus en plus profond lorsque vous essayez de faire quelque chose d'un peu compliqué. Vous devrez peut-être écrire le code dans des blocs appropriés pour qu'il n'aille pas trop loin. Parfois, lors de l'édition sur plusieurs éditeurs, les onglets et les espaces sont mélangés, et le niveau d'imbrication qui apparaît et l'imbrication que l'interpréteur python comprend sont incohérents, ce qui entraîne une erreur.
Cela n'a pas beaucoup de sens, mais quel pourcentage de la "zone noire" totale dans l'image binarisée? Si vous voulez demander cela, ajoutez une ligne pour calculer la sole dans la variable convert_and_count () définie.
def convert_and_count( dir, ext ):
for root,dirs,files in os.walk(dir):
for f in files:
if os.path.splitext(f)[1] == ext:
img = cv2.imread(os.path.join(root, f), 0)
blur = cv2.GaussianBlur(img,(5,5),0)
ret,imgb = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cnt = 0
for range in imgb.flat:
if val == 0:
cnt += 1
ratio = cnt / imgb.size
msg = f + ":\t" + str(ratio)
print( msg )
Que faire si vous souhaitez afficher le ratio calculé jusqu'à 3 chiffres? Une image comme printf («% .3f», ratio), en langage C. Quand j'y ai pensé, ça ressemblait à ceci.
msg = "%s:\t%.3f" % (f, ratio)
Comme mentionné ci-dessus, en utilisant Python, il était possible d'effectuer facilement la binarisation d'images.
Recommended Posts