Search code examples
pythonpython-3.xopencvmorphing

How to morph two grid-like images seamlessly?


I have two images that consist of colored squares with different grid step (10x10 and 12x12).

What I want is to make the first image to be smoothly transformed into the second one.

10x10 grid-like image 12x12 grid-like image

When I use a plain image overlay with cv2.addWeighted() function, the result (left) is not good because of the intersected grid spaces. I suppose it would be better to shift remaining grid cells to the borders and clear out the rest (right).

The weighted average of two grid-like images The desired result of two grid-like images

Is there any algorithm to deal with this task?

Thanks.


Solution

  • You can interpolate each pixel individually between different images.

    import numpy as np
    from scipy import interpolate
    import matplotlib.pyplot as plt
    
    np.random.seed(200)
    
    num_images = 2
    images = np.random.rand(num_images, 8,8)
    
    for index, im in enumerate(images):
        print(f'Images {index}')
        fig = plt.imshow(im)
        plt.show()
    
    

    Initial images

    Interpolating these images:

    
    n_frames = 4
    x_array = np.linspace(0, 1, int(n_frames))
    
    
    def interpolate_images(frame):
        intermediate_image = np.zeros((1, *images.shape[1:]))
        for lay in range(images.shape[1]):
            for lat in range(images.shape[2]):
                tck = interpolate.splrep(np.linspace(0, 1, images.shape[0]), images[:, lay, lat], k = 1)
                intermediate_image[:, lay, lat] = interpolate.splev(x_array[frame], tck)
        return intermediate_image
    
    
    for frame in range(n_frames):
        im = interpolate_images(int(frame))
        fig = plt.imshow(im[0])
        plt.show()
    

    enter image description here