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

标签 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

8x8 补丁产量的 0,0 补丁:

enter image description here

最佳答案

两件事:

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

  2. 从您的 for 循环索引判断,您想要提取出 不重叠 的 8 x 8 block 。这意味着,如果您有一个 32 x 32 的图像和 8 x 8 的补丁,则总共有 16 个补丁排列在一个 4 x 4 的网格中。

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


结合以上两点,修改后的代码应该是:

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 的奇怪之处在于,如果您有一个单 channel 图像(例如您的案例),并且周围具有相同的强度,它会被可视化为黑色 否不管颜色图是什么,就像我们使用 imsave 时遇到的情况一样。因此,我不得不人为地将其制作成 RGB 图像,但所有 channel 都相同,以便在我们显示图像之前将其可视化为灰度。

我们得到:

enter image description here

关于python - Numpy 图像切片返回黑色补丁/错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32030750/

相关文章:

python - 哪种方法可以更简洁地获取 Python @property 作为具有特定条件的列表?

python - 如何从字符串中删除列表中的所有元素?

python - 哪些验证码解决方案可以与 App Engine 一起使用?

python - 将 Numpy 数组保存为图像

python - Sphinx autodoc 使用模拟卡在 random.choice() 上

python - 我不断收到线性回归过程的错误 :"ValueError: Expected 2D array, got 1D array instead:"

ios - 如何在后台放置按钮?

css - 如何摆脱图像下方和上方的空白区域

php调整图像大小而不损失质量

c++ - 为嵌入式解释器安装为 VS2010 编译的 Numpy