Image Processing #10 - Zoom in animation

 I like to make various effects using OpenCV. If I knew how to use image processing programs such as video editing programs and Photoshop, I would probably have used these programs. But I am a programmer and I can hardly use these programs. So I enjoy using OpenCV to implement the effects I want.


Zoom in

Suppose you want to zoom in to a specific area in the original high-resolution image as shown below.  

The final image area is marked with a box. And the display will use images of this box size. If you zoom in while maintaining the original resolution of image, the resolution will be much lower because you will need to zoom in on the gradually smaller image. This method is also possible, but I don't want the image resolution to be lowered.

So at first, we will start zooming in by reducing the original image to the size of the box image. During zoom-in, the size of the image will gradually become similar to the size of the box, and the final image will be the box image. Therefore, resolution degradation of the final image will not occur.

<original high resolution image and final crop image to zoom in>

To implement zoom-in using OpenCV, the first necessary variable is the zoom-in step. You have to decide how many steps to zoom in.  Let's call this variable "step".

Then you will probably zoom in to the box image, starting with the original image, as shown in the next picture.

<5 step zoom in>


Simplifying the above figure, the following is done.

<simplified concept>

New coordinates can be obtained using interpolation between the four corner coordinates of the original image and the four corner coordinates of the final box image.

To create new coordinates between two coordinates using interpolation, use the interp function of numpy.


numpy.interp(x, xp, fp, left=None, right=None, period=None)

[source]

One-dimensional linear interpolation.

Returns the one-dimensional piecewise linear interpolant to a function with given discrete data points (xpfp), evaluated at x.

Parameters
xarray_like

The x-coordinates at which to evaluate the interpolated values.

xp1-D sequence of floats

The x-coordinates of the data points, must be increasing if argument period is not specified. Otherwise, xp is internally sorted after normalizing the periodic boundaries with xp = xp % period.

fp1-D sequence of float or complex

The y-coordinates of the data points, same length as xp.

leftoptional float or complex corresponding to fp

Value to return for x < xp[0], default is fp[0].

rightoptional float or complex corresponding to fp

Value to return for x > xp[-1], default is fp[-1].

periodNone or float, optional

A period for the x-coordinates. This parameter allows the proper interpolation of angular x-coordinates. Parameters left and right are ignored if period is specified.

New in version 1.10.0.

Returns
yfloat or complex (corresponding to fp) or ndarray

The interpolated values, same shape as x.

Raises
ValueError

If xp and fp have different length If xp or fp are not 1-D sequences If period == 0


In order to speed up processing, the coordinates should be obtained in advance using interpolation and stored in Python list variable.

import numpy as np
import cv2
import time, math, os, sys, random


pos_tl = []
pos_tr = []
pos_bl = []
pos_br = []
def prepare_zoom(img, pos, w, h, step):
    global pos_bl, pos_br, pos_tl, pos_tr
    img_h, img_w, _ = img.shape
    # tl = (0,0)
    # tr = (img_w,0)
    # bl = (0,img_h)
    # br = (img_w,img_h)
    l_step = pos[0] / step
    r_step = (img_w -pos[0] - w) / step


    for i in range (step):
        x = i * l_step
        y_new = np.interp(x, [0, pos[0]],  [0, pos[1]])
        pos_tl.append((int(x), int(y_new)))

        y_new = np.interp(x, [0, pos[0]], [img_h, h + pos[1]])
        pos_bl.append((int(x), int(y_new)))

        x = img_w - i * r_step
        y_new = np.interp(x, [img_w, w + pos[0]], [0, pos[1]])
        pos_tr.append((int(x),int(y_new)))

        y_new = np.interp(x, [img_w, w + pos[0]], [img_h, h + pos[1]])
        pos_br.append((int(x), int(y_new)))


def zoom(img, w, h, cur_step):
    tl = pos_tl[cur_step]
    tr = pos_tr[cur_step]
    bl = pos_bl[cur_step]
    br = pos_br[cur_step]
    new_img = img[ tl[1]:bl[1], tl[0]:tr[0], :]
    new_img = cv2.resize(new_img, (w, h))
    return new_img

filename = 'C:\\MyProject\\led\\tmp\\20201112_165308.jpg'
img = cv2.imread(filename, cv2.IMREAD_COLOR)

step = 100
w = 960
h = 600
prepare_zoom(img, (2600, 330), w, h, step)

for i in range(step):
    im = zoom(img, w, h, i)
    cv2.imshow('zoom', im)
    cv2.waitKey(20)


cv2.waitKey(0)
cv2.destroyAllWindows()

<zoomin.py>

The most important part of the code above is the prefix_zoom function. In this function, interpolation is used to obtain the image coordinates for each zoom in step.

The parameters are as follows.

  • img : first high resolution image
  • (2600, 330): Top left coordinates of the final zoom-in box image
  • w: Box width
  • h: Box Height
  • Step : Zoom in step. Increasing this value enables sophisticated zoom in implementation.


By executing the above code, you will get the following results: The path of the image file will need to be changed to suit your PC environment.

<zoom in result>

Wrapping up

You can adjust the box coordinates, size, and zoom-in steps to implement zoom-in to the location you want.






댓글

이 블로그의 인기 게시물

Image Processing #7 - OpenCV Text

Playing YouTube videos using OpenCV

OpenCV Installation - Rasbian Buster, Jessie, DietPi Buster