Ejemplo n.º 1
0
 def test_load_file_from_stream(self):
     img_ref = image.load(tif_path)
     with open(tif_path, 'rb') as f:
         p = io.BytesIO(f.read())
         img = image.load(p)
     self.assertIsInstance(img, FileImage)
     self.assertEqual(img.center, img_ref.center)
Ejemplo n.º 2
0
 def test_load_dicom_from_stream(self):
     img_ref = image.load(dcm_path)
     with open(dcm_path, 'rb') as f:
         p = io.BytesIO(f.read())
         img = image.load(p)
     self.assertIsInstance(img, DicomImage)
     self.assertEqual(img.dpi, img_ref.dpi)
Ejemplo n.º 3
0
 def file_should_be_processed(self, filepath):
     """Decision of whether file should be run. Returns boolean."""
     try:
         image.load(filepath)
         return True
     except:
         return False
Ejemplo n.º 4
0
 def file_should_be_processed(self, filepath):
     """Decision of whether file should be run. Returns boolean."""
     try:
         image.load(filepath)
         return True
     except:
         return False
Ejemplo n.º 5
0
    def test_gamma(self):
        array = np.arange(49).reshape((7,7))
        ref_img = image.load(array, dpi=1)
        comp_img = image.load(array, dpi=1)
        comp_img.roll(amount=1)
        g_map = ref_img.gamma(comp_img)

        num_passing_pixels = np.nansum(g_map < 1)
        num_calced_pixels = np.nansum(g_map >= 0)
        pass_pct = num_passing_pixels / num_calced_pixels * 100
        average_gamma = np.nanmean(g_map)
        expected_pass_pct = 86
        expected_avg_gamma = 0.87
        self.assertAlmostEqual(pass_pct, expected_pass_pct, delta=1)
        self.assertAlmostEqual(average_gamma, expected_avg_gamma, delta=0.02)
Ejemplo n.º 6
0
def identify_images(zip_file):
    """Interactively identify images from a folder, writing the labels to an array for later training"""
    with TemporaryZipDirectory(zip_file) as zfiles:
        filepaths = get_files(zfiles, is_dicom)
        labels = np.zeros(len(filepaths))
        split_val = 25
        length = len(filepaths)
        rounds = int(math.ceil(length / split_val))
        for n in range(rounds):
            fig, axes = plt.subplots(5, 5, figsize=(10, 10))
            for axis, (idx, fp) in zip(axes.flatten(), enumerate(filepaths[split_val*n:split_val*(n+1)])):
                img = load(fp)
                plt.sca(axis)
                plt.imshow(img, cmap=plt.cm.Greys)
                plt.axis('off')
                plt.title(idx+split_val*n)
            plt.show()
        not_done = True
        while not_done:
            label = input("Input the HU indices as a number or range. E.g. '66' or '25-47'. Type 'done' when finished:")
            if label == 'done':
                not_done = False
            else:
                items = label.split('-')
                if len(items) > 1:
                    labels[int(items[0]):int(items[1])] = 1
                else:
                    labels[int(items[0])] = 1
        scaled_features = np.zeros((len(filepaths), 10000), dtype=np.float32)
        for idx, fp in enumerate(filepaths):
            scaled_features[idx, :] = process_image(fp)
    dir2write = osp.dirname(zip_file)
    np.save(osp.join(dir2write, 'images_' + osp.splitext(osp.basename(zip_file))[0]), scaled_features)
    np.save(osp.join(dir2write, 'labels_' + osp.splitext(osp.basename(zip_file))[0]), labels)
    os.remove(zip_file)
Ejemplo n.º 7
0
def _find_bb(img, rad_field_bounding_box):
    """Find the BB within the radiation field. Iteratively searches for a circle-like object
    by lowering a low-pass threshold value until found.

    Returns
    -------
    Point
        The weighted-pixel value location of the BB.
    """
    # get initial starting conditions
    hmin, hmax = np.percentile(img.array, [5, 99.9])
    spread = hmax - hmin
    max_thresh = hmax
    lower_thresh = hmax - spread / 1.5
    # search for the BB by iteratively lowering the low-pass threshold value until the BB is found.
    found = False
    iteration = 0

    while not found:
        try:
            binary_arr = np.logical_and((max_thresh > img), (img >= lower_thresh))
            labeled_arr, num_roi = ndimage.measurements.label(binary_arr)
            roi_sizes, bin_edges = np.histogram(labeled_arr, bins=num_roi + 1)

            if num_roi != 3:  # if not background, field, and 2 BBs
                raise ValueError
            
            bw_bb_img1 = np.where(labeled_arr == np.argsort(roi_sizes)[-3], 1, 0)  
            bw_bb_img1 = ndimage.binary_fill_holes(bw_bb_img1).astype(int)
            bb_regionprops1 = measure.regionprops(bw_bb_img1)[0]
            
            bw_bb_img2 = np.where(labeled_arr == np.argsort(roi_sizes)[-4], 1, 0)  
            bw_bb_img2 = ndimage.binary_fill_holes(bw_bb_img2).astype(int) 
            bb_regionprops2 = measure.regionprops(bw_bb_img2)[0]
    
            if not is_round(bb_regionprops1) and not is_round(bb_regionprops2):
                raise ValueError
            if not is_modest_size(bw_bb_img1, rad_field_bounding_box) and not is_modest_size(bw_bb_img2, rad_field_bounding_box):
                raise ValueError
            if not is_symmetric(bw_bb_img1) and not is_symmetric(bw_bb_img2):
                raise ValueError
        
        except (IndexError, ValueError):
            max_thresh -= 0.05 * spread
            if max_thresh < hmin or iteration > 50:
                raise ValueError("Unable to locate the two BBs. Make sure the BBs are located within the field away from field edges and that there is no significant noise or artifact in the image.")
        else:
            found = True
        iteration += 1
    
    # determine the center of mass of the BB
    inv_img = image.load(img.array)
    # we invert so BB intensity increases w/ attenuation
    inv_img.check_inversion_by_histogram(percentiles=(99.99, 50, 0.01))
    bb_rprops1 = measure.regionprops(bw_bb_img1, intensity_image=inv_img)[0]
    bb_rprops2 = measure.regionprops(bw_bb_img2, intensity_image=inv_img)[0]
    return [[[bb_rprops1.weighted_centroid[1], bb_rprops1.weighted_centroid[0]], bw_bb_img1],
            [[bb_rprops2.weighted_centroid[1], bb_rprops2.weighted_centroid[0]], bw_bb_img2]]
Ejemplo n.º 8
0
def _find_bb(img, bb_box):
    """Find the BB within the radiation field. Iteratively searches for a circle-like object
    by lowering a low-pass threshold value until found.

    Returns
    -------
    Point
        The weighted-pixel value location of the BB.
    """
    # get initial starting conditions
    hmin, hmax = np.percentile(img.array, [5, 99.9])
    spread = hmax - hmin
    max_thresh = hmax
    lower_thresh = hmax - spread / 1.5
    # search for the BB by iteratively lowering the low-pass threshold value until the BB is found.
    found = False
    iteration = 0
    while not found:
        try:
            binary_arr = np.logical_and((max_thresh > img),
                                        (img >= lower_thresh))
            labeled_arr, num_roi = ndimage.measurements.label(binary_arr)
            roi_sizes, bin_edges = np.histogram(labeled_arr, bins=num_roi + 1)
            bw_bb_img = np.where(labeled_arr == np.argsort(roi_sizes)[-3], 1,
                                 0)
            bw_bb_img = ndimage.binary_fill_holes(bw_bb_img).astype(
                int)  # fill holes for low energy beams like 2.5MV
            bb_regionprops = measure.regionprops(bw_bb_img)[0]

            if not is_round(bb_regionprops):
                raise ValueError
            if not is_modest_size(bw_bb_img, bb_box):
                raise ValueError
            if not is_symmetric(bw_bb_img):
                raise ValueError
        except (IndexError, ValueError):
            max_thresh -= 0.05 * spread
            if max_thresh < hmin:
                raise ValueError(
                    "Unable to locate the BB. Make sure the field edges do not obscure the BB and that there is no artifacts in the images."
                )
        else:
            found = True
        if iteration > 100:  # Allow only 100 iterations, then abort (addition)
            raise ValueError(
                "Unable to locate the BB. It is possible that your image does not contain a BB."
            )
        iteration += 1

    # determine the center of mass of the BB
    inv_img = image.load(img.array)
    # we invert so BB intensity increases w/ attenuation
    inv_img.check_inversion_by_histogram(percentiles=(99.99, 50, 0.01))
    bb_rprops = measure.regionprops(bw_bb_img, intensity_image=inv_img)[0]

    # Added output to show BB contour!
    return [[bb_rprops.weighted_centroid[1], bb_rprops.weighted_centroid[0]],
            bw_bb_img]
Ejemplo n.º 9
0
 def __init__(self, path: str):
     """
     Parameters
     ----------
     path : str
         The path to the image.
     """
     self.image = image.load(path)
     self.symmetry: dict = {}
     self.flatness: dict = {}
     self.positions: dict = {}
     self._is_analyzed: bool = False
     self.image.check_inversion_by_histogram()
Ejemplo n.º 10
0
 def _check_inversion(self):
     """Check the inversion by using the histogram of the phantom region"""
     roi = self._phantom_ski_region_calc()
     phantom_array = self.image.array[roi.bbox[0]:roi.bbox[2], roi.bbox[1]:roi.bbox[3]]
     phantom_sub_image = image.load(phantom_array)
     phantom_sub_image.crop(int(phantom_sub_image.shape[0]*0.1))
     p5 = np.percentile(phantom_sub_image, 0.5)
     p50 = np.percentile(phantom_sub_image, 50)
     p95 = np.percentile(phantom_sub_image, 99.5)
     dist_to_5 = abs(p50 - p5)
     dist_to_95 = abs(p50 - p95)
     if dist_to_5 > dist_to_95:
         self.image.invert()
Ejemplo n.º 11
0
 def __init__(self, filepath: str):
     """
     Parameters
     ----------
     filepath : str
         Path to the image file.
     """
     self.image = image.load(filepath)
     self.image.invert()
     self.image.ground()
     self.image.normalize()
     self._angle_override = None
     self._size_override = None
     self._center_override = None
     self._high_contrast_threshold = None
     self._low_contrast_threshold = None
     self.mtf = None
Ejemplo n.º 12
0
def identify_images(zip_file):
    """Interactively identify images from a folder, writing the labels to an array for later training"""
    with TemporaryZipDirectory(zip_file) as zfiles:
        filepaths = get_files(zfiles, is_dicom)
        labels = np.zeros(len(filepaths))
        split_val = 25
        length = len(filepaths)
        rounds = int(math.ceil(length / split_val))
        for n in range(rounds):
            fig, axes = plt.subplots(5, 5, figsize=(10, 10))
            for axis, (idx, fp) in zip(
                    axes.flatten(),
                    enumerate(filepaths[split_val * n:split_val * (n + 1)])):
                img = load(fp)
                plt.sca(axis)
                plt.imshow(img, cmap=plt.cm.Greys)
                plt.axis('off')
                plt.title(idx + split_val * n)
            plt.show()
        not_done = True
        while not_done:
            label = input(
                "Input the HU indices as a number or range. E.g. '66' or '25-47'. Type 'done' when finished:"
            )
            if label == 'done':
                not_done = False
            else:
                items = label.split('-')
                if len(items) > 1:
                    labels[int(items[0]):int(items[1])] = 1
                else:
                    labels[int(items[0])] = 1
        scaled_features = np.zeros((len(filepaths), 10000), dtype=np.float32)
        for idx, fp in enumerate(filepaths):
            scaled_features[idx, :] = process_image(fp)
    dir2write = osp.dirname(zip_file)
    np.save(
        osp.join(dir2write,
                 'images_' + osp.splitext(osp.basename(zip_file))[0]),
        scaled_features)
    np.save(
        osp.join(dir2write,
                 'labels_' + osp.splitext(osp.basename(zip_file))[0]), labels)
    os.remove(zip_file)
Ejemplo n.º 13
0
 def test_nonsense(self):
     with self.assertRaises(TypeError):
         image.load('blahblah')
Ejemplo n.º 14
0
 def setUp(self):
     self.img = image.load(tif_path)
     self.dcm = image.load(dcm_path)
     array = np.arange(42).reshape(6, 7)
     self.arr = image.load(array)
Ejemplo n.º 15
0
 def test_load_file(self):
     img = image.load(tif_path)
     self.assertIsInstance(img, FileImage)
Ejemplo n.º 16
0
 def test_load_array(self):
     arr = np.arange(36).reshape(6, 6)
     img = image.load(arr)
     self.assertIsInstance(img, ArrayImage)
Ejemplo n.º 17
0
 def setUpClass(cls):
     cls.dcm = image.load(dcm_path)
Ejemplo n.º 18
0
 def test_load_dicom(self):
     img = image.load(dcm_path)
     self.assertIsInstance(img, DicomImage)
Ejemplo n.º 19
0
 def setUpClass(cls):
     img = image.load(cls.image_file_location)
     cls.profile = cls.klass(cls.center_point, cls.radius, img.array)
     cls.profile.filter(size=0.01, kind='gaussian')
Ejemplo n.º 20
0
 def setUpClass(cls):
     img = image.load(cls.image_file_location)
     cls.profile = cls.klass(cls.center_point, cls.radius, img.array)
Ejemplo n.º 21
0
 def test_nonsense(self):
     with self.assertRaises(FileNotFoundError):
         image.load('blahblah')
Ejemplo n.º 22
0
 def test_load_dicom_from_file_object(self):
     img_ref = image.load(dcm_path)
     with open(dcm_path, 'rb') as f:
         img = image.load(f)
     self.assertIsInstance(img, DicomImage)
     self.assertEqual(img.dpi, img_ref.dpi)
Ejemplo n.º 23
0
 def test_load_file_from_file_object(self):
     img_ref = image.load(tif_path)
     with open(tif_path, 'rb') as f:
         img = image.load(f)
     self.assertIsInstance(img, FileImage)
     self.assertEqual(img.center, img_ref.center)