使用skimage view_as_windows制作图像补丁并重建补丁

时间:2019-07-01 08:01:01

标签: python opencv scikit-image

我想从512x512彩色图像中提取彩色图像补丁,并将其作为单独的图像补丁保存在文件夹中。如何从这些图像补丁中重建原始图像? 我已经阅读并查看了一些类似的问题,但是它们并不能解决我的问题。

我做了一些阅读工作,并决定使用SKimage的view_as_windows函数进行图像修补。我还设法将补丁保存到png文件中。

当前,在显示输出数组的详细信息时,当前使用SKimage view_as_window从大小为512x512 patch_img = view_as_windows(input_img, (128, 128, 3), step=64)的彩色图像中提取色块,我注意到patch_img的形状为(7,7,1,128 ,128,3)和unint8的dtype。要将每个补丁保存为单独的图像,请使用以下代码。

    for i in range(0, len(patch_img)):    #range should be 0 to 6
        for x in range(0, len(patch_img)):
            fname= 'IMG_test_{}_{}.png'.format(i, x)
            #cv2.imwrite(fname, crop_img[i,x,0,:,:,:])

使用CV2将保存的图像加载到整个文件夹时,我无法恢复到patch_img的相同形状和dtype,而是得到了形状(49、128、128、3)。我该如何解决。

编辑:使用savedimg = savedimg.reshape(7,7,128 128, 3)

修复了形状

然后,我该如何使用保存的图像补丁来重建原始图像?

1 个答案:

答案 0 :(得分:1)

让我们首先假设我们正在做一些简单的事情。假设我们要拆分2D数字数组,而不是2D RGB数组,如下所示:

>>> image_arr = np.array(list(range(1, 26))).reshape((5,5))
>>> image_arr
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.],
       [11., 12., 13., 14., 15.],
       [16., 17., 18., 19., 20.],
       [21., 22., 23., 24., 25.]])

现在,假设我们要将其拆分为2x2个窗口:

>>> patch_arr = view_as_windows(image_arr, (2,2))

让我们比较两个数组的形状:

>>> image_arr.shape
(5, 5)
>>> patch_arr.shape
(4, 4, 2, 2)

现在,(如果我对您的理解正确),您在问我们如何使用image_arr来重建patch_arr

我们要采用的方法是,创建一个空的np.array,然后将获取每个“补丁”并将其粘贴到图像上。由于它们是重叠的,这意味着我们将多次将相同的值写入大多数单元格,但这当然不是问题。

您还可以尝试优化此方法,以仅向每个单元写入一次,但是在这种情况下,我不确定这样做是否值得。

  1. 让我们创建一个空数组
>>> reconstructed_arr = np.zeros(shape=(5,5))
>>> reconstructed_arr
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.]])
  1. 我们现在遍历补丁并将其粘贴到reconstructed_arr
for x in range(patch_arr.shape[0]):
    for y in range(patch_arr.shape[1]):
        reconstructed_arr[x:x + 2, y:y + 2] = patch_arr[x,y]
  1. 就这样
>>> reconstructed_arr
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.],
       [11., 12., 13., 14., 15.],
       [16., 17., 18., 19., 20.],
       [21., 22., 23., 24., 25.]])

类似的方法需要应用于您的数据(这次使用另一个轴作为RGB值):

  1. 生成随机的input_img数组
input_img = np.random.rand(512, 512, 3)
  1. 让我们像您一样创建补丁:
patch_img = view_as_windows(input_img, (128, 128, 3), step=64)
  1. 用于重建的空数组:
>>> reconstructed_arr = np.zeros((512, 512, 3))
  1. 自从您使用step=64以来,对for循环进行了一些小的调整。
>>> step = 64
>>> for x in range(patch_img.shape[0]):
        for y in range(patch_img.shape[1]):
            x_pos, y_pos = x * step, y * step
            reconstructed_arr[x_pos:x_pos + 128, y_pos:y_pos + 128] = patch_img[x, y, 0, ...]
>>> (input_img == reconstructed_arr).all()
True