Numpy图像切片返回黑色补丁/错误值

时间:2015-08-16 00:36:38

标签: python image numpy image-processing scipy

最终目标是拍摄图像并将其切片成我保存的样本。问题是我的切片随机返回黑色/不正确的补丁。贝娄是一个小样本计划。

import scipy.ndimage as ndimage
import scipy.misc as misc
import numpy as np

image32 = misc.imread("work0.png")
patches = np.zeros((36, 8, 8))
for i in range(4):
  for j in range(4):
    patches[i*4 + j] = image32[i:i+8,j:j+8]
    misc.imsave("{0}{1}.png".format(i,j), patches[i*4 + j])

我的形象的一个例子是:

Letter that I'm getting patches of

0x的8x8补丁产生补丁:

enter image description here

1 个答案:

答案 0 :(得分:6)

两件事:

  1. 您正在将补丁矩阵初始化为错误的数据类型。默认情况下,numpy会将修补程序矩阵设为np.float64类型,如果您将其用于保存,则无法获得预期的结果。具体来说,如果您查阅Mr. F's answer,实际上会对浮点图像执行一些缩放,其中图像的最小值和最大值分别缩放为黑色和白色,因此如果您的图像完全均匀,则背景,最小值和最大值都是相同的,并且可视化为黑色。因此,最好的方法是尊重原始图像的数据类型,即将补丁矩阵的dtype设置为np.uint8

  2. 根据您的for循环索引,您想要提取出8 x 8 非重叠的补丁。这意味着如果你有一个带有8 x 8补丁的32 x 32图像,那么总共有 16个补丁以4 x 4网格排列。

  3. 因此,您需要更改patches语句,使其在第一维中具有16,而不是36.此外,您必须调整索引到图像的方式以提取出来8 x 8补丁,因为现在补丁是重叠的。具体来说,您希望图像修补程序索引的行从8*i8*(i+1),列的8*j8*(j+1)。如果您自己替换ij的样本值,您会看到我们为您图片中的每个网格获得了唯一的8 x 8补丁。

    我注意到上述两件事,修改后的代码应为:

    import scipy.ndimage as ndimage
    import scipy.misc as misc
    import numpy as np
    
    image32 = misc.imread('work0.png')
    
    patches = np.zeros((16,8,8), dtype=np.uint8) # Change
    
    for i in range(4):
        for j in range(4):
            patches[i*4 + j] = image32[8*i:8*(i+1),8*j:8*(j+1)] # Change
            misc.imsave("{0}{1}.png".format(i,j), patches[i*4 + j])
    

    当我这样做并看一下输出图像时,我得到了我期望的结果。

    为了绝对确定,让我们使用matplotlib绘制片段。您已经方便地保存了patches中的所有补丁,因此它不应该是显示我们需要的问题。但是,我会在注释中放置一些代码,以便您可以使用上面的代码读取从磁盘保存的图像,这样您就可以验证它是否仍然有效,无论是查看patches还是磁盘上的图像:

    import matplotlib.pyplot as plt
    
    plt.figure()
    for i in range(4):
        for j in range(4):
            plt.subplot(4, 4, 4*i + j + 1)
            img = patches[4*i + j]
            # or you can do this:
            # img = misc.imread('{0}{1}.png'.format(i,j))
            img = np.dstack([img, img, img])
            plt.imshow(img)
    
    plt.show()
    

    关于matplotlib.pyplot.imshow的奇怪之处在于,如果你有一个单一通道的图像(例如你的情况),它周围具有相同的强度,无论颜色图是什么,它都会被显示为黑色,很像我们在imsave时遇到的情况。因此,我必须人为地将其设为RGB图像,但所有通道都相同,因此在我们显示图像之前,这会被视为灰度。

    我们得到:

    enter image description here