在python中将等效图片分组

时间:2019-12-28 05:18:52

标签: python numpy

我有几张图片描绘了几个点(通常是3-10点)的坐标。我想对具有相同点排列的图片进行分组。通过向量(0,1)来移动(a),其中三个点的集合(a)具有坐标(1,1)(2,1)和(3,1),我们可以获得具有( 1,2)(2,2)和(3,2)。类似地,在移动向量(2,0)之后,集合(a)变为(1、3),(2、3)和(3、3)的集合(g)。然后,我们可以将排列相同的集合(a),(d)和(g)进行分组,并视为等效。 你能帮我吗?

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)],
    ])

输出:

[[(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)]

enter image description here

2 个答案:

答案 0 :(得分:2)

这里的想法是通过构造一个键,使用字典对图像进行分组。如果我考虑图像的描绘方式,如果我认为[x - min(x_coords) for x in x_coords][y - min(y_coords) for y in y_coords]的偏移,对于相似的图像,我可以认为坐标沿x轴和y轴的移动是相似的。

例如,对于图像1,x_coords = [1,2,3]y_coords = [2,2,2],由于x和y坐标的最小值分别为1和2,因此偏移将分别为(0, 1, 2)0,0,0。分别。这些移位的组合现在可以用作对不同图像进行分组的关键,如下所示

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)

输出将为

[[(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)]]

答案 1 :(得分:0)

我的想法是也要应用上述坐标移动。我尝试尽可能地保持基于numpy的计算(没有for循环):

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)]]]