在 Python 中使用 view_as_blocks 更改块后生成图像

Generate image back after changing blocks with view_as_blocks in Python

我想更改下图的给定块,然后重建图像。

我想从这样的图像中划分和更改 224x224x3 块中的像素。由于图像是1024x1024x3,不会有整数个224x224x3块,numpyso,我必须select图像的一个子区域来适应块形状,如下所示:

>>> block_shape = np.array((224, 224, 3))
>>> nblocks = np.array(img.shape) // block_shape  # integer division
>>> crop_r, crop_c, crop_ch = nblocks * block_shape
>>> cropped_img = img[:crop_r, :crop_c, :crop_ch]

因此,裁剪后的图像是图像的一个子区域,它将 select 224x224x3 像素的非重叠块

>>> cropped_img.shape
(896, 896, 3)
>>> Blocks = view_as_blocks(cropped_img, block_shape=(224, 224, 3))
>>> Blocks.shape
(4, 4, 1, 224, 224, 3)

现在,假设我想更改给定块的像素,例如将第一个块的所有像素归零:

Blocks[0,0,:,:,:,:]=Blocks[0,0,:,:,:,:]*0

现在我有一个块的块改变了。然后,我需要恢复 cropped_img 并更改该块(通过将变量 Blocks 转换回只有一个 image/NumPy 数组),最后保存图像。如何在 Python 中做到这一点?

P.s=我检查了一个类似的线程()但是所考虑的图像具有不同的形状,通道以及通道的顺序也不同。

这里的好处是 view_as_blocks returns 数组的 view。所以如果你修改块in-place,你将修改原始数组,你不需要“解锁”:

from skimage import data, util
import matplotlib.pyplot as plt

image = data.camera()
blocked = util.view_as_blocks(image, (256, 256))
blocked[0, 0] *= 0

fig, ax = plt.subplots()
ax.imshow(image)
plt.show()

给出:

如果您 需要取消块,您希望将块视为嵌套列表,并使用对 np.concatenate 的调用来连接引导轴上的块沿剩余个轴。

在这种情况下,主导轴是块的 ,我们想要沿着其余轴的行连接,即轴 1:

intermediate = np.concatenate(blocked, axis=1)
print(intermediate.shape)

打印:

(2, 512, 256)

所以我们现在有两个“高”块,我们想沿着列将它们连接起来,在忽略引导轴之后,这又是轴 1。

unblocked = np.concatenate(intermediate, axis=1)

fig, ax = plt.subplots()
ax.imshow(unblocked)
plt.show()

这显示了与上面相同的图像。

对于你的彩色图片,原理是一样的,你只需要将axis=1切换为axis=2即可。

如果你愿意直接使用Imagemagick(或者如果使用Python子进程调用或者使用基于Imagemagick的PythonWand做同样的事情),这很简单。甚至 non-full-sized 个图块也得到适当保留。

输入:

convert man.jpg -crop 50x50% man_tile_%02d.png

这会生成一个 2x2 的图块阵列,标签为 man_tile_00.png man_tile_01.png man_tile_02.png 和 man_tile_03.png

然后重建它:

convert man_tile_*.png -background none -flatten man_tile_reconstitute.jpg