使用 12 位图像从头开始创建新的 DICOM
Creating new DICOM from sratch using 12 bit images
我正在尝试使用 pydicom 从 sratch 创建一个新的 dicom 文件。我在来自 Whosebug and the pydicom github examples 的以下链接的帮助下构建了一个文件。这是我的功能:
def generate_dicom(pixel_array,filename):
sop_uid = pydicom.uid.generate_uid()
sop_class_uid = pydicom._storage_sopclass_uids.ComputedRadiographyImageStorage
#create metadata
file_meta = Dataset()
file_meta.MediaStorageSOPClassUID = sop_class_uid
file_meta.MediaStorageSOPInstanceUID = sop_uid
file_meta.ImplementationClassUID = '1.2.276.0.7230010.3.0.3.6.2'
file_meta.FileMetaInformationGroupLength = 218
file_meta.FileMetaInformationVersion = b'\x00\x01'
file_meta.ImplementationVersionName = 'OFFIS_DCMTK_362'
file_meta.SourcApplicationEntitTitle = 'AZMED'
ds = FileDataset(filename, {},file_meta = file_meta,preamble=b"\x00" * 128)
# Set the transfer syntax implicitly, if not set explicitly above
ds.is_little_endian = True
ds.is_implicit_VR = True
#change modality
ds.Modality = 'CR'
# Set creation date/time
dt = datetime.datetime.now()
ds.ContentDate = dt.strftime('%Y%m%d')
timeStr = dt.strftime('%H%M%S.%f') # long format with micro seconds
ds.ContentTime = timeStr
ds.StudyInstanceUID = pydicom.uid.generate_uid()
ds.SeriesInstanceUID = pydicom.uid.generate_uid()
ds.SOPInstanceUID = sop_uid
ds.SOPClassUID = sop_class_uid
ds.SecondaryCaptureDeviceManufctur = 'AZMed_SAS'
ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
# set patient name and ID
ds.PatientName = "Test^Firstname"
ds.PatientID = "123456"
## These are the necessary imaging components of the FileDataset object.
# we create 16 bit pixel arrays here
ds.SamplesPerPixel = 1
ds.PhotometricInterpretation = "MONOCHROME2"
ds.PixelRepresentation = 0
ds.HighBit = 15
ds.BitsStored = 16
ds.BitsAllocated = 16
#ds.SmallestImagePixelValue = b"\x00\x00"
#ds.LargestImagePixelValue = b"\xff\xff"
ds.Columns = pixel_array.shape[0]
ds.Rows = pixel_array.shape[1]
if pixel_array.dtype != np.uint16:
pixel_array = pixel_array.astype(np.uint16)
ds.PixelData = pixel_array.tostring()
ds.ImagesInAcquisition = "1"
# reutrn the dataset of dicom
return ds
对于这个函数,我使用 cv2 传递图像:
new_pixel_array = cv2.imread('/home/toing/image_01.png', -1)
当我以形状 (1500, 200)
传递 new_pixel_array
时,使用 12 位值并向我的函数键入 uint16
时,当我尝试读取生成的 dicom 时,我得到一个非常模糊的图像.
ds = generate_dicom(new_pixel_array, 'toing.dcm')
ds.pixel_array
但是,当我尝试通过时:
x = np.arange(16).reshape(16,1)
new_pixel_array = (x + x.T) * 32
new_pixel_array = np.tile(new_pixel_array,(16,16))
按照 this 回答中的建议,我得到了正确显示的所需平铺图像。
我也尝试在传递给我的函数之前将 new_pixel_array 转换为 8 位值,但我仍然得到相同的结果。另一方面,生成的平铺图像在转换时工作正常。
我在这里做错了什么?
在我看来,尺寸设置不正确。
如果我理解正确的话,你的图片应该是 (1500, 200)
,即高度为 1500 像素,宽度为 200 像素。
ds.Columns = pixel_array.shape[0] # 1500
ds.Rows = pixel_array.shape[1] # 200
在您提供的代码段中,您将宽度或列设置为形状的第一个值。
尝试更改这些值
我正在尝试使用 pydicom 从 sratch 创建一个新的 dicom 文件。我在来自 Whosebug and the pydicom github examples 的以下链接的帮助下构建了一个文件。这是我的功能:
def generate_dicom(pixel_array,filename):
sop_uid = pydicom.uid.generate_uid()
sop_class_uid = pydicom._storage_sopclass_uids.ComputedRadiographyImageStorage
#create metadata
file_meta = Dataset()
file_meta.MediaStorageSOPClassUID = sop_class_uid
file_meta.MediaStorageSOPInstanceUID = sop_uid
file_meta.ImplementationClassUID = '1.2.276.0.7230010.3.0.3.6.2'
file_meta.FileMetaInformationGroupLength = 218
file_meta.FileMetaInformationVersion = b'\x00\x01'
file_meta.ImplementationVersionName = 'OFFIS_DCMTK_362'
file_meta.SourcApplicationEntitTitle = 'AZMED'
ds = FileDataset(filename, {},file_meta = file_meta,preamble=b"\x00" * 128)
# Set the transfer syntax implicitly, if not set explicitly above
ds.is_little_endian = True
ds.is_implicit_VR = True
#change modality
ds.Modality = 'CR'
# Set creation date/time
dt = datetime.datetime.now()
ds.ContentDate = dt.strftime('%Y%m%d')
timeStr = dt.strftime('%H%M%S.%f') # long format with micro seconds
ds.ContentTime = timeStr
ds.StudyInstanceUID = pydicom.uid.generate_uid()
ds.SeriesInstanceUID = pydicom.uid.generate_uid()
ds.SOPInstanceUID = sop_uid
ds.SOPClassUID = sop_class_uid
ds.SecondaryCaptureDeviceManufctur = 'AZMed_SAS'
ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
# set patient name and ID
ds.PatientName = "Test^Firstname"
ds.PatientID = "123456"
## These are the necessary imaging components of the FileDataset object.
# we create 16 bit pixel arrays here
ds.SamplesPerPixel = 1
ds.PhotometricInterpretation = "MONOCHROME2"
ds.PixelRepresentation = 0
ds.HighBit = 15
ds.BitsStored = 16
ds.BitsAllocated = 16
#ds.SmallestImagePixelValue = b"\x00\x00"
#ds.LargestImagePixelValue = b"\xff\xff"
ds.Columns = pixel_array.shape[0]
ds.Rows = pixel_array.shape[1]
if pixel_array.dtype != np.uint16:
pixel_array = pixel_array.astype(np.uint16)
ds.PixelData = pixel_array.tostring()
ds.ImagesInAcquisition = "1"
# reutrn the dataset of dicom
return ds
对于这个函数,我使用 cv2 传递图像:
new_pixel_array = cv2.imread('/home/toing/image_01.png', -1)
当我以形状 (1500, 200)
传递 new_pixel_array
时,使用 12 位值并向我的函数键入 uint16
时,当我尝试读取生成的 dicom 时,我得到一个非常模糊的图像.
ds = generate_dicom(new_pixel_array, 'toing.dcm')
ds.pixel_array
x = np.arange(16).reshape(16,1)
new_pixel_array = (x + x.T) * 32
new_pixel_array = np.tile(new_pixel_array,(16,16))
按照 this 回答中的建议,我得到了正确显示的所需平铺图像。
我也尝试在传递给我的函数之前将 new_pixel_array 转换为 8 位值,但我仍然得到相同的结果。另一方面,生成的平铺图像在转换时工作正常。 我在这里做错了什么?
在我看来,尺寸设置不正确。
如果我理解正确的话,你的图片应该是 (1500, 200)
,即高度为 1500 像素,宽度为 200 像素。
ds.Columns = pixel_array.shape[0] # 1500
ds.Rows = pixel_array.shape[1] # 200
在您提供的代码段中,您将宽度或列设置为形状的第一个值。
尝试更改这些值