如何对使用 SimpleITK 读取的 DICOM 图像进行直方图均衡
How to do histogram equalization to DICOM images read with SimpleITK
我正在尝试对从 *.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)?
更新:
当我 运行 这个命令时:
print(images_array[24].shape, images_array[24].dtype)
我明白了:
(240, 240) float32
SimpleITK 确实有一个 AdaptiveHistogramEqualization 函数,它确实适用于 float32 图像。以下是您可以如何使用它:
new_images = sitk.AdaptiveHistogramEqualization(images)
请注意,这将对整个 3d 图像进行均衡。如果你想逐个切片地进行,它看起来像这样:
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 笔记本中查看 3d 图像。你可以在那里看到图像的直方图。
我正在尝试对从 *.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)?
更新:
当我 运行 这个命令时:
print(images_array[24].shape, images_array[24].dtype)
我明白了:
(240, 240) float32
SimpleITK 确实有一个 AdaptiveHistogramEqualization 函数,它确实适用于 float32 图像。以下是您可以如何使用它:
new_images = sitk.AdaptiveHistogramEqualization(images)
请注意,这将对整个 3d 图像进行均衡。如果你想逐个切片地进行,它看起来像这样:
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 笔记本中查看 3d 图像。你可以在那里看到图像的直方图。