在 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
我想更改下图的给定块,然后重建图像。
我想从这样的图像中划分和更改 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