T2映射后DICOM图像显示异常,求修复以正常显示
T2映射图像显示修复方案
需求说明
需要实现以下DICOM图像T2映射功能:
- 按
TE2 > TE1规则对指定路径下的DCM文件配对 - 通过公式
T2=(TE2-TE1)/(ln(S1)-ln(S2))计算每个像素的T2值 - 对所有符合条件的文件对重复计算
- 将每对T2值按像素累加后求平均值
- 将平均T2值重建为8位DICOM图像,在Scene2中完整显示并保存
当前代码问题
生成的T2映射图像在Scene2中显示错乱,无法和左侧DICOM图像一样正常展示,核心原因包括:T2值直接转uint8导致数值截断、QImage内存布局解析错误、缺少异常值处理。
修复后的完整代码
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) # 处理log(0)异常,限制T2值在合理医学范围 epsilon = 1e-6 signal1_safe = np.maximum(signal1, epsilon) signal2_safe = np.maximum(signal2, epsilon) t2_map = (te2 - te1) / (np.log(signal1_safe) - np.log(signal2_safe)) t2_map = np.clip(t2_map, 0, 1000) pixel_t2_values.append(t2_map) if not pixel_t2_values: print("未找到符合TE2>TE1的有效文件对") return # 计算平均T2值 averaged_t2_array = np.mean(pixel_t2_values, axis=0) # 将T2值归一化到0-255区间,避免直接转uint8丢失细节 t2_min = averaged_t2_array.min() t2_max = averaged_t2_array.max() if t2_max > t2_min: normalized_t2 = ((averaged_t2_array - t2_min) / (t2_max - t2_min)) * 255 else: normalized_t2 = np.zeros_like(averaged_t2_array) new_pixel_array = normalized_t2.astype(np.uint8) # 生成标准化的8位DICOM文件 new_dicom = dicom1.copy() 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) # 正确读取并显示图像,适配Scene2布局 new_dicom = pydicom.dcmread(output_file_path) pixel_array = new_dicom.pixel_array # 指定字节行间距,确保QImage正确解析像素内存布局 qimage = QImage(pixel_array.data, pixel_array.shape[1], pixel_array.shape[0], pixel_array.strides[0], QImage.Format_Grayscale8) pixmap = QPixmap.fromImage(qimage) self.scene2.clear() pixmap_item = QGraphicsPixmapItem(pixmap) self.scene2.addItem(pixmap_item) self.scene2.setSceneRect(pixmap_item.boundingRect()) # 自适应视图大小,和左侧图像显示逻辑保持一致 self.view2.fitInView(pixmap_item, Qt.KeepAspectRatio) self.view2.setScene(self.scene2)
关键修复点
- 数值范围处理:将T2值归一化到0-255区间,避免直接转
uint8导致的数值截断 - 异常值防护:添加
epsilon避免log(0)错误,用clip限制T2值在医学合理范围 - QImage内存解析:指定
strides[0]行间距,确保图像数据正确映射 - 显示逻辑对齐:使用
fitInView让视图自适应图像尺寸,和左侧显示逻辑保持一致
内容的提问来源于stack exchange,提问作者SUAH YU
相关产品推荐
相关产品推荐

