Python:中心阵列图像

Python: Center array image

使用 skimage 库,我必须将这些图像居中。我发现 SimilarityTransform 应该接受偏移量,但缺少文档。我将如何检测此类图像的角,然后确定如何将其居中? 阵列总是存在于 28x28 图像之外。有些图像中有噪点,例如此处的第二张图像代表四。我不小心抓到了两张居中的图片,但它们可以在数组中无处不在。 在底部,您还可以看到 4 的更多视觉表示。

[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  11 203 229  32   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  26  47  47  30  95 254 215  13   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0  45 154 185 185 223 253 253 133 175 255 188  19   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0 110 253 253 253 246 161 228 253 253 254  92   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0 128 245 253 158 137  21   0  48 233 253 233   8   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0 139 254 223  25   0   0  36 170 254 244 106   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0  55 212 253 161  11  26 178 253 236 113   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   7 155 253 228  80 223 253 253 109   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0 141 253 253 253 254 253 154  29   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0 110 253 253 253 254 179  38   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   3 171 254 254 254 179   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0 171 253 253 253 253 178   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0  26 123 254 253 203 156 253 200   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0  93 253 254 121  13  93 253 158   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0  64 239 253  76   8  32 219 253 126   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0 133 254 191   0   5 108 234 254 106   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0 132 253 190   5  85 253 236 154   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0 153 253 169 192 253 253  77   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0 112 253 253 254 236 129   9   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0  17 118 243 191 113   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]]

[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  42 164 252  63   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0  23  34   0 244 254 112   0   0   0   0  85   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   4 190 225   0 255 185  13   0   0   0   0  95   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   6 170 254 197  64 254  59   0   0   0   0   0  95   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   9 132 254 204  23 112 254  28   0   0   0   0   0  77   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   6 167 254 216  58  24 242 225  16   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0  76 254 254 162  85 138 254 188   0   0   0  48  85  25   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   3 159 254 254 254 254 254 228 151 151 214 250 254  75   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   7  79 131 158 254 254 226 225 225 225 190 148  39   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0 127 254 148   0   0   0   0   0   0   0  71   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0  23 248 201   0   0   0   0   0   0   0   0  36   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0  85 254 118   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0  12 189 227  22   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0 114 254 103   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0  44 226 175   8   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0 148 203  59   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0  26 242 140   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0 131 169  22   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0  19 233  65   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0 174 109   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]]

解决方案代码: @anmol_uppal.

提供的代码略有改动
def pad_image(img, pad_t, pad_r, pad_b, pad_l):
    """Add padding of zeroes to an image.
    Add padding to an array image.
    :param img:
    :param pad_t:
    :param pad_r:
    :param pad_b:
    :param pad_l:
    """
    height, width = img.shape

    # Adding padding to the left side.
    pad_left = np.zeros((height, pad_l), dtype = np.int)
    img = np.concatenate((pad_left, img), axis = 1)

    # Adding padding to the top.
    pad_up = np.zeros((pad_t, pad_l + width))
    img = np.concatenate((pad_up, img), axis = 0)

    # Adding padding to the right.
    pad_right = np.zeros((height + pad_t, pad_r))
    img = np.concatenate((img, pad_right), axis = 1)

    # Adding padding to the bottom
    pad_bottom = np.zeros((pad_b, pad_l + width + pad_r))
    img = np.concatenate((img, pad_bottom), axis = 0)

    return img

def center_image(img):
    """Return a centered image.
    :param img:
    """
    col_sum = np.where(np.sum(img, axis=0) > 0)
    row_sum = np.where(np.sum(img, axis=1) > 0)
    y1, y2 = row_sum[0][0], row_sum[0][-1]
    x1, x2 = col_sum[0][0], col_sum[0][-1]

    cropped_image = img[y1:y2, x1:x2]

    zero_axis_fill = (images[0].shape[0] - cropped_image.shape[0])
    one_axis_fill = (images[0].shape[1] - cropped_image.shape[1])

    top = zero_axis_fill / 2
    bottom = zero_axis_fill - top
    left = one_axis_fill / 2
    right = one_axis_fill - left

    padded_image = pad_image(cropped_image, top, left, bottom, right)

    return padded_image

# Usage is in a for loop that iterates through 60.000 images.
for item in permuList:
        shuImages.append(center_image(images[item]).reshape((28 * 28)))
img = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 203, 229, 32, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 47, 47, 30, 95, 254, 215, 13, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 154, 185, 185, 223, 253, 253, 133, 175, 255, 188, 19, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 253, 253, 253, 246, 161, 228, 253, 253, 254, 92, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 245, 253, 158, 137, 21, 0, 48, 233, 253, 233, 8, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 254, 223, 25, 0, 0, 36, 170, 254, 244, 106, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 212, 253, 161, 11, 26, 178, 253, 236, 113, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 155, 253, 228, 80, 223, 253, 253, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 253, 253, 253, 254, 253, 154, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 253, 253, 253, 254, 179, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 171, 254, 254, 254, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 253, 253, 253, 253, 178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 26, 123, 254, 253, 203, 156, 253, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 93, 253, 254, 121, 13, 93, 253, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 64, 239, 253, 76, 8, 32, 219, 253, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 133, 254, 191, 0, 5, 108, 234, 254, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 132, 253, 190, 5, 85, 253, 236, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 153, 253, 169, 192, 253, 253, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 112, 253, 253, 254, 236, 129, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 17, 118, 243, 191, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

所以问题的第一部分是找到包含图像的边界框,第二部分涉及将图像居中,对于第二部分,我们将为边界框的每个顶点添加填充。

第 1 部分:

要绘制边界框,方法是我们可以遍历每一行并找到具有 1 个或多个非零元素的行,从顶部和底部执行此过程我们将得到 [=13 的限制=] 和我们通过遍历列对 X-axis 做的一样,Numpy 提供了一些很棒的函数,例如 sum(),我们将使用这个函数来检查 row/column 是否有任何非零字符,在那种情况下 sum > 0:

设(x1, y1)为左上坐标,(x2, y2)为右下坐标,这两点足以定义一个边界框。

col_sum = np.where(np.sum(a, axis = 0)>0)
row_sum = np.where(np.sum(a, axis = 1)>0)
y1, y2 = row_sum[0][0], row_sum[0][-1]
x1, x2 = col_sum[0][0], col_sum[0][-1]
print x1, y1
print x2, y2 

第 2 部分:

现在我们必须将图像居中,而不是计算每边所需的填充,我们只需按照边界框的形状裁剪图像,然后对每边应用相等的填充。

def add_padding(img, pad_l, pad_t, pad_r, pad_b):
    height, width = img.shape
    #Adding padding to the left side.
    pad_left = np.zeros((height, pad_l), dtype = np.int)
    img = np.concatenate((pad_left, img), axis = 1)

    #Adding padding to the top.
    pad_up = np.zeros((pad_t, pad_l + width))
    img = np.concatenate((pad_up, img), axis = 0)

    #Adding padding to the right.
    pad_right = np.zeros((height + pad_t, pad_r))
    img = np.concatenate((img, pad_right), axis = 1)

    #Adding padding to the bottom
    pad_bottom = np.zeros((pad_b, pad_l + width + pad_r))
    img = np.concatenate((img, pad_bottom), axis = 0)

    return img

cropped_image = img[y1:y2, x1:x2]
padded_image = add_padding(cropped_image, 20, 20, 20, 20)