def load(**kwargs): """ Load volume data and managed in memory :param volume: volume data :param seriesuid: series uid :return: """ try: volume_path = kwargs['volumepath'] if not os.path.isfile(volume_path): return response(success=False, message='volume data not exist.') except Exception as err: return response(success=False, message=err.message) try: vol = cio.read_image(volume_path) os.remove(volume_path) size = vol.size().tolist() imageentity.set_volume(vol) imageentity.remove_child_entities() imageentity.add_child_entity(CellEntity(0, False)) imageentity.add_child_entity(CellEntity(1, False)) imageentity.add_child_entity(CellEntity(2, False)) imageentity.init_default_scenes(vol) log.dev_info("load volume succeed") return response(content=json.dumps(size), success=True, message='load volume succeed') except Exception as err: return response(success=False, message=err.message)
def mask_to_contours(mask_fp): """ Convert mask to contours :param mask_fp: Mask file path :return: Array of contours """ log.dev_info('Mask file path: {}'.format(mask_fp)) if not os.path.isfile(mask_fp): log.dev_error('Path {} is not a mask file') return None mask = cio.read_image(mask_fp) mask.from_numpy(mask.to_numpy(), np.uint8) size_x, size_y, slice_count = mask.size() slices = mask.to_numpy() rst = {} for index in range(slice_count): slice = slices[index] _, thresh = cv2.threshold(slice, 0, 255, cv2.THRESH_BINARY) _, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) if len(contours) == 0: continue graphics = [] for contour in contours: graphic = [] for cp in contour: pt = cp[0].tolist() pt.append(index + 1) graphic.append(pt) graphics.append(graphic) rst[index + 1] = graphics return rst
def contours_to_mask(mask_fp, contours): """ Convert contour to mask(.nii.gz) :param contours: dictionary of contours :param size: mask shape :return: mask file path """ mask = cio.read_image(mask_fp) size_x, size_y, slice_count = mask.size() mask.from_numpy(np.zeros(np.array([slice_count, size_y, size_x])), np.uint8) slices = mask.to_numpy() for index in contours: slice = slices[int(index) - 1] graphics = contours[index] for pts in graphics: num_pts = len(pts) for i in range(num_pts): pt = pts[i] prev = pts[num_pts - 1] if i == 0 else pts[i - 1] rr, cc, _ = line_aa(prev[1], prev[0], pt[1], pt[0]) rr[rr >= size_y] = size_y - 1 cc[cc >= size_x] = size_x - 1 slice[rr, cc] = 1 slices[int(index) - 1] = binary_fill_holes(slice).astype(np.uint8) mask.from_numpy(slices, np.uint8) cio.write_image(mask, mask_fp)
def seg(self, series_uid): try: series, msg = series_ctx.retrieve(series_uid=series_uid) if len(series) == 0: return False, 'series_uid is wrong' mask_fp = file_path_ferry.volumePath + r'{}_mask.nii.gz'.format(series_uid) if os.path.isfile(mask_fp): os.remove(mask_fp) volume_path = series[0].seriespixeldatafilepath im = read_image(volume_path) model = autoseg_load_model(r'D:\segmentation_model\VSEG_Heart_20180611_01', 0) seg = autoseg_volume(im, model) write_image(seg, mask_fp) return mask_fp, None except Exception as ex: return False, ex.message
def load_volume(self, volume_path, series_uid): """ Load volume data to memory :param volume: volumn data :param series_uid: series uid :return: True or False """ if volume_path is None: return False, 'Volume data is None.' im = read_image(volume_path) # manage volume data in a dictionary self.volumes[series_uid] = im # init config info of this volume self.configs[series_uid] = {} self.configs[series_uid]['size'] = [512, 512, 57] self.configs[series_uid]['center'] = im.center() self.configs[series_uid]['cursor'] = im.center() self.configs[series_uid]['spacing'] = im.spacing() # [1, 1, 1] self.configs[series_uid]['zoom_factor'] = 1 self.configs[series_uid]['win_center'] = 0 self.configs[series_uid]['win_width'] = 2000 self.configs[series_uid]['colormode'] = 0 self.configs[series_uid]['alpha'] = 1 self.configs[series_uid]['default_v'] = -1024 self.configs[series_uid]['transverse_axis'] = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] self.configs[series_uid]['saggital_axis'] = [[0, 1, 0], [0, 0, -1], [1, 0, 0]] self.configs[series_uid]['coronal_axis'] = [[1, 0, 0], [0, 0, -1], [0, 1, 0]] # switch current volume to this volume self.change_volume(series_uid) self.look_at['transverse'] = im.center() self.look_at['coronal'] = im.center() self.look_at['saggital'] = im.center() return True, 'Load succeed.'