[PYTHON] Réduction de l'échelle de gris 8 bits des images et du contraste de l'image

supposition

La réduction d'échelle signifie ici une réduction d'échelle en termes d'échantillonnage d'image.

Mise à l'échelle de l'image

Ici, nous parlerons des images en échelle de gris. Généralement, une image en échelle de gris est composée d'une collection de pixels «1 canal» tels que 8 bits, 16 bits, 32 bits, etc. (Les images couleur telles que RVB ont des canaux R, V et B, et ceux-ci sont intégrés dans une image. Ceci est important. En d'autres termes, une image RVB a trois images en niveaux de gris 8 bits. À proprement parler, il peut y avoir un composant α (un composant qui spécifie la transparence), mais le composant α ressemble également à une image en niveaux de gris 8 bits augmentée de un.)

Les images 16 bits sont souvent utilisées dans les images médicales. Les images 16 bits peuvent contenir des nombres compris entre 0 et 65535 en tant que valeurs de pixels. En revanche, les images 8 bits ne peuvent contenir que des nombres de 0 à 255. (Signé et non signé ne sont pas mentionnés ici.)

Dans le traitement d'image et l'apprentissage automatique, les images à bits élevés sont réduites à l'échelle et converties en images 8 bits afin de simplifier les calculs ou d'accélérer le traitement. Veuillez noter que si vous faites une erreur lors de cette réduction, l'image sera étrange.

exemple d'image

J'emprunterai le torse de JIRA. Celui avec LEE signifie image non compressée. Utilisez ceci. Exemple d'image

Exemple de réduction d'échelle (16 bits à 8 bits)

Tout d'abord, utilisez pydicom pour charger l'image et la traiter comme un ndarray numpy.

!pip install pydicom

Chargez les données.

import pydicom
import numpy as np
ds = pydicom.dcmread('CR_LEE_IR87a.dcm')#Spécifiez le chemin

#Extraire les pixels (traités comme ndarray)
pixels = ds.pixel_array

#Puisqu'il est retourné à gauche et à droite, retournez-le
pixels = np.fliplr(pixels)

#Afficher comme image
import matplotlib.pyplot as plt
plt.imshow(pixels,cmap="gray")#Les deux sont obligatoires
plt.show() 

ダウンロード (2).png

Pour être prudent, assurez-vous que cette image n'est pas 8 bits. Comme vous pouvez le voir sur la balise DICOM, vous pouvez également le voir en regardant directement les pixels.

#Jetez un œil aux pixels de cette image
print (pixels[512,512]) # 3186

Vous pouvez voir que la valeur du pixel au pixel (x, y) (512512) est 3186. En d'autres termes, il est 16 bits car il n'est pas compris entre 0 et 255 et ce n'est pas un nombre réel.

Vous êtes maintenant prêt.

numpy

Je vais simplement le convertir en 8 bits.

#Essayez la conversion 8 bits avec numpy
np_img = pixels.astype('uint8')
plt.imshow(np_img,cmap="gray")
plt.show() 

ダウンロード (3).png

C'est différent.

Pillow

#Utilisez un oreiller
from PIL import Image, ImageOps
pil_img = Image.fromarray(pixels)
pil_img = pil_img.convert('L')#L:grayscale
plt.imshow(pil_img,cmap="gray")#Les deux sont obligatoires
plt.show() 
print(np.asarray(pil_img)[512,512]) #255,Il se sent complètement hors de portée.

ダウンロード (4).png

Ceci est également différent.

OpenCV

#utiliser opencv
#Puisqu'il ne peut pas être converti par la méthode suivante, tapez un type de numpy à l'étape 1()Vous ne pourrez peut-être utiliser que la même méthode que la méthode de conversion avec.
#Peut-être que mon utilisation est erronée. .. Reportez-vous à cela comme un exemple de défaillance.
import cv2
cv_img16 = cv2.cvtColor(pixels, cv2.COLOR_BAYER_GR2GRAY)
cv_img8 = cv2.cvtColor(pixels, cv2.COLOR_BAYER_GR2GRAY) #Pour la copie et la conversion.
cv2.convertScaleAbs(cv_img16, cv_img8, 1/255,)#Non converti
plt.imshow(cv_img8,cmap="gray")
plt.show() 
print(cv_img8[512,512])#Confirmez qu'il n'est pas converti.

Scikit-image

#Utiliser skimage
import skimage
sk_img = skimage.img_as_ubyte(pixels)
plt.imshow(sk_img,cmap="gray")#Les deux sont obligatoires
plt.show() 

Oh! Je pense que c'est une tromperie, et si vous regardez de près, les pixels sont écrasés.

ダウンロード (5).png

Mise à l'échelle à l'aide de l'algorithme ImageJ

J'ai essayé d'implémenter ImageJ downscale. Normaliser avec des facteurs maximum, minimum et d'échelle.

#Normalisation empruntée à ImageJ
amin=np.amin(pixels)
amax=np.amax(pixels)
scale = 255.0/(amax-amin) # 256.0/(amax-amin+1)
pixelsByte = np.copy(pixels)
# pixelsByte = pixelsByte - amin #Il semble que la valeur minimale ne doit pas être différente.
pixelsByte = pixelsByte*scale # 0-Redimensionner à la plage de 255
# np.clip(pixelsByte,0,255) #C'était redondant
pixelsByte = np.uint8(pixelsByte) #Convertir en octets non signés

print(np.asarray(pixelsByte)[512,512])
plt.imshow(pixelsByte,cmap="gray")
plt.show() 

ダウンロード (6).png

C'est ça. C'est l'image que je recherchais.

Visionary Imaging Services, Inc.

Recommended Posts

Réduction de l'échelle de gris 8 bits des images et du contraste de l'image
Image en niveaux de gris et enregistrer au format csv
Comment régler le contraste de l'image en Python
Redimensionner l'image à la taille spécifiée et noircir les marges