From 4596895103d74cea1015c43a7dae44af00663165 Mon Sep 17 00:00:00 2001 From: Sameera Abeykoon Date: Thu, 23 Apr 2015 16:07:03 -0400 Subject: [PATCH 1/5] WIP: adding a function to divide the ring into pies, and get the roi information --- skxray/roi.py | 89 ++++++++++++++++++++++++++++++++++++++++ skxray/tests/test_roi.py | 48 ++++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/skxray/roi.py b/skxray/roi.py index 6c11cb4c5..54e81bda7 100644 --- a/skxray/roi.py +++ b/skxray/roi.py @@ -229,3 +229,92 @@ def ring_edges(inner_radius, width, spacing=0, num_rings=None): edges = np.cumsum(steps).reshape(-1, 2) return edges + + +def divide_pies(image_shape, radius, calibrated_center, + num_angles, rotate='N',): + """ + This function will provide the indices when a circular roi + is divided into pies. + + Parameters + ---------- + image_shape : tuple + shape of the image (detector X and Y direction) + Order is (num_rows, num_columns) + + radius : float + radius of the circle + + calibrated_center : tuple + defining the center of the image + (column value, row value) (mm) + + num_angles : int + number of angles ring divide into + angles are measured from horizontal-anti clock wise + + rotate : {'Y', 'N'}, optional + to make angles measured from vertical-anti clock wise + + Returns + ------- + labels_grid : array + indices of the required roi's + shape is ([image_shape[0], image_shape[1]]) + """ + angle_grid, grid_values = get_angle_grid(image_shape, calibrated_center, + num_angles) + #grid_values = core.pixel_to_radius(image_shape, calibrated_center) + if rotate == 'Y': + mesh = np.rot90(angle_grid) + grid_values = np.rot90(grid_values) + + angle_grid[grid_values > radius] = 0 + + labels_grid = angle_grid.reshape(image_shape) + + return labels_grid + + +def get_angle_grid(image_shape, calibrated_center, num_angles): + """ + Helper function to get the grid values and indices values from + the angles of the grid + + Parameters + ---------- + image_shape : tuple + shape of the image (detector X and Y direction) + Order is (num_rows, num_columns) + + calibrated_center : tuple + defining the center of the image + (column value, row value) (mm) + + Returns + ------- + ind_grid : array + indices grid, indices according to the angles + + grid_values : array + grid values + + """ + yy, xx = np.mgrid[:image_shape[0], :image_shape[1]] + y_ = (np.flipud(yy) - calibrated_center[1]) + x_ = (xx - calibrated_center[0]) + grid_values = np.float_(np.hypot(x_, y_)) + angle_grid = np.rad2deg(np.arctan2(y_, x_)) + + angle_grid[angle_grid < 0] = 360 + angle_grid[angle_grid < 0] + + # required angles + angles = np.linspace(0, 360, num_angles) + # the indices of the bins(angles) to which each value in input + # array(angle_grid) belongs. + ind_grid = (np.digitize(np.ravel(angle_grid), angles, + right=False)).reshape(image_shape) + + return ind_grid, grid_values + diff --git a/skxray/tests/test_roi.py b/skxray/tests/test_roi.py index 51b0c0fe6..53f6c565b 100644 --- a/skxray/tests/test_roi.py +++ b/skxray/tests/test_roi.py @@ -147,3 +147,51 @@ def _helper_check(pixel_list, inds, num_pix, q_ring_val, calib_center, - 0.000001)]]))[0][0])) assert_array_equal(zero_grid, data) assert_array_equal(num_pix, num_pixels) + + +def test_divide_pies(): + detector_size = (10, 8) + radius = 5. + calibrated_center = (5., 2.) + num_angles = 3 + + angles = np.linspace(0, 360, num_angles) + + all_roi_inds = roi.divide_pies(detector_size, radius, + calibrated_center, + num_angles) + + labels, indices = corr.extract_label_indices(all_roi_inds) + + ty = np.zeros(detector_size).ravel() + ty[indices] = labels + + num_pixels = (np.bincount(ty.astype(int)))[1:] + + # get the angle grid and grid values from the center + angle_grid, grid_values = roi.get_angle_grid(detector_size, calibrated_center, + num_angles) + # get the indices into a grid + zero_grid = np.zeros((detector_size[0], detector_size[1])) + + zero_grid[grid_values <= radius] = 1 + + assert_array_equal(np.nonzero(zero_grid), + np.nonzero((ty.reshape(*detector_size)))) + + mesh = np.zeros((detector_size[0], detector_size[1])) + for i in range(num_angles-1): + vl = ((angles[i] <= angle_grid) & + (angle_grid < angles[i + 1])) + mesh[vl] = i + 1 + + # remove the values grater than the radius + mesh[grid_values > radius] = 0 + # take out the zero values in the grid + roi_inds_m = mesh[mesh > 0] + + assert_array_equal(roi_inds_m, labels) + + +if __name__ == "__main__": + test_divide_pies() From 5c919097695521359ca3e0ef01e9515dac15c469 Mon Sep 17 00:00:00 2001 From: Sameera Abeykoon Date: Thu, 23 Apr 2015 16:30:03 -0400 Subject: [PATCH 2/5] DOC: modified the documnetation in the functions, --- skxray/roi.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/skxray/roi.py b/skxray/roi.py index 54e81bda7..59e11d081 100644 --- a/skxray/roi.py +++ b/skxray/roi.py @@ -35,8 +35,8 @@ ######################################################################## """ -This module is to get informations of different region of interests(roi's). -Information : the number of pixels, pixel indices, indices +This module is to get information of different region of interests(roi's). +Information : pixel indices, indices array """ @@ -62,6 +62,8 @@ def rectangles(coords, shape): """ + This function wil provide the indices array for rectangle region of interests. + Parameters ---------- coords : iterable @@ -267,8 +269,7 @@ def divide_pies(image_shape, radius, calibrated_center, num_angles) #grid_values = core.pixel_to_radius(image_shape, calibrated_center) if rotate == 'Y': - mesh = np.rot90(angle_grid) - grid_values = np.rot90(grid_values) + angle_grid = np.rot90(angle_grid) angle_grid[grid_values > radius] = 0 @@ -279,8 +280,8 @@ def divide_pies(image_shape, radius, calibrated_center, def get_angle_grid(image_shape, calibrated_center, num_angles): """ - Helper function to get the grid values and indices values from - the angles of the grid + This function will provide the grid values and indices values from + the angles of the grid and the radius values of the grid Parameters ---------- @@ -299,7 +300,6 @@ def get_angle_grid(image_shape, calibrated_center, num_angles): grid_values : array grid values - """ yy, xx = np.mgrid[:image_shape[0], :image_shape[1]] y_ = (np.flipud(yy) - calibrated_center[1]) @@ -317,4 +317,3 @@ def get_angle_grid(image_shape, calibrated_center, num_angles): right=False)).reshape(image_shape) return ind_grid, grid_values - From e276402ab381ccd8e92a77e41069c3e583f64edd Mon Sep 17 00:00:00 2001 From: Sameera Abeykoon Date: Fri, 24 Apr 2015 11:44:15 -0400 Subject: [PATCH 3/5] TST : added more tests to test_rings() --- skxray/roi.py | 50 +++++++++++++++++----------------- skxray/tests/test_roi.py | 58 +++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 44 deletions(-) diff --git a/skxray/roi.py b/skxray/roi.py index 59e11d081..00ba06f56 100644 --- a/skxray/roi.py +++ b/skxray/roi.py @@ -216,7 +216,7 @@ def ring_edges(inner_radius, width, spacing=0, num_rings=None): if num_rings != len(width): raise ValueError("num_rings does not match width list") if spacing_is_list: - if num_rings != len(spacing): + if num_rings-1 != len(spacing): raise ValueError("num_rings does not match spacing list") # Now regularlize the input. @@ -265,23 +265,31 @@ def divide_pies(image_shape, radius, calibrated_center, indices of the required roi's shape is ([image_shape[0], image_shape[1]]) """ - angle_grid, grid_values = get_angle_grid(image_shape, calibrated_center, - num_angles) - #grid_values = core.pixel_to_radius(image_shape, calibrated_center) + angle_grid = get_angle_grid(image_shape, calibrated_center) + # required angles + angles = np.linspace(0, 360, num_angles) + # the indices of the bins(angles) to which each value in input + # array(angle_grid) belongs. + ind_grid = (np.digitize(np.ravel(angle_grid), angles, + right=False)).reshape(image_shape) + + # radius grid for the image_shape + grid_values = core.pixel_to_radius(image_shape, calibrated_center) + if rotate == 'Y': - angle_grid = np.rot90(angle_grid) + ind_grid = np.rot90(ind_grid) - angle_grid[grid_values > radius] = 0 + ind_grid[grid_values > radius] = 0 - labels_grid = angle_grid.reshape(image_shape) + labels_grid = ind_grid.reshape(image_shape) return labels_grid -def get_angle_grid(image_shape, calibrated_center, num_angles): +def get_angle_grid(image_shape, calibrated_center): """ - This function will provide the grid values and indices values from - the angles of the grid and the radius values of the grid + This function will provide angle values for the whole grid + from the calibrated center Parameters ---------- @@ -295,25 +303,15 @@ def get_angle_grid(image_shape, calibrated_center, num_angles): Returns ------- - ind_grid : array - indices grid, indices according to the angles - - grid_values : array - grid values + angle_grid : array + angle values from the calibrated center + shape image_shape """ yy, xx = np.mgrid[:image_shape[0], :image_shape[1]] - y_ = (np.flipud(yy) - calibrated_center[1]) - x_ = (xx - calibrated_center[0]) - grid_values = np.float_(np.hypot(x_, y_)) + y_ = (np.flipud(yy) - calibrated_center[0]) + x_ = (xx - calibrated_center[1]) angle_grid = np.rad2deg(np.arctan2(y_, x_)) angle_grid[angle_grid < 0] = 360 + angle_grid[angle_grid < 0] - # required angles - angles = np.linspace(0, 360, num_angles) - # the indices of the bins(angles) to which each value in input - # array(angle_grid) belongs. - ind_grid = (np.digitize(np.ravel(angle_grid), angles, - right=False)).reshape(image_shape) - - return ind_grid, grid_values + return angle_grid diff --git a/skxray/tests/test_roi.py b/skxray/tests/test_roi.py index 53f6c565b..4df048b6c 100644 --- a/skxray/tests/test_roi.py +++ b/skxray/tests/test_roi.py @@ -53,7 +53,7 @@ import numpy.testing as npt -def test_roi_rectangles(): +def test_rectangles(): shape = (15, 26) roi_data = np.array(([2, 2, 6, 3], [6, 7, 8, 5], [8, 18, 5, 10]), dtype=np.int64) @@ -80,17 +80,41 @@ def test_roi_rectangles(): assert_almost_equal(bottom-1, ind_co[-1][-1]) -def test_roi_rings(): - calibrated_center = (100, 100) +def test_rings(): + calibrated_center = (100., 100.) img_dim = (200, 205) - first_q = 2 - delta_q = 3 + first_q = 10. + delta_q = 5. num_rings = 7 # number of Q rings + one_step_q = 5.0 + step_q = [2.5, 3.0, 5.8] + # test when there is same spacing between rings + edges = roi.ring_edges(first_q, width=delta_q, spacing=one_step_q, + num_rings=num_rings) + print("edges there is same spacing between rings ", edges) + label_array = roi.rings(edges, calibrated_center, img_dim) + print("label_array there is same spacing between rings", label_array) + + # test when there is same spacing between rings + edges = roi.ring_edges(first_q, width=delta_q, spacing=2.5, + num_rings=num_rings) + print("edges there is same spacing between rings ", edges) + label_array = roi.rings(edges, calibrated_center, img_dim) + print("label_array there is same spacing between rings", label_array) + + # test when there is different spacing between rings + edges = roi.ring_edges(first_q, width=delta_q, spacing=step_q, + num_rings=4) + print("edges when there is different spacing between rings", edges) + label_array = roi.rings(edges, calibrated_center, img_dim) + print("label_array there is different spacing between rings", label_array) + + # test when there is no spacing between rings edges = roi.ring_edges(first_q, width=delta_q, num_rings=num_rings) - print(edges) + print("edges", edges) label_array = roi.rings(edges, calibrated_center, img_dim) - print(label_array) + print("label_array", label_array) # Did we draw the right number of rings? print(np.unique(label_array)) @@ -150,10 +174,10 @@ def _helper_check(pixel_list, inds, num_pix, q_ring_val, calib_center, def test_divide_pies(): - detector_size = (10, 8) - radius = 5. - calibrated_center = (5., 2.) - num_angles = 3 + detector_size = (100, 80) + radius = 50. + calibrated_center = (50., 20.) + num_angles = 8 angles = np.linspace(0, 360, num_angles) @@ -168,12 +192,14 @@ def test_divide_pies(): num_pixels = (np.bincount(ty.astype(int)))[1:] - # get the angle grid and grid values from the center - angle_grid, grid_values = roi.get_angle_grid(detector_size, calibrated_center, - num_angles) + # get the angle grid from the center + angle_grid = roi.get_angle_grid(detector_size, calibrated_center) # get the indices into a grid zero_grid = np.zeros((detector_size[0], detector_size[1])) + # radius values from the calibrated + grid_values = core.pixel_to_radius(detector_size, calibrated_center) + zero_grid[grid_values <= radius] = 1 assert_array_equal(np.nonzero(zero_grid), @@ -191,7 +217,3 @@ def test_divide_pies(): roi_inds_m = mesh[mesh > 0] assert_array_equal(roi_inds_m, labels) - - -if __name__ == "__main__": - test_divide_pies() From caeecaf6dae9cb6a05b4ca529841e3cc26b05a8d Mon Sep 17 00:00:00 2001 From: Sameera Abeykoon Date: Fri, 24 Apr 2015 16:28:25 -0400 Subject: [PATCH 4/5] API: added a new function pie_slices To divide the rings into pies and removed the divide_cirecle functon --- skxray/roi.py | 93 ++++++++++++++++++++++------------------ skxray/tests/test_roi.py | 54 ++++++----------------- 2 files changed, 65 insertions(+), 82 deletions(-) diff --git a/skxray/roi.py b/skxray/roi.py index 00ba06f56..f9bc9a481 100644 --- a/skxray/roi.py +++ b/skxray/roi.py @@ -233,84 +233,93 @@ def ring_edges(inner_radius, width, spacing=0, num_rings=None): return edges -def divide_pies(image_shape, radius, calibrated_center, - num_angles, rotate='N',): +def pie_slices(edges, slicing, center, shape, theta=0): """ - This function will provide the indices when a circular roi - is divided into pies. - Parameters ---------- - image_shape : tuple - shape of the image (detector X and Y direction) - Order is (num_rows, num_columns) + edges : array + inner and outer radius for each ring - radius : float - radius of the circle + slicing : int or list + number of pie slices or list of angles in degrees - calibrated_center : tuple - defining the center of the image - (column value, row value) (mm) + center : rr, cc : tuple + point in image where r=0; may be a float giving subpixel precision - num_angles : int - number of angles ring divide into - angles are measured from horizontal-anti clock wise + shape: rr, cc: tuple + Image shape which is used to determine the maximum extent of output + pixel coordinates. - rotate : {'Y', 'N'}, optional - to make angles measured from vertical-anti clock wise + theta : float, optional + angle in degrees Returns ------- - labels_grid : array - indices of the required roi's - shape is ([image_shape[0], image_shape[1]]) + label_array : array + Elements not inside any ROI are zero; elements inside each + ROI are 1, 2, 3, corresponding to the order they are specified + in edges and slicing + """ - angle_grid = get_angle_grid(image_shape, calibrated_center) + angle_grid = get_angle_grid(shape, center) + + slicing_is_list = isinstance(slicing, collections.Iterable) # required angles - angles = np.linspace(0, 360, num_angles) + + if slicing_is_list: + slicing = np.asarray(slicing) + theta + else: + slicing = np.linspace(0, 360, slicing) + theta + # the indices of the bins(angles) to which each value in input # array(angle_grid) belongs. - ind_grid = (np.digitize(np.ravel(angle_grid), angles, - right=False)).reshape(image_shape) + ind_grid = (np.digitize(np.ravel(angle_grid), slicing, + right=False)).reshape(shape) + label_array = np.zeros(shape, dtype=np.int64) # radius grid for the image_shape - grid_values = core.pixel_to_radius(image_shape, calibrated_center) + grid_values = core.pixel_to_radius(shape, center) - if rotate == 'Y': - ind_grid = np.rot90(ind_grid) + # assign indices value according to angles then rings + for r in range(len(edges)): + vl = (edges[r][0] <= grid_values) & (grid_values + < edges[r][1]) + label_array[vl] = ind_grid[vl] + len(slicing)*(r) - ind_grid[grid_values > radius] = 0 + return label_array - labels_grid = ind_grid.reshape(image_shape) - return labels_grid - - -def get_angle_grid(image_shape, calibrated_center): +def get_angle_grid(shape, center): """ This function will provide angle values for the whole grid from the calibrated center Parameters ---------- - image_shape : tuple + shape : tuple shape of the image (detector X and Y direction) Order is (num_rows, num_columns) - calibrated_center : tuple - defining the center of the image - (column value, row value) (mm) + center : rr, cc : tuple + point in image where r=0; may be a float giving + subpixel precision + + pixel_size : tuple, optional + The size of a pixel (really the pitch) in real units. (height, width). + Defaults to 1 pixel/pixel if not specified. Returns ------- angle_grid : array angle values from the calibrated center shape image_shape + """ - yy, xx = np.mgrid[:image_shape[0], :image_shape[1]] - y_ = (np.flipud(yy) - calibrated_center[0]) - x_ = (xx - calibrated_center[1]) - angle_grid = np.rad2deg(np.arctan2(y_, x_)) + X, Y = np.meshgrid((np.arange(shape[1]) - + center[1]), + (np.arange(shape[0]) - + center[0])) + angle_grid = np.rad2deg(np.arctan2(Y, X)) angle_grid[angle_grid < 0] = 360 + angle_grid[angle_grid < 0] diff --git a/skxray/tests/test_roi.py b/skxray/tests/test_roi.py index 4df048b6c..adfb18fc4 100644 --- a/skxray/tests/test_roi.py +++ b/skxray/tests/test_roi.py @@ -173,47 +173,21 @@ def _helper_check(pixel_list, inds, num_pix, q_ring_val, calib_center, assert_array_equal(num_pix, num_pixels) -def test_divide_pies(): - detector_size = (100, 80) - radius = 50. - calibrated_center = (50., 20.) - num_angles = 8 - - angles = np.linspace(0, 360, num_angles) - - all_roi_inds = roi.divide_pies(detector_size, radius, - calibrated_center, - num_angles) - - labels, indices = corr.extract_label_indices(all_roi_inds) - - ty = np.zeros(detector_size).ravel() - ty[indices] = labels - - num_pixels = (np.bincount(ty.astype(int)))[1:] - - # get the angle grid from the center - angle_grid = roi.get_angle_grid(detector_size, calibrated_center) - # get the indices into a grid - zero_grid = np.zeros((detector_size[0], detector_size[1])) - - # radius values from the calibrated - grid_values = core.pixel_to_radius(detector_size, calibrated_center) - - zero_grid[grid_values <= radius] = 1 +def test_pie_slices(): + calibrated_center = (20., 25.) + img_dim = (100, 80) + first_q = 5. + delta_q = 5. + num_rings = 4 # number of Q rings + slicing = 4 - assert_array_equal(np.nonzero(zero_grid), - np.nonzero((ty.reshape(*detector_size)))) + edges = roi.ring_edges(first_q, width=delta_q, spacing=4, + num_rings=num_rings) + label_array = roi.pie_slices(edges, slicing, calibrated_center, img_dim, + theta=0) - mesh = np.zeros((detector_size[0], detector_size[1])) - for i in range(num_angles-1): - vl = ((angles[i] <= angle_grid) & - (angle_grid < angles[i + 1])) - mesh[vl] = i + 1 - # remove the values grater than the radius - mesh[grid_values > radius] = 0 - # take out the zero values in the grid - roi_inds_m = mesh[mesh > 0] - assert_array_equal(roi_inds_m, labels) +if __name__ == "__main__": + import matplotlib.pyplot as plt + test_pie_slices() From b24b5a8408272bfcbe07d384433e2b669429aeb2 Mon Sep 17 00:00:00 2001 From: Sameera Abeykoon Date: Fri, 24 Apr 2015 16:33:49 -0400 Subject: [PATCH 5/5] TST: nmodified the tests --- skxray/tests/test_roi.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/skxray/tests/test_roi.py b/skxray/tests/test_roi.py index adfb18fc4..5cadef703 100644 --- a/skxray/tests/test_roi.py +++ b/skxray/tests/test_roi.py @@ -185,9 +185,4 @@ def test_pie_slices(): num_rings=num_rings) label_array = roi.pie_slices(edges, slicing, calibrated_center, img_dim, theta=0) - - - -if __name__ == "__main__": - import matplotlib.pyplot as plt - test_pie_slices() + \ No newline at end of file