def upload_study_me(file_path, host, port): file_dict = [] headers = {'Content-Type': 'multipart/related; '} request_json = { 'request': 'post', 'route': '/', 'inference_command': 'get-bounding-box-2d' } images = load_image_data(file_path) images = sort_images(images) width = 0 height = 0 count = 0 for image in images: try: dcm_file = pydicom.dcmread(image.path) if width == 0 or height == 0: width = dcm_file.Columns height = dcm_file.Rows count += 1 field = str(count) fo = open(image.path, 'rb').read() filename = os.path.basename(os.path.normpath(image.path)) file_dict.append((field, (filename, fo, 'application/dicom'))) except: print('File {} is not a DICOM file'.format(image.path)) continue print('Sending {} files...'.format(count)) request_json['depth'] = count request_json['height'] = height request_json['width'] = width file_dict.insert( 0, ('request_json', ('request', json.dumps(request_json).encode('utf-8'), 'text/json'))) me = MultipartEncoder(fields=file_dict) boundary = me.content_type.split('boundary=')[1] headers['Content-Type'] = headers['Content-Type'] + 'boundary="{}"'.format( boundary) r = requests.post('http://' + host + ':' + port + '/', data=me, headers=headers) if r.status_code != 200: print("Got error status code ", r.status_code) exit(1) multipart_data = decoder.MultipartDecoder.from_response(r) json_response = json.loads(multipart_data.parts[0].text) print("JSON response:", json_response)
def _get_images_and_masks(dicom_images, inference_results): if isinstance(dicom_images, str): images = load_image_data(dicom_images) images = sort_images(images) else: images = dicom_images if isinstance(inference_results, str): masks = [np.fromfile(inference_results, dtype=np.uint8)] else: masks = inference_results return (images, masks)
def upload_study_me(file_path, model_type, host, port, output_folder, attachments, override_inference_command=None, send_study_size=False): file_dict = [] headers = {'Content-Type': 'multipart/related; '} images = load_image_data(file_path) images = sort_images(images) if model_type == BOUNDING_BOX: print("Performing bounding box prediction") inference_command = 'get-bounding-box-2d' elif model_type == SEGMENTATION_MODEL: if images[0].position is None: # No spatial information available. Perform 2D segmentation print("Performing 2D mask segmentation") inference_command = 'get-probability-mask-2D' else: print("Performing 3D mask segmentation") inference_command = 'get-probability-mask-3D' else: inference_command = 'other' if override_inference_command: inference_command = override_inference_command request_json = { 'request': 'post', 'route': '/', 'inference_command': inference_command } count = 0 width = 0 height = 0 for att in attachments: count += 1 field = str(count) fo = open(att, 'rb').read() filename = os.path.basename(os.path.normpath(att)) file_dict.append((field, (filename, fo, 'application/octet-stream'))) for image in images: try: dcm_file = pydicom.dcmread(image.path) if width == 0 or height == 0: width = dcm_file.Columns height = dcm_file.Rows count += 1 field = str(count) fo = open(image.path, 'rb').read() filename = os.path.basename(os.path.normpath(image.path)) file_dict.append((field, (filename, fo, 'application/dicom'))) except: print('File {} is not a DICOM file'.format(image.path)) continue print('Sending {} files...'.format(len(images))) if send_study_size: request_json['depth'] = count request_json['height'] = height request_json['width'] = width file_dict.insert( 0, ('request_json', ('request', json.dumps(request_json).encode('utf-8'), 'text/json'))) me = MultipartEncoder(fields=file_dict) boundary = me.content_type.split('boundary=')[1] headers['Content-Type'] = headers['Content-Type'] + 'boundary="{}"'.format( boundary) r = requests.post('http://' + host + ':' + port + '/', data=me, headers=headers) if r.status_code != 200: print("Got error status code ", r.status_code) exit(1) multipart_data = decoder.MultipartDecoder.from_response(r) json_response = json.loads(multipart_data.parts[0].text) print("JSON response:", json_response) if model_type == SEGMENTATION_MODEL: mask_count = len(json_response["parts"]) # Assert that we get one binary part for each object in 'parts' # The additional two multipart object are: JSON response and request:response digests assert mask_count == len(multipart_data.parts) - 2, \ "The server must return one binary buffer for each object in `parts`. Got {} buffers and {} 'parts' objects" \ .format(len(multipart_data.parts) - 2, mask_count) masks = [ np.frombuffer(p.content, dtype=np.uint8) for p in multipart_data.parts[1:mask_count + 1] ] if images[0].position is None: # We must sort the images by their instance UID based on the order of the response: identifiers = [ part['dicom_image']['SOPInstanceUID'] for part in json_response["parts"] ] filtered_images = [] for id in identifiers: image = next((img for img in images if img.instanceUID == id)) filtered_images.append(image) test_inference_mask.generate_images_for_single_image_masks( filtered_images, masks, json_response, output_folder) else: test_inference_mask.generate_images_with_masks( images, masks, json_response, output_folder) print("Segmentation mask images generated in folder: {}".format( output_folder)) print("Saving output masks to files '{}/output_masks_*.npy".format( output_folder)) for index, mask in enumerate(masks): mask.tofile('{}/output_masks_{}.npy'.format( output_folder, index + 1)) elif model_type == BOUNDING_BOX: boxes = json_response['bounding_boxes_2d'] test_inference_boxes.generate_images_with_boxes( images, boxes, output_folder) with open(os.path.join(output_folder, 'response.json'), 'w') as outfile: json.dump(json_response, outfile)
def upload_study_me(file_path, is_segmentation_model, host, port): file_dict = [] headers = {'Content-Type': 'multipart/related; '} images = load_image_data(file_path) images = sort_images(images) if not is_segmentation_model: inference_command = 'get-bounding-box-2d' elif images[0].position is None: # No spatial information available. Perform 2D segmentation inference_command = 'get-probability-mask-2D' else: inference_command = 'get-probability-mask-3D' inference_command = "covid19" request_json = { 'request': 'post', 'route': '/', 'inference_command': inference_command } width = 0 height = 0 count = 0 for image in images: try: dcm_file = pydicom.dcmread(image.path) if width == 0 or height == 0: width = dcm_file.Columns height = dcm_file.Rows count += 1 field = str(count) fo = open(image.path, 'rb').read() filename = os.path.basename(os.path.normpath(image.path)) file_dict.append((field, (filename, fo, 'application/dicom'))) except: print('File {} is not a DICOM file'.format(image.path)) continue print('Sending {} files...'.format(count)) request_json['depth'] = count request_json['height'] = height request_json['width'] = width file_dict.insert( 0, ('request_json', ('request', json.dumps(request_json).encode('utf-8'), 'text/json'))) me = MultipartEncoder(fields=file_dict) boundary = me.content_type.split('boundary=')[1] headers['Content-Type'] = headers['Content-Type'] + 'boundary="{}"'.format( boundary) r = requests.post('http://' + host + ':' + port + '/', data=me, headers=headers) if r.status_code != 200: print("Got error status code ", r.status_code) exit(1) multipart_data = decoder.MultipartDecoder.from_response(r) json_response = json.loads(multipart_data.parts[0].text) print("JSON response:", json_response) mask_count = len(json_response["parts"]) masks = [ np.frombuffer(p.content, dtype=np.uint8) for p in multipart_data.parts[1:mask_count + 1] ] if is_segmentation_model: output_folder = 'output' if images[0].position is None: # We must sort the images by their instance UID based on the order of the response: identifiers = [ part['dicom_image']['SOPInstanceUID'] for part in json_response["parts"] ] filtered_images = [] for id in identifiers: image = next((img for img in images if img.instanceUID == id)) filtered_images.append(image) test_inference_mask.generate_images_for_single_image_masks( filtered_images, masks, output_folder) else: test_inference_mask.generate_images_with_masks( images, masks, output_folder) print("Segmentation mask images generated in folder: {}".format( output_folder)) print("Saving output masks to files 'output/output_masks_*.npy") for index, mask in enumerate(masks): mask.tofile('output/output_masks_{}.npy'.format(index + 1))
def worker(args, q_ind, q_value, r_ind, r_value): fd = load_object_detector(args.object_detector) dataset = "data/TinyTLP/" all_directories = get_directories(dataset) results = {} for directory in all_directories: try: results_dir = results[directory] = [] plotted = results[f"{directory}_plots"] = [] iou = results[f"{directory}_iou"] = [] errors = results[f"{directory}_errors"] = [] ground_truth_file = dataset + directory + "/groundtruth_rect.txt" images_wildcard = dataset + directory + "/img/*.jpg" images_filelist = glob(images_wildcard) images_filelist = sort_images(images_filelist) de = None if args.extract_density: # de = DensityExtractor(images_filelist[0], args) # de.create_grid() de = GaussianDensityExtractor(images_filelist[0], args) de.create_grid() # Extract all ground truths ground_truth, gt_measurements = extract_all_groud_truths( ground_truth_file) # Create PF w, h = map(int, ground_truth[0][3:5]) pf = create_particle_filter(ground_truth[0], q_value, r_value, images_filelist[0], args) # Create images iterator t = create_iterator(images_filelist, args) # Create data association da = MLPFAssociation(states=pf.S, R=r_value, H=pf.H, threshold=args.outlier_detector_threshold) # Iterate of every image features = None for i, im in enumerate(t): img = read_img(im) # Do prediction pf.predict() if i % args.resample_every == 0: # Compute features features = np.array(fd.compute_features(img)) if len(features) > 0: # Do data association if args.point_estimate: features = [ np.array([i[0] + w / 2, i[1] + h / 2]) for i in features ] psi, outlier, c = da.associate(features) pf.update(psi, outlier, c) else: pf.assign_predicted() else: pf.assign_predicted() gt = list(map(int, ground_truth[i])) x = pf.get_x().T # Plot features if args.should_plot: plot_result = plot(args, x, de, img, gt, features) if args.show_plots is False: plotted.append(plot_result) if args.extract_density: if args.should_plot is False: de.estimate(x) if args.point_estimate: v = np.linalg.norm([ de.xtmean - gt[1] - gt[3] / 2, de.ytmean - gt[2] - gt[4] / 2 ], axis=0) results_dir.append(v) else: v = np.linalg.norm([ de.xtmean - gt[1], de.ytmean - gt[2], (de.xbmean - de.xtmean) - gt[3], (de.ybmean - de.ytmean) - gt[4] ]) t.set_description(f"Last error: {v:3.4}") errors.append(v) if not args.point_estimate: iou.append( get_iou( [de.xtmean, de.ytmean, de.xbmean, de.ybmean], [gt[1], gt[2], gt[1] + gt[3], gt[2] + gt[4]])) results_dir.append([ de.xtmean, de.ytmean, de.xbmean - de.xtmean, de.ybmean - de.ytmean ]) except Exception as e: print(f"Crashed with error: {str(e)}. Q: {q_value}, R: {r_value}") if args.point_estimate: results_file = f"results/pf_R_{r_ind}_Q_{q_ind}_{args.object_detector}.pickle" else: results_file = f"results/pf_box_R_{r_ind}_Q_{q_ind}_{args.object_detector}.pickle" with open(results_file, 'wb') as fp: pickle.dump(results, fp)
def test_bkf_Q(dataset, all_directories, args): results = {} l = 2 R_value = 1 # Get images list from dataset dataset = "data/TinyTLP/" all_directories = get_directories(dataset) fd = load_object_detector(args.object_detector) for k, Q_value in enumerate(Q_values): for dir in all_directories: iou = [] results_dir = results[dir] = [] ground_truth_file = dataset + dir + "/groundtruth_rect.txt" images_wildcard = dataset + dir + "/img/*.jpg" images_filelist = glob(images_wildcard) images_filelist = sort_images(images_filelist) # Extract all ground truths ground_truth, gt_measurements = extract_all_groud_truths( ground_truth_file) # Create KF kf = create_box_kalman_filter(ground_truth[0], Q_value, R_value) # Iterate of every image t = tqdm(images_filelist[1:], desc="Processing") da = DataAssociation(R=kf.R, H=kf.H, threshold=1) # Create plot if should_plot is true if args.should_plot: fig, ax = create_fig_ax() features = {} for i, im in enumerate(t): img = read_img(images_filelist[i]) # Compute features features[i] = np.array(fd.compute_features(img)) # Do prediction mu_bar, Sigma_bar = kf.predict() # Do data association da.update_prediction(mu_bar, Sigma_bar) m = da.associate(features[i]) kf.update(m) gt = list(map(int, ground_truth[i])) kf_x = kf.get_x() if args.should_plot: plot_box_kf_result(ax, i, img, m, kf_x, ground_truth) iou.append( get_iou([kf_x[0], kf_x[1], kf_x[2], kf_x[3]], [gt[1], gt[2], gt[1] + gt[3], gt[2] + gt[4]])) results_dir.append( [kf_x[0], kf_x[1], kf_x[2] - kf_x[0], kf_x[3] - kf_x[1]]) print(f"Dataset: {dir}, IoU: {np.mean(iou), np.std(iou)}") with open( f"results/kalman_filter_box_R_{l}_Q_{k}_{args.object_detector}.pickle", 'wb') as fp: pickle.dump(results, fp)