From 00f4d38c2c743cfc3f5b22c286cb3fbce049fda0 Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Wed, 29 Jan 2014 22:47:52 +1100 Subject: [PATCH] Polish coordinate system It's important to distinguish between pixels and points. A square set of points belongs to one pixel. When users type `linewidth=3`, they usually mean a line 3 pixels wide. The distance between the pixel center points, then, is 2. --- skimage/measure/profile.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/skimage/measure/profile.py b/skimage/measure/profile.py index 008948e2..823bd9da 100644 --- a/skimage/measure/profile.py +++ b/skimage/measure/profile.py @@ -40,27 +40,37 @@ def profile_line(img, src, dst, linewidth=1, [1, 1, 1, 2, 2, 2], [1, 1, 1, 2, 2, 2], [0, 0, 0, 0, 0, 0]]) - >>> profile_line(img, (2, 1), (2, 5)) + >>> profile_line(img, (2, 1), (2, 4)) array([ 1., 1., 2., 2.]) + + Notes + ----- + The destination point is included in the profile, in contrast to + standard numpy indexing. """ src_row, src_col = src = np.asarray(src, dtype=float) dst_row, dst_col = dst = np.asarray(dst, dtype=float) d_row, d_col = dst - src theta = np.arctan2(d_row, d_col) - length = np.ceil(np.hypot(d_row, d_col)) + length = np.ceil(np.hypot(d_row, d_col) + 1) + # we add one above because we include the last point in the profile + # (in contrast to standard numpy indexing) line_col = np.linspace(src_col, dst_col, length) line_row = np.linspace(src_row, dst_row, length) # this if clause is necessary to keep the line centered on the true # source and destination points. Otherwise, the computed line has - # an offset of `linewidth/2` + # an offset of `linewidth / 2` if linewidth <= 1: perp_lines = np.array([line_row[:, np.newaxis], line_col[:, np.newaxis]]) else: - col_width = linewidth * np.sin(-theta) / 2 - row_width = linewidth * np.cos(theta) / 2 + # we subtract 1 from linewidth to change from pixel-counting + # (make this line 3 pixels wide) to point distances (the + # distance between pixel centers) + col_width = (linewidth - 1) * np.sin(-theta) / 2 + row_width = (linewidth - 1) * np.cos(theta) / 2 perp_rows = np.array([np.linspace(row_i - row_width, row_i + row_width, linewidth) for row_i in line_row]) perp_cols = np.array([np.linspace(col_i - col_width, col_i + col_width,