简体   繁体   中英

Group the equivalent pictures in python

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)

Output:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM