Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize frame's from video with aspect ratio

I am using Python 2.7, OpenCV. I have written this code.

import cv2
vidcap = cv2.VideoCapture('myvid2.mp4')
success,image = vidcap.read()
count = 0;
print "I am in success"
while success:
  success,image = vidcap.read()
  resize = cv2.resize(image, (640, 480)) 
  cv2.imwrite("%03d.jpg" % count, resize)     
  if cv2.waitKey(10) == 27:                     
      break
  count += 1

I am working with video and am dividing the video into individual frames, as a .jpg images. I am also at the same time resizing the frames to dimension 640x480. The order of the frames is also being preserved. The only issue with the code is that it does not save the previous image-ratio.

For example how it look's like, resize from 1920x1080: Resized image by pure code

There is a problem in ratio, as you can see. 1920x1080 16:9, but 640:480 4:3

How I ideally want it to be: Resized image in ideal code

Thank you for your taking the time for reading the question. I will be very glad if you can help me solve this issue~ Have a good day, my friend.

like image 432
GGzet Avatar asked Apr 10 '17 05:04

GGzet


People also ask

How do I change the video ratio in Canva?

Just add the width and height in pixels of your desired aspect ratio. Then, click Resize to change the current design or click Copy and Resize to preserve the video and create a resized copy. Go the extra mile to fit a specific platform.


3 Answers

Instead of using hard-coded values 640 and 480, you can divide the original frame height and width by a value and supply that as an argument, like so:

import cv2

vidcap = cv2.VideoCapture("/path/to/video")
success, image = vidcap.read()
count = 0

while success:
    height, width, layers = image.shape
    new_h = height / 2
    new_w = width / 2
    resize = cv2.resize(image, (new_w, new_h))
    cv2.imwrite("%03d.jpg" % count, resize)
    success, image = vidcap.read()
    count += 1
like image 51
Saransh Kejriwal Avatar answered Sep 23 '22 06:09

Saransh Kejriwal


Please try this.. It should give you the expected output.

 def resize_image(image, width, height,COLOUR=[0,0,0]):
    h, w, layers = image.shape
    if h > height:
        ratio = height/h
        image = cv2.resize(image,(int(image.shape[1]*ratio),int(image.shape[0]*ratio)))
    h, w, layers = image.shape
    if w > width:
        ratio = width/w
        image = cv2.resize(image,(int(image.shape[1]*ratio),int(image.shape[0]*ratio)))
    h, w, layers = image.shape
    if h < height and w < width:
        hless = height/h
        wless = width/w
        if(hless < wless):
            image = cv2.resize(image, (int(image.shape[1] * hless), int(image.shape[0] * hless)))
        else:
            image = cv2.resize(image, (int(image.shape[1] * wless), int(image.shape[0] * wless)))
    h, w, layers = image.shape
    if h < height:
        df = height - h
        df /= 2
        image = cv2.copyMakeBorder(image, int(df), int(df), 0, 0, cv2.BORDER_CONSTANT, value=COLOUR)
    if w < width:
        df = width - w
        df /= 2
        image = cv2.copyMakeBorder(image, 0, 0, int(df), int(df), cv2.BORDER_CONSTANT, value=COLOUR)
    image = cv2.resize(image,(1280,720),interpolation=cv2.INTER_AREA)
    return image
like image 27
Jobin Mathew Avatar answered Sep 22 '22 06:09

Jobin Mathew


Wanted to add onto what Saransh mentioned about dividing. Dividing works great, but I believe the resize function expects that the new dimensions be an int object, so make sure you use the int(x) or round(x, 0) function to do so.

like image 41
ThePython1 Avatar answered Sep 20 '22 06:09

ThePython1