Пример #1
0
 def fileopen():
     filename = filedialog.askopenfilename(
         filetypes=[('mhd files',
                     '*.mhd'), ('dicom files',
                                '*.dcm'), ('numpy files',
                                           '*.npy'), ('all', '*')])
     #filename = "E:/tianchi_project/TIANCHI_examples/train_1/LKDS-00001.mhd"
     if filename == '':
         return
     print(repr(filename))
     prename, extname = os.path.splitext(filename)
     if extname == '.mhd':
         full_image_info = sitk.ReadImage(filename)
         full_scan = sitk.GetArrayFromImage(full_image_info)
         old_spacing = np.array(full_image_info.GetSpacing())[::-1]
         volimg, new_spacing = mt.resample(full_scan, old_spacing)
     elif extname == '.dcm':
         pathname = os.path.split(filename)[0]
         full_scan, full_image_info, patientid = mt.read_dicom_scan(
             pathname)
         cvm.view_CT(full_scan)
         old_spacing = np.array(full_image_info.GetSpacing())[::-1]
         volimg, new_spacing = mt.resample(full_scan, old_spacing)
     elif extname == '.npy':
         volimg = np.load(filename)
     else:
         print('unknown data type')
         return
     label = tk.Label(tool_view, image=cvm.view_CT(volimg))
     label.pack()
     tool_view.quit()
Пример #2
0
    def annotations_crop(self, overbound=True, candsample=False):
        if os.access(self.output_path, os.F_OK):
            shutil.rmtree(self.output_path)
        os.makedirs(self.output_path)
        os.mkdir(self.nodules_npy_path)
        os.mkdir(self.nonnodule_npy_path)

        if not os.access(self.vision_path, os.F_OK):
            os.makedirs(self.vision_path)

        for patient in enumerate(tqdm(self.ls_all_patients[814:])):
            patient = patient[1]
            #patient = "./SLH_data/0721/285 0800418645"
            print(patient)
            full_scan, full_image_info, patient_uid = mt.read_dicom_scan(
                patient)
            if full_scan.min() < -1024:
                errorlog = open("results/error.log", "w")
                errorlog.write("Hu unit incorrect:%s\n" % (patient))
                errorlog.close()
            origin = np.array(
                full_image_info.GetOrigin())[::-1]  #---获取“体素空间”中结节中心的坐标
            old_spacing = np.array(full_image_info.GetSpacing()
                                   )[::-1]  #---该CT在“世界空间”中各个方向上相邻单位的体素的间距
            min_space = old_spacing.min()
            image, new_spacing = mt.resample(full_scan, old_spacing)  #---重采样
            print('resample done')

            silist = self.df_annotations.serie_id.tolist()
            if silist.count(patient_uid) == 0:
                print('no annotation for this patient found')
                continue
            serie_index = silist.index(patient_uid)
            patient_nodules = []
            for annocol in self.annotation_columns:
                annostr = self.df_annotations.get(annocol)[serie_index]
                if type(annostr) == unicode:
                    #annotation = np.array(annostr.split(u'\uff08')[0].split(' '), dtype=int)
                    #patient_nodules.append([serie_index, annotation]) #the index order is [x,y,z]
                    if annostr.find(u'*') >= 0:
                        continue
                    coordbegin = -1
                    coordend = -1
                    for ci in range(len(annostr)):
                        if coordbegin < 0:
                            if annostr[ci] >= u'0' and annostr[ci] <= u'9':
                                coordbegin = ci
                        elif (annostr[ci] < u'0'
                              or annostr[ci] > u'9') and annostr[ci] != u' ':
                            coordend = ci
                            break
                    if coordbegin >= 0:
                        if coordend < 0:
                            coordend = len(annostr)
                        coordstr = annostr[coordbegin:coordend]
                        annotation = np.array(coordstr.split(u' '), dtype=int)
                        patient_nodules.append(
                            [annocol,
                             annotation])  # the index order is [x,y,z]
                if type(annostr) == str:
                    if annostr.find('*') >= 0:
                        continue
                    coordbegin = -1
                    coordend = -1
                    for ci in range(len(annostr)):
                        if coordbegin < 0:
                            if annostr[ci] >= '0' and annostr[ci] <= '9':
                                coordbegin = ci
                        elif (annostr[ci] < '0'
                              or annostr[ci] > '9') and annostr[ci] != ' ':
                            coordend = ci
                            break
                    if coordbegin >= 0:
                        # annotation = np.array(annostr.split('(')[0].split(' '), dtype=int)
                        if coordend < 0:
                            coordend = len(annostr)
                        coordstr = annostr[coordbegin:coordend]
                        annotation = np.array(coordstr.split(' '), dtype=int)
                        patient_nodules.append(
                            [annocol,
                             annotation])  # the index order is [x,y,z]

            v_centers = []
            center_coords = []
            for annocol, nodule in patient_nodules:
                nodule_center = np.array(np.flip(nodule, axis=0) *
                                         old_spacing / new_spacing,
                                         dtype=int)  #---获取“世界空间”中结节中心的坐标
                #v_center = np.rint((nodule_center - origin) / new_spacing) #映射到“体素空间”中的坐标
                #v_center = np.array(v_center, dtype=int)
                v_centers.append([annocol, nodule_center])
                center_coords.append(nodule_center)
            #volume_regioned = cv.view_coordinations(image, center_coords, window_size=10, reverse=False, slicewise=False, show=False)
            #cv.view_CT(volume_regioned)
            #np.save(self.vision_path+"/"+patient_uid+"_annotated.mhd", volume_regioned)
            #---这一系列的if语句是根据“判断一个结节的癌性与否需要结合该结节周边位置的阴影和位置信息”而来,故每个结节都获取了比该结节尺寸略大的3D体素

            #get annotations nodule
            window_half = int(BOX_SIZE / 2)
            if overbound:
                box_size = 2 * BOX_SIZE
                box_half = BOX_SIZE
            else:
                box_size = BOX_SIZE
                box_half = window_half

            for annocol, v_center in v_centers:
                zyx_1 = v_center - box_half  # 注意是: Z, Y, X
                zyx_2 = v_center + box_half
                if mt.coord_overflow(zyx_1, image.shape) or mt.coord_overflow(
                        zyx_2, image.shape):
                    zyx_1_fix = zyx_1.copy()
                    zyx_2_fix = zyx_2.copy()
                    for ci in range(3):
                        if zyx_1[ci] < 0:
                            zyx_1_fix[ci] = 0
                        elif zyx_1[ci] >= image.shape[ci]:
                            zyx_1_fix[ci] = image.shape[ci]
                        if zyx_2[ci] < 0:
                            zyx_2_fix[ci] = 0
                        elif zyx_2[ci] >= image.shape[ci]:
                            zyx_2_fix[ci] = image.shape[ci]
                    img_crop = image[zyx_1_fix[0]:zyx_2_fix[0],
                                     zyx_1_fix[1]:zyx_2_fix[1],
                                     zyx_1_fix[2]:zyx_2_fix[2]]
                    img_crop[img_crop < -1024] = -1024
                    #if img_crop.max() >= 600:
                    #	padding_value = 600
                    #elif img_crop.max() >= 0:
                    #	padding_value = img_crop.max()
                    #else:
                    #	padding_value = -1024
                    padding_value = -1024
                    nodule_box = padding_value * np.ones(
                        [box_size, box_size, box_size], int)
                    nodule_box[zyx_1_fix[0] - zyx_1[0]:zyx_2_fix[0] - zyx_1[0],
                               zyx_1_fix[1] - zyx_1[1]:zyx_2_fix[1] - zyx_1[1],
                               zyx_1_fix[2] - zyx_1[2]:zyx_2_fix[2] -
                               zyx_1[2]] = img_crop
                else:
                    #nodule_box = np.zeros([box_size, box_size, box_size], np.int16)
                    img_crop = image[zyx_1[0]:zyx_2[0], zyx_1[1]:zyx_2[1],
                                     zyx_1[2]:zyx_2[2]]  # ---截取立方体
                    img_crop[img_crop <
                             -1024] = -1024  # ---设置窗宽,小于-1024的体素值设置为-1024
                    nodule_box = img_crop[0:box_size, 0:box_size,
                                          0:box_size]  # ---将截取的立方体置于nodule_box
                self.save_annotations_nodule(
                    nodule_box, patient_uid + "_" + annocol + "_ob")
            print("annotation sampling done")

            #get candidate annotation nodule
            candidate_coords = []
            if candsample:
                segimage, segmask, flag = cd.segment_lung_mask(image)
                if segimage is not None:
                    nodule_matrix, index = cd.candidate_detection(
                        segimage, flag)
                    cluster_labels = lc.seed_mask_cluster(nodule_matrix,
                                                          cluster_size=1000)
                    #cluster_labels = lc.seed_volume_cluster(image, segmask, eliminate_lower_size=-1)
                    #segresult = lc.segment_color_vision(image, cluster_labels)
                    #cv.view_CT(segresult)
                    #lc.cluster_size_vision(cluster_labels)
                    candidate_coords, _ = lc.cluster_centers(cluster_labels)
                    #candidate_coords = lc.cluster_center_filter(image, candidate_coords)
                #the coordination order is [z,y,x]
                print("candidate number:%d" % (len(candidate_coords)))
                #volume_regioned = cv.view_coordinations(image, candidate_coords, window_size=10, reverse=False, slicewise=True, show=False)
                #mt.write_mhd_file(self.vision_path+"/"+patient_uid+"_candidate.mhd", volume_regioned, volume_regioned.shape[::-1])
                for cc in range(len(candidate_coords)):
                    candidate_center = candidate_coords[cc]
                    invalid_loc = False
                    if mt.coord_overflow(candidate_center - window_half,
                                         image.shape) or mt.coord_overflow(
                                             candidate_center + BOX_SIZE -
                                             window_half, image.shape):
                        invalid_loc = True
                        continue
                    for index_search, v_center_search in v_centers:
                        rpos = v_center_search - candidate_center
                        if abs(rpos[0]) < window_half and abs(
                                rpos[1]
                        ) < window_half and abs(
                                rpos[2]
                        ) < window_half:  #the negative sample is located in the positive location
                            invalid_loc = True
                            break
                    if not invalid_loc:
                        zyx_1 = candidate_center - window_half
                        zyx_2 = candidate_center + BOX_SIZE - window_half
                        nodule_box = np.zeros(
                            [BOX_SIZE, BOX_SIZE, BOX_SIZE],
                            np.int16)  #---nodule_box_size = 45
                        img_crop = image[zyx_1[0]:zyx_2[0], zyx_1[1]:zyx_2[1],
                                         zyx_1[2]:zyx_2[2]]  #---截取立方体
                        img_crop[img_crop <
                                 -1024] = -1024  #---设置窗宽,小于-1000的体素值设置为-1000
                        if img_crop.shape[0] != BOX_SIZE | img_crop.shape[
                                1] != BOX_SIZE | img_crop.shape[2] != BOX_SIZE:
                            print("error in resmapleing shape")
                        try:
                            nodule_box[
                                0:BOX_SIZE, 0:BOX_SIZE, 0:
                                BOX_SIZE] = img_crop  # ---将截取的立方体置于nodule_box
                        except:
                            print("random error")
                            continue
                        #nodule_box[nodule_box == 0] = -1024#---将填充的0设置为-1000,可能有极少数的体素由0=>-1000,不过可以忽略不计
                        self.save_nonnodule(nodule_box,
                                            patient_uid + "_cc_" + str(cc))
                print("candidate sampling done")
            print('Done for this patient!\n\n')
        print('Done for all!')
    results = []
    CPMs = []
    CPMs2 = []
    test_patients = all_patients
    bt.filelist_store(all_patients, evaluation_path + "/patientfilelist.log")
    #random.shuffle(test_patients)
    for p in range(len(test_patients)):
        result = []
        patient = test_patients[p]
        #uid = mt.get_mhd_uid(patient)
        #annotations = mt.get_luna_annotations(uid, annotation_file)
        #if len(annotations)==0:
        #print('%d/%d patient %s has no annotations, ignore it.' %(p+1, len(test_patients), uid))
        #continue

        full_scan, image_info = mt.read_dicom_scan(patient)
        uid = image_info['uid']
        print('%d/%d processing patient:%s' % (p + 1, len(test_patients), uid))

        origin = image_info['origin']
        old_spacing = image_info['spacing']
        image, new_spacing = mt.resample(full_scan, old_spacing)  #resample
        print('Resample Done. time:{}s'.format(time.time() - start_time))

        #make a real nodule visualization
        real_nodules = []
        #for annotation in annotations:
        #real_nodule = np.int_([abs(annotation[2]-origin[0])/new_spacing[0], abs(annotation[1]-origin[1])/new_spacing[1], abs(annotation[0]-origin[2])/new_spacing[2]])
        #real_nodules.append(real_nodule)
        if 'vision_path' in dir() and 'vision_path' is not None:
            annotation_vision = cvm.view_coordinates(image,