Skip to content

Instantly share code, notes, and snippets.

@pangyuteng
Last active May 24, 2024 08:06
Show Gist options
  • Save pangyuteng/803cf2fda3d7568aaa348fdd409937d7 to your computer and use it in GitHub Desktop.
Save pangyuteng/803cf2fda3d7568aaa348fdd409937d7 to your computer and use it in GitHub Desktop.
DO-NOT-USE dicom multiframe to single frame conversion
this gist is used as a supporting doc, in response to 
https://github.com/pydicom/pydicom/discussions/1705
import os
import sys
import pydicom
essential_group_list = [0x0008,0x0010,0x0018,0x0020,0x0028]
def main(input_file,output_folder):
os.makedirs(output_folder,exist_ok=True)
ds = pydicom.dcmread(input_file)
number_of_frames = int(ds.NumberOfFrames)
# requirements
assert(number_of_frames > 1)
assert(ds.pixel_array.shape[0]==number_of_frames)
assert('SharedFunctionalGroupsSequence' in ds)
assert('PerFrameFunctionalGroupsSequence' in ds)
assert(len(ds.SharedFunctionalGroupsSequence)==1)
assert(len(ds.PerFrameFunctionalGroupsSequence)==number_of_frames)
img = ds.pixel_array.squeeze()
for idx in range(number_of_frames):
target_file = os.path.join(output_folder,f'foobar.{idx:05d}.dcm')
file_meta = pydicom.dataset.FileMetaDataset()
file_meta.MediaStorageSOPClassUID = pydicom.uid.SecondaryCaptureImageStorage
file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid()
file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian # pydicom.uid.ExplicitVRLittleEndian
tmp_ds = pydicom.dataset.Dataset()
tmp_ds.file_meta = file_meta
tmp_ds.is_little_endian = tmp_ds.file_meta.TransferSyntaxUID.is_little_endian
tmp_ds.is_implicit_VR = tmp_ds.file_meta.TransferSyntaxUID.is_implicit_VR
essential_group_list = [0x0020,0x0028] # barebones...
for group in essential_group_list:
for k,v in ds.group_dataset(group).items():
tmp_ds[k]=v
foo = ds.SharedFunctionalGroupsSequence[0]
bar = ds.PerFrameFunctionalGroupsSequence[idx]
for tag_name in ['RescaleIntercept','RescaleSlope','RescaleType']:
if tag_name in foo[(0x0028,0x9145)][0]:
value = foo[(0x0028,0x9145)][0][tag_name].value
setattr(tmp_ds,tag_name,value)
del tmp_ds.NumberOfFrames
tmp_ds.InstanceNumber = idx+1
tmp_ds.PixelData = img[idx,:].squeeze().tobytes()
tmp_ds.save_as(target_file,write_like_original=False)
if __name__ == "__main__":
input_file = sys.argv[1]
output_folder = sys.argv[2]
raise NotImplementedError()
main(input_file,output_folder)
'''
** DISCLAIMER **
i definitely would not use the above.
only tested using 1 hologic tomosythesis multiframe file.
Clients should acknowledge and accept they are okay having private tags nuked.
Further, to prove this method works,
you'll need to gather dicom file flavors from your clients/institutions and then implement and verify
the output dicom files can be opened by downstream workstations
'''

So how do you split multi frame to single frame dicom images?


First you should google the current top results in google
keywords I used: "split dicom multiframe to single frame"
If you don't like the results you can check the below related links:


i reserve all rights to not respond to questions here XDDDD
please go to stackoverflow and ask your questions there!

--

@pangyuteng
Copy link
Author

pangyuteng commented Feb 1, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment