DICOM结构坐标的快速提取

2024-06-10 11:21:41 发布

您现在位置:Python中文网/ 问答频道 /正文

使用numpy.reshape帮助很大,使用map帮助不大。有没有可能再加快一点?在

import pydicom
import numpy as np
import cProfile
import pstats


def parse_coords(contour):
    """Given a contour from a DICOM ROIContourSequence, returns coordinates
    [loop][[x0, x1, x2, ...][y0, y1, y2, ...][z0, z1, z2, ...]]"""
    if not hasattr(contour, "ContourSequence"):
        return [] # empty structure
    def _reshape_contour_data(loop):
        return np.reshape(np.array(loop.ContourData),
                          (3, len(loop.ContourData) // 3),
                          order='F')
    return list(map(_reshape_contour_data,contour.ContourSequence))


def profile_load_contours():
    rs = pydicom.dcmread('RS.gyn1.dcm')
    structs = [parse_coords(contour) for contour in rs.ROIContourSequence]


cProfile.run('profile_load_contours()','prof.stats')
p = pstats.Stats('prof.stats')
p.sort_stats('cumulative').print_stats(30)

使用从varianeclipse导出的实际结构集。在

^{pr2}$

大部分时间都在convert_DS_string。有可能让它更快吗?我想部分问题是坐标在DICOM文件中的存储效率不高。在

编辑: 为了避免MultiVal.__init__结尾处的循环,我想知道如何获取每个ContourData的原始双字符串并在其上使用numpy.fromstring。然而,我还没能得到原始的双弦。在


Tags: importnumpyloopmapreturnparsedefstats
1条回答
网友
1楼 · 发布于 2024-06-10 11:21:41

消除MultiVal.__init__中的循环并使用numpy.fromstring可以提供4倍以上的加速。我将在pydicom github上发表文章,看看是否有人对将其引入库代码感兴趣。有点难看。我希望得到进一步改进的建议。在

import pydicom
import numpy as np
import cProfile
import pstats


def parse_coords(contour):
    """Given a contour from a DICOM ROIContourSequence, returns coordinates
    [loop][[x0, x1, x2, ...][y0, y1, y2, ...][z0, z1, z2, ...]]"""
    if not hasattr(contour, "ContourSequence"):
        return [] # empty structure
    cd_tag = pydicom.tag.Tag(0x3006, 0x0050) # ContourData tag
    def _reshape_contour_data(loop):
        val = super(loop.__class__, loop).__getitem__(cd_tag).value
        try:
            double_string = val.decode(encoding='utf-8')
            double_vec = np.fromstring(double_string, dtype=float, sep=chr(92)) # 92 is '/'
        except AttributeError: # 'MultiValue'  has no 'decode' (bytes does)
            # It's already been converted to doubles and cached
            double_vec = loop.ContourData
        return np.reshape(np.array(double_vec),
                          (3, len(double_vec) // 3),
                          order='F')
    return list(map(_reshape_contour_data, contour.ContourSequence))


def profile_load_contours():
    rs = pydicom.dcmread('RS.gyn1.dcm')
    structs = [parse_coords(contour) for contour in rs.ROIContourSequence]


profile_load_contours()
cProfile.run('profile_load_contours()','prof.stats')
p = pstats.Stats('prof.stats')
p.sort_stats('cumulative').print_stats(15)

结果

^{pr2}$

相关问题 更多 >