pythonimage-processingcellnumpy-slicingcellspacing

How to slice and complie an image into a window effect using Python


I would like to slice up an image in python and paste it back together again as a window.

The tiles measure as 8pixels by 9pixels and each row needs to skip 1 pixel

I would then need to merge the tiles back together again with a 1 pixel padding around each tile to give a windowed effect.

The image is black and white but for the example I have used color to show that the windowed effect would need to have a white background

input example

Desired Output


Solution

  • Update: change tiles dimension to bigger for illustration, you can adjust per your need
    Use this:

    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)
    

    Update 1: Because you want to latter remove tiles, I added code that can help you with that. Now all you have to do is changing variables in tiles config, white padding, tile 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)
    

    test.jpg enter image description here res.jpg enter image description here remove_tiles.jpg enter image description here

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