コード例 #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)
コード例 #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)
コード例 #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
コード例 #4
0
ファイル: utils.py プロジェクト: jdschmitt11/pylinac
 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
コード例 #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)
コード例 #6
0
ファイル: build_cbct_images.py プロジェクト: bastula/pylinac
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)
コード例 #7
0
ファイル: field_rotation.py プロジェクト: fishdda/pyqaserver
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]]
コード例 #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]
コード例 #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()
コード例 #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()
コード例 #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
コード例 #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)
コード例 #13
0
 def test_nonsense(self):
     with self.assertRaises(TypeError):
         image.load('blahblah')
コード例 #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)
コード例 #15
0
 def test_load_file(self):
     img = image.load(tif_path)
     self.assertIsInstance(img, FileImage)
コード例 #16
0
 def test_load_array(self):
     arr = np.arange(36).reshape(6, 6)
     img = image.load(arr)
     self.assertIsInstance(img, ArrayImage)
コード例 #17
0
 def setUpClass(cls):
     cls.dcm = image.load(dcm_path)
コード例 #18
0
 def test_load_dicom(self):
     img = image.load(dcm_path)
     self.assertIsInstance(img, DicomImage)
コード例 #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')
コード例 #20
0
ファイル: test_profile.py プロジェクト: cpbhatt/pylinac-1
 def setUpClass(cls):
     img = image.load(cls.image_file_location)
     cls.profile = cls.klass(cls.center_point, cls.radius, img.array)
コード例 #21
0
 def test_nonsense(self):
     with self.assertRaises(FileNotFoundError):
         image.load('blahblah')
コード例 #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)
コード例 #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)