问题
I'm trying to do histogram equalization to all images read from a *.nii.gz file.
I have tried this code:
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())
With this output:
Width: 240
Height: 240
Depth: 48
Dimension: 3
Pixel ID: 8
Pixel ID Type: 32-bit float
But when I try to do histogram equalization with OpenCV I get errors:
images_array = sitk.GetArrayFromImage(images)
gray = cv2.cvtColor(images_array[24], cv2.COLOR_BGR2GRAY)
Output:
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
So, I have tried this other code:
images_array = sitk.GetArrayFromImage(images)
#gray = cv2.cvtColor(images_array[24], cv2.COLOR_BGR2GRAY)
output = cv2.equalizeHist(images_array[24])
But I get this error:
error: OpenCV(4.1.2) /io/opencv/modules/imgproc/src/histogram.cpp:3429: error: (-215:Assertion failed) _src.type() == CV_8UC1 in function 'equalizeHist'
How can I do histogram equalization to those DICOM images (maybe not using OpenCV, and using instead SimpleITK)?
UPDATE:
When I run this command:
print(images_array[24].shape, images_array[24].dtype)
I get this:
(240, 240) float32
回答1:
SimpleITK does have an AdaptiveHistogramEqualization function, and it does work on float32 images. Here's how you could use it:
new_images = sitk.AdaptiveHistogramEqualization(images)
Note that this would do equalization across the whole 3d image. If you wanted to do it on a slice-by-slice basis, it'd look something like this:
new_images = []
for z in range(images.GetDepth()):
new_images.append(sitk.AdaptiveHistogramEqualization(images[:,:,z])
UPDATE: As pointed out by @blowekamp, AHE doesn't produce a global histogram equalization across the whole image, but a local equalization. Here is some example code that show's how to use the HistogramMatching function, as described by him, to achieve global histogram equalization.
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)
Note that itkwidgets allows you to view a 3d image in a Jupyter notebook. You can see the histogram of the image there.
来源:https://stackoverflow.com/questions/59947265/how-to-do-histogram-equalization-to-dicom-images-read-with-simpleitk