La réduction d'échelle signifie ici une réduction d'échelle en termes d'échantillonnage d'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.
J'emprunterai le torse de JIRA. Celui avec LEE signifie image non compressée. Utilisez ceci. Exemple d'image
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()
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()
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.
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.
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()
C'est ça. C'est l'image que je recherchais.
Visionary Imaging Services, Inc.