I have several pictures depicting coordinates of several points (often 3-10 points). I 'd like to group picture having same arrangement of points. By shifting (a) via vector (0, 1), which the set (a) of 3 points having coordinates (1, 1) (2, 1) and (3, 1), we obtain the set (d) having (1, 2) (2, 2) and (3, 2) respectively. Similarly, after shifting by a vector (2, 0), the set (a) becomes the set (g) of (1, 3), (2, 3) and (3, 3). Then we can group the set (a), (d) and (g) which have same arrangement and consider as equivalent. Could you please help me out?
def is_shift(set1, set2):
shift = None # will store a tuple of delta_x, delta_y
for (x1, y1), (x2, y2) in zip(set1, set2):
cur_shift = x1 - x1, y1 - y2
if not shift: # the first pair of points
shift = cur_shift
elif shift != cur_shift: # shifted the same way as the first one?
return False
return True
matrices = array([
[(1, 1), (2, 1), (3, 1)],
[(1, 2), (2, 1), (3, 1)],
[(1, 3), (2, 1), (2, 2)],
[(1, 2), (2, 2), (3, 2)],
[(1, 3), (2, 2), (3, 2)],
[(2, 3), (3, 1), (3, 2)],
[(1, 3), (2, 3), (3, 3)],
[(2, 2), (3, 1), (4, 4)],
])
Output:
[[(1, 1), (2, 1), (3, 1)], [(1, 2), (2, 2), (3, 2)], [(1, 3), (2, 3), (3, 3)]]
[[(1, 2), (2, 1), (3, 1)], [(1, 3), (2, 2), (3, 2)]]
[[(1, 3), (2, 1), (2, 2)], [(2, 3), (3, 1), (3, 2)]]
[(2, 2), (3, 1), (4, 4)]
The idea here is to group images using a dictionary by constructing a key. If I consider the way the images are depicted, I can think of the shift of coordinates around the x axis and the y axis to be similar for similar images, if I consider the shift as [x - min(x_coords) for x in x_coords]
and [y - min(y_coords) for y in y_coords]
.
For example, for image 1, x_coords = [1,2,3]
and y_coords = [2,2,2]
, so the shifts will be (0, 1, 2)
and 0,0,0
as the minimum of x and y coords are 1 and 2 respectively. The combination of these shifts can now be used as a key to group different images as follows
import collections
def group_matrices():
matrices = [
[(1, 1), (2, 1), (3, 1)],
[(1, 2), (2, 1), (3, 1)],
[(1, 3), (2, 1), (2, 2)],
[(1, 2), (2, 2), (3, 2)],
[(1, 3), (2, 2), (3, 2)],
[(2, 3), (3, 1), (3, 2)],
[(1, 3), (2, 3), (3, 3)],
[(2, 2), (3, 1), (4, 4)],
]
# Dictionary to group images
groups = collections.defaultdict(list)
# Iterate over the matrices
for image in matrices:
# Extract x and y coordinates from the image
x_coords, y_coords = zip(*image)
# Compute minimum of x and y coordinates
min_x = min(x_coords)
min_y = min(y_coords)
# Compute the shifts
key_x = tuple(x - min_x for x in x_coords)
key_y = tuple(y - min_y for y in y_coords)
# Create the key combining the shifts and add image
# to corresponding key
key = (key_x, key_y)
groups[key].append(image)
# Return the list of lists of grouped images
return [value for value in groups.values()]
for group in group_matrices():
print(group)
The output will be
[[(1, 1), (2, 1), (3, 1)], [(1, 2), (2, 2), (3, 2)], [(1, 3), (2, 3), (3, 3)]]
[[(1, 2), (2, 1), (3, 1)], [(1, 3), (2, 2), (3, 2)]]
[[(1, 3), (2, 1), (2, 2)], [(2, 3), (3, 1), (3, 2)]]
[[(2, 2), (3, 1), (4, 4)]]
My idea is to apply the coordinate shift abovementioned as well. I try to keep calculations numpy
based (no for
loops) as much as possible:
import numpy as np
import numpy_indexed as npi
matrices = [
[(1, 1), (2, 1), (3, 1)],
[(1, 2), (2, 1), (3, 1)],
[(1, 3), (2, 1), (2, 2)],
[(1, 2), (2, 2), (3, 2)],
[(1, 3), (2, 2), (3, 2)],
[(2, 3), (3, 1), (3, 2)],
[(1, 3), (2, 3), (3, 3)],
[(2, 2), (3, 1), (4, 4)],
]
translation = np.min(matrices, axis=1)
translated_matrices = np.array([n-m for n, m in zip(np.array(matrices), translation)])
_, groups = np.unique(translated_matrices, return_inverse=True, axis=0)
unique, idx_groups = npi.group_by(groups, np.arange(len(groups)))
result = [[matrices[idx] for idx in n] for n in idx_groups]
print('groups are:', groups)
print('index groups are:', idx_groups)
print('matrix groups are:', result)
groups are: [0 1 3 0 1 3 0 2]
index groups are: [array([0, 3, 6]), array([1, 4]), array([7]), array([2, 5])]
matrix groups are: [[[(1, 1), (2, 1), (3, 1)], [(1, 2), (2, 2), (3, 2)], [(1, 3), (2, 3), (3, 3)]], [[(1, 2), (2, 1), (3, 1)], [(1, 3), (2, 2), (3, 2)]], [[(2, 2), (3, 1), (4, 4)]], [[(1, 3), (2, 1), (2, 2)], [(2, 3), (3, 1), (3, 2)]]]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.