【问题标题】:How to slice and complie an image into a window effect using Python如何使用 Python 将图像切片并编译成窗口效果
【发布时间】:2022-01-04 13:01:05
【问题描述】:

我想在 python 中分割图像 并将其作为窗口再次粘贴在一起。

图块尺寸为 8 像素 x 9 像素,每行需要跳过 1 像素

然后我需要将这些图块重新合并在一起,并在每个图块周围使用 1 像素填充以产生窗口效果。

图像是黑白的,但在示例中,我使用颜色来显示窗口效果需要有白色背景

input example

Desired Output

【问题讨论】:

  • 合并瓦片的时候,是需要数组,还是画一张图就够了?
  • 绘制图像好

标签: python image-processing cell numpy-slicing cellspacing


【解决方案1】:

您可以尝试使用 scikit-image 包中的 skimage.utils.view_as_windows

from skimage.util import view_as_windows
import matplotlib.pyplot as plt
import numpy as np

img = np.random.rand(90, 90, 1)  # gray-scale image, you can change the channels accordingly
img[8::9,] = 0
tiles = view_as_windows(img, (9, 9, 1), (9, 9, 1)).squeeze(2)  # squeeze out unneded dim
tiles = tiles[:, :, :-1, :, :]  # Remove last row of each tile

# plot the original image
plt.axis("off")
plt.imshow(img.squeeze(2))
plt.show()

# plot the tiles
fig, axes = plt.subplots(10, 10)
for i in range(10):
  for j in range(10):
    axes[i, j].axis("off")
    axes[i, j].imshow(tiles[i, j, ...].squeeze(-1))
plt.show()

结果如下:

原创

切片

PyTorch 中的 torch.Tensor.unfold 运算符也可以是一个选项。

【讨论】:

    【解决方案2】:

    更新:将图块尺寸更改为更大以进行说明,您可以根据需要进行调整
    使用这个:

    import cv2
    
    image = cv2.imread('test.jpg')
    
    tiles_height = 50
    tiles_width = 30
    # white padding
    padding_x = 10
    padding_y = 20
    
    num_y = int(image.shape[0]/tiles_height)
    num_x = int(image.shape[1]/tiles_width)
    new_img = np.full((image.shape[0] + num_y*padding_y, image.shape[1] + num_x*padding_x,3),255)
    
    
    
    for incre_i,i in enumerate(range(0,image.shape[0],tiles_height)):
      for incre_j,j in enumerate(range(0, image.shape[1], tiles_width)):
        new_img[i+incre_i*padding_y:i+tiles_height+incre_i*padding_y
                ,j+incre_j*padding_x:j+tiles_width+incre_j*padding_x,:] = image[i:i+tiles_height,j:j+tiles_width,:]
    cv2.imwrite('res.jpg',new_img)
    print(image.shape, new_img.shape)
    

    更新 1: 因为您想稍后删除图块,所以我添加了可以帮助您的代码。现在您所要做的就是更改tiles configwhite paddingtile index to be removed 中的变量:

    import cv2
    
    image = cv2.imread('test.jpg')
    
    # tiles config
    tiles_height = 50
    tiles_width = 30
    # white padding
    padding_x = 10
    padding_y = 20
    
    # tile index to be removed
    remove_indices = [(0,0),(3,6)]
    
    
    num_y = int(image.shape[0]/tiles_height)
    num_x = int(image.shape[1]/tiles_width)
    new_img = np.full((image.shape[0] + num_y*padding_y, image.shape[1] + num_x*padding_x,3),255)
    
    for incre_i,i in enumerate(range(0,image.shape[0],tiles_height)):
      for incre_j,j in enumerate(range(0, image.shape[1], tiles_width)):
        if (incre_i,incre_j) in remove_indices:
          new_img[i+incre_i*padding_y:i+tiles_height+incre_i*padding_y
                ,j+incre_j*padding_x:j+tiles_width+incre_j*padding_x,:] = 255
        else:
          new_img[i+incre_i*padding_y:i+tiles_height+incre_i*padding_y
                  ,j+incre_j*padding_x:j+tiles_width+incre_j*padding_x,:] = image[i:i+tiles_height,j:j+tiles_width,:]
    cv2.imwrite('remove_tiles.jpg',new_img)
    print(image.shape, new_img.shape)
    

    测试.jpg res.jpg remove_tiles.jpg

    print(image.shape, new_img.shape)(952, 1429, 3) (1332, 1899, 3)

    【讨论】:

    • 这是一个开始,谢谢,但是这段代码也会从每一行中截取数据,我想对每一行中的图块进行切片,然后将它们彼此重新定位
    • @77two4seven4 你想要一个 8x9 的图块,所以在大图像中它们与正方形非常相似,如果你不想丢失数据,那么我会相应地改变我的答案
    • @77two4seven4 检查我的更新。我复制每个图块并将其粘贴到更大的图像中
    • 感谢您的帮助,我认为有误会。我不想在每个矩形周围剪下一部分图像。我希望将图像切成矩形,然后将它们分开,以便输出图像更宽。然后在每一行之间我希望删除一些图像
    • 嗯,我相信我的代码会在不丢失数据的情况下对图像进行切片,然后将它们隔开以使输出图像更宽。在我的答案末尾检查图像的形状
    猜你喜欢
    • 2011-06-20
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 2015-09-13
    • 2019-09-18
    相关资源
    最近更新 更多