예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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))
예제 #5
0
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)
예제 #6
0
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)