1 import matplotlib.pyplot
as plt
3 from scipy.ndimage.interpolation
import geometric_transform
4 from scipy.signal
import fftconvolve
5 from skimage.draw
import polygon
8 from shapely.geometry
import LineString
12 crossproduct = (c[1] - a[1]) * (b[0] - a[0]) - (c[0] - a[0]) * (b[1] - a[1])
14 if abs(crossproduct) > sys.float_info.epsilon * 100:
16 dotproduct = (c[0] - a[0]) * (b[0] - a[0]) + (c[1] - a[1]) * (b[1] - a[1])
19 squaredlengthba = (b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1])
20 if dotproduct > squaredlengthba:
26 rho = np.sqrt(x ** 2 + y ** 2)
27 phi = np.arctan2(y, x)
49 Input arrays should be floating point numbers.
50 :param template: N-D array, of template or filter you are using for cross-correlation.
51 Must be less or equal dimensions to image.
52 Length of each dimension must be less than length of image.
53 :param image: N-D array
54 :param mode: Options, "full", "valid", "same"
55 full (Default): The output of fftconvolve is the full discrete linear convolution of the inputs.
56 Output size will be image size + 1/2 template size in each dimension.
57 valid: The output consists only of those elements that do not rely on the zero-padding.
58 same: The output is the same size as image, centered with respect to the 'full' output.
59 :return: N-D array of same dimensions as image. Size depends on mode parameter.
63 if np.ndim(template) > np.ndim(image)
or \
64 len([i
for i
in range(np.ndim(template))
if template.shape[i] > image.shape[i]]) > 0:
65 print(
"normxcorr2: TEMPLATE larger than IMG. Arguments may be swapped.")
67 template = template - np.mean(template)
68 image = image - np.mean(image)
70 a1 = np.ones(template.shape)
72 ar = np.flipud(np.fliplr(template))
73 out = fftconvolve(image, ar.conj(), mode=mode)
75 image = fftconvolve(np.square(image), a1, mode=mode) - \
76 np.square(fftconvolve(image, a1, mode=mode)) / (np.prod(template.shape))
79 image[np.where(image < 0)] = 0
81 template = np.sum(np.square(template))
82 out = out / np.sqrt(image * template)
85 out[np.where(np.logical_not(np.isfinite(out)))] = 0
91 ftimage = np.fft.fft2(binary_map * 255)
92 ftimage = np.fft.fftshift(ftimage)
94 flat_ftimage = np.abs(ftimage.flatten())
96 flat_ftimage = np.sort(flat_ftimage)
97 flat_ftimage = np.flip(flat_ftimage)
99 tr_id = int(len(flat_ftimage) * tr)
100 tr = flat_ftimage[tr_id]
101 ftimage[np.abs(ftimage) < tr] = 0.0
103 fig, ax = plt.subplots(nrows=1, ncols=1, sharex=
True, sharey=
True)
104 ax.plot(flat_ftimage, range(len(flat_ftimage)),
'.')
111 iftimage = np.fft.ifft2(fft)
112 domin = abs(iftimage) / np.max(abs(iftimage))
113 fft_map = np.zeros(binary_map.shape)
114 fft_map[binary_map] = domin[binary_map]
115 ft_v = fft_map.flatten()
116 ft_v = ft_v[ft_v > 0]
117 tr = np.percentile(ft_v, per)
118 tr_fft_map = np.zeros(fft_map.shape)
119 tr_fft_map[fft_map > tr] = 1
120 return fft_map, tr_fft_map
125 Transform img to its polar coordinate representation.
127 order: int, default 1
128 Specify the spline interpolation order.
129 High orders may be slow for large images.
133 max_radius = 0.5 * np.linalg.norm(img.shape)
135 def transform(coords):
137 theta = 2 * np.pi * coords[1] / (img.shape[1] - 1.)
141 radius = max_radius * coords[0] / img.shape[0]
143 i = 0.5 * img.shape[0] - radius * np.sin(theta)
144 j = radius * np.cos(theta) + 0.5 * img.shape[1]
147 polar = geometric_transform(img, transform, order=order)
149 rads = max_radius * np.linspace(0, 1, img.shape[0])
150 angs = np.linspace(0, 2 * np.pi, img.shape[1])
152 return polar, (rads, angs)
156 phi = np.abs(a - b) % (2 * np.pi)
157 dist = (2 * np.pi - phi)
if phi > np.pi
else phi
162 xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
163 ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
166 return a[0] * b[1] - a[1] * b[0]
168 div = det(xdiff, ydiff)
170 return np.nan, np.nan
172 d = (det(*line1), det(*line2))
173 x = det(d, xdiff) / div
174 y = det(d, ydiff) / div
179 array = np.asarray(array)
180 idx = (np.abs(array - value)).argmin()
181 return array[idx], idx
185 rr, cc = polygon(r, c)
188 rm_rr = np.logical_and(rm_rr_1, rm_rr_2)
193 rm_cc = np.logical_and(rm_cc_1, rm_cc_2)
200 return {x
for x
in range(1, (n + 1) // 2 + 1)
if n % x == 0
and n != x}
211 return math.sqrt(x * x + y * y)
223 return (x / mag, y / mag)
232 return (x * sc, y * sc)
238 return (x + X, y + Y,)
260 line_vec =
vector(start, end)
261 pnt_vec =
vector(start, pnt)
262 line_len =
length(line_vec)
263 line_unitvec =
unit(line_vec)
264 pnt_vec_scaled =
scale(pnt_vec, 1.0 / line_len)
265 t =
dot(line_unitvec, pnt_vec_scaled)
270 nearest =
scale(line_vec, t)
272 nearest =
add(nearest, start)
278 if is_between([segment1[0][0], segment1[0][1]], [segment1[1][0], segment1[1][1]], [x, y]):
281 return np.nan, np.nan
288 if x
is np.nan
and y
is np.nan:
308 edges_1 = [LineString([points[0], points[1]]), LineString([points[2], points[3]])]
309 edges_2 = [LineString([points[1], points[2]]), LineString([points[3], points[4]])]
310 if edges_1[0].length<edges_2[0].length:
311 return (edges_1[0].interpolate(0.5, normalized=
True), edges_1[1].interpolate(0.5, normalized=
True))
313 return (edges_2[0].interpolate(0.5, normalized=
True), edges_2[1].interpolate(0.5, normalized=
True))