nene
nene

Reputation: 63

The entire frame is rotated after video capture

frame variables pixel is entire frame

environment

3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0]
opencv-contrib-python==4.1.2.30
opencv-python==4.1.2.30

moviefile 30seconds

frame height = 1920, width = 1080

cap = cv2.VideoCapture(video_file_path)
frames = []
while(cap.isOpened()):
    ret, frame = cap.read()
    if ret:
        frames.append(frame)
    else:
        break
plt.imshow(frames[0])

When executed height = 1080, width = 1920

How do I ? Thanks

Upvotes: 1

Views: 1953

Answers (1)

Rotem
Rotem

Reputation: 32084

Your video is rotated by metadata settings, and not encoded as 1080x1920.

The most probable explanation is that the video resolution is 1920x1080 (width=1920, and height=1080) [this is the standard resolution of FullHD video].
It is also probable that the video is captured with the camera rotated by 90 degrees.

Instead of decoding the video, rotating each frame, and encoding the frame, it's possible to add metadata to the video file, that marks the player to rotate the video when playing.
Adding metadata is more efficient (takes minimal time) and may have better quality (because it saves decoding and encoding stages).

Here is an example of rotating mp4 by setting metadata using FFmpeg: Rotate mp4 videos without re-encoding.

When OpenCV reads the video frame, it reads it in the original orientation (1920x1080 and not 1080x1920).

This is a common convention regarding most of the video metadata - OpenCV assumes that you know that the metadata flag is set to "rotated", and assumes you are in charge of rotating the frame before displaying it (your Python program suppose to do the Players job).

Here is an example of creating sample mp4 video file using FFmpeg (in command line):

ffmpeg -y -r 10 -f lavfi -i testsrc=rate=10:size=198x108 -t 5 -c:v libx264 vid0.mp4

Here is an example of rotating the video by setting the metadata:

ffmpeg -i vid0.mp4 -c copy -metadata:s:v:0 rotate=90 vid90.mp4

In the following Python code, the frame shape of both videos is the same: (108, 198, 3) (width=198, height=108):

import cv2
from matplotlib import pyplot as plt

# video_file_path = 'vid0.mp4'

video_file_path = 'vid90.mp4'

cap = cv2.VideoCapture(video_file_path)
frames = []
while(cap.isOpened()):
    ret, frame = cap.read()
    if ret:
        frames.append(frame)
    else:
        break

plt.imshow(frames[0])

You can check the video metadata using mediainfo tool:

enter image description here

Reading the metadata in Python is more difficult than I thought (I never tried it).
You may find a solution here.
[Now I realized your question is probably duplicated].

First video frame of vid90 in MPC-HC Player:
enter image description here

First video frame of vid90 in Python (matplotlib):
enter image description here

Upvotes: 3

Related Questions