DICOM images displaying strangely

67 Views Asked by At

See Image

I wish to write Python code to perform these functions:

  1. Among the DCM files entered in TE_lineedit, pair 2 files so that TE2 is greater than TE1.
  2. The T2 value for each pixel array is obtained through the formula T2=(TE2-TE1)/(ln(S1)-ln(S2)).
  3. Repeat for all pairs.
  4. The T2 value calculated for each pair is added for each pixel array, divided by the number of pairs, and averaged.
  5. The average T2 value for each pixel array is reconstructed into one 8-bit DICOM image, displayed in Scene2, and saved. and here's my code:
    def T2_Mapping(self):
        folder_path = self.TE_lineedit.text()
        dicom_files = [file_name for file_name in os.listdir(folder_path)
                       if os.path.isfile(os.path.join(folder_path, file_name)) and file_name.endswith('.dcm')]
        dicom_files.sort()
        pixel_t2_values = {}

        for i in range(len(dicom_files) - 1):
            dicom1 = pydicom.dcmread(os.path.join(folder_path, dicom_files[i]))
            te1 = dicom1.EchoTime
            signal1 = dicom1.pixel_array.astype(np.float32)

            for j in range(i + 1, len(dicom_files)):
                dicom2 = pydicom.dcmread(os.path.join(folder_path, dicom_files[j]))
                te2 = dicom2.EchoTime
                if te2 > te1:
                    signal2 = dicom2.pixel_array.astype(np.float32)
                    t2_map = np.zeros_like(signal1, dtype=np.uint8)
                    t2_map= (te2 - te1) /(np.log(signal1) - np.log(signal2))
                    if (i, j) not in pixel_t2_values:
                        pixel_t2_values[(i, j)] = t2_map
                    else:
                        pixel_t2_values[(i, j)] += t2_map
        if not pixel_t2_values:
            print("No valid pairs found with te2 > te1")
            return
        averaged_t2_array = np.zeros_like(signal1, dtype=np.float32)
        for value in pixel_t2_values.values():
            averaged_t2_array += value
        num_combinations = len(pixel_t2_values)
        averaged_t2_array /= num_combinations
        new_dicom = dicom1.copy()
        new_pixel_array = (averaged_t2_array).astype(np.uint8)
        new_dicom.PixelData = new_pixel_array.tobytes()
        new_dicom.Rows, new_dicom.Columns = new_pixel_array.shape
        new_dicom.BitsAllocated = 8
        new_dicom.BitsStored = 8
        new_dicom.HighBit = 7
        new_dicom.SamplesPerPixel = 1
        new_dicom.PhotometricInterpretation = "MONOCHROME2"
        new_dicom.PixelRepresentation = 0
        new_dicom.RescaleIntercept = 0
        new_dicom.RescaleSlope = 1
        output_file_path = os.path.join(folder_path, "t2_mapping.dcm")
        new_dicom.save_as(output_file_path)
        new_dicom = pydicom.dcmread(output_file_path)
        qimage = QImage(new_dicom.pixel_array.data, new_pixel_array.shape[1], new_pixel_array.shape[0],
                        QImage.Format_Grayscale8)
        pixmap = QPixmap.fromImage(qimage)
        scaled_pixmap = pixmap.scaled(450, 450, Qt.KeepAspectRatio)
        pixmap_item = QGraphicsPixmapItem(scaled_pixmap)
        self.scene2.clear()
        self.scene2.addItem(pixmap_item)
        self.scene2.setSceneRect(pixmap_item.boundingRect())
        self.view2.setScene(self.scene2)

I want to display the mapped image on the right, but I want to display it without breaking like the DICOM image displayed on the left.

1

There are 1 best solutions below

0
scaramallion On

You're recasting the dtype of the array from float32 to uint8 without properly downscaling the array values:

averaged_t2_array = np.zeros_like(signal1, dtype=np.float32)
# skipped
new_pixel_array = (averaged_t2_array).astype(np.uint8)

So any value in averaged_t2_array above 255 is being overflowed.

>>> arr = np.asarray([0, 300], dtype="float32")
>>> arr.astype("uint8")
array([ 0, 44], dtype=uint8)
>>>