Как выполнить выравнивание гистограммы для изображений DICOM, прочитанных с помощью SimpleITK - PullRequest
1 голос
/ 28 января 2020

Я пытаюсь выполнить выравнивание гистограммы для всех изображений, считанных из файла * .nii.gz.

Я пробовал этот код:

import SimpleITK as sitk
flair_file = '/content/gdrive/My Drive/Colab Notebooks/.../FLAIR.nii.gz'

images = sitk.ReadImage(flair_file)
print("Width: ", images.GetWidth())
print("Height:", images.GetHeight())
print("Depth: ", images.GetDepth())

print("Dimension:", images.GetDimension())
print("Pixel ID: ", images.GetPixelIDValue())
print("Pixel ID Type:", images.GetPixelIDTypeAsString())

С этим выводом:

Width:  240
Height: 240
Depth:  48
Dimension: 3
Pixel ID:  8
Pixel ID Type: 32-bit float

Но когда я пытаюсь выполнить выравнивание гистограммы с помощью OpenCV, я получаю ошибки:

images_array = sitk.GetArrayFromImage(images)
gray = cv2.cvtColor(images_array[24], cv2.COLOR_BGR2GRAY)

Вывод:

error: OpenCV(4.1.2) /io/opencv/modules/imgproc/src/color.simd_helpers.hpp:92: error: (-2:Unspecified error) in function 'cv::impl::{anonymous}::CvtHelper<VScn, VDcn, VDepth, sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [with VScn = cv::impl::{anonymous}::Set<3, 4>; VDcn = cv::impl::{anonymous}::Set<1>; VDepth = cv::impl::{anonymous}::Set<0, 2, 5>; cv::impl::{anonymous}::SizePolicy sizePolicy = (cv::impl::<unnamed>::SizePolicy)2u; cv::InputArray = const cv::_InputArray&; cv::OutputArray = const cv::_OutputArray&]'
> Invalid number of channels in input image:
>     'VScn::contains(scn)'
> where
>     'scn' is 1

Итак, я попробовал этот другой код :

images_array = sitk.GetArrayFromImage(images)
#gray = cv2.cvtColor(images_array[24], cv2.COLOR_BGR2GRAY)
output = cv2.equalizeHist(images_array[24])

Но я получаю эту ошибку:

error: OpenCV(4.1.2) /io/opencv/modules/imgproc/src/histogram.cpp:3429: error: (-215:Assertion failed) _src.type() == CV_8UC1 in function 'equalizeHist'

Как я могу выполнить выравнивание гистограммы для этих изображений DICOM (возможно, не используя OpenCV, а вместо этого вместо SimpleITK)?

UPDATE: Когда я запускаю эту команду:

print(images_array[24].shape, images_array[24].dtype)

я получаю это:

(240, 240) float32

1 Ответ

3 голосов
/ 28 января 2020

SimpleITK имеет функцию AdaptiveHistogramEqualization и работает с изображениями с плавающей точкой32. Вот как вы можете использовать это:

new_images = sitk.AdaptiveHistogramEqualization(images)

Обратите внимание, что это сделает выравнивание по всему трехмерному изображению. Если бы вы хотели сделать это по частям, то это выглядело бы примерно так:

new_images = []
for z in range(images.GetDepth()):
    new_images.append(sitk.AdaptiveHistogramEqualization(images[:,:,z])

ОБНОВЛЕНИЕ: Как указывает @blowekamp, ​​AHE не производит глобальное выравнивание гистограммы по всему изображению, но локальное выравнивание. Вот пример кода, который показывает, как использовать функцию HistogramMatching, как он его описал, для достижения глобального выравнивания гистограммы.

import SimpleITK as sitk
import numpy as np

# Create a noise Gaussian blob test image
img = sitk.GaussianSource(sitk.sitkFloat32, size=[240,240,48], mean=[120,120,24])
img = img + sitk.AdditiveGaussianNoise(img,10)

# Create a ramp image of the same size
h = np.arange(0.0, 255,1.0666666666, dtype='f4')
h2 = np.reshape(np.repeat(h, 240*48), (48,240,240))
himg = sitk.GetImageFromArray(h2)
print(himg.GetSize())

# Match the histogram of the Gaussian image with the ramp
result=sitk.HistogramMatching(img, himg)

# Display the 3d image
import itkwidgets
itkwidgets.view(result)

Обратите внимание, что itkwidgets позволяет просматривать трехмерное изображение в блокноте Jupyter. Вы можете увидеть гистограмму изображения там.

...