视频捕获后旋转整个帧

The entire frame is rotated after video capture

帧变量像素是整个帧

环境

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

电影文件 30秒

帧 高度 = 1920,宽度 = 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])

执行时 高度 = 1080,宽度 = 1920

我怎么办? 谢谢

您的视频根据 元数据 设置旋转,未编码为 1080x1920。

最可能的解释是视频分辨率为 1920x1080(宽度=1920,高度=1080)[这是 FullHD 视频的标准分辨率]。
视频也有可能是相机旋转 90 度后拍摄的。

可以将元数据添加到视频文件,标记播放器在播放时旋转视频,而不是解码视频、旋转每一帧和编码帧。
添加元数据效率更高(花费最少的时间)并且可能具有更好的质量(因为它节省了解码和编码阶段)。

这是一个通过使用 FFmpeg: Rotate mp4 videos without re-encoding 设置元数据来旋转 mp4 的示例。

当 OpenCV 读取视频帧时,它会以原始方向(1920x1080 而不是 1080x1920)读取它。

这是关于大多数视频元数据的常见约定 - OpenCV 假设您知道元数据标志设置为 "rotated",并假设您负责在显示之前旋转帧(您的Python 程序假设执行玩家的工作)。

以下是使用 FFmpeg(在命令行中)创建示例 mp4 视频文件的示例:

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

下面是一个通过设置元数据来旋转视频的例子:

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

在下面的Python代码中,两个视频的帧形状相同:(108, 198, 3)(宽度=198,高度=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])

您可以使用 mediainfo 工具检查视频元数据:

读取 Python 中的元数据比我想象的要难(我从未尝试过)。
您可能会找到解决方案 .
[现在我意识到你的问题可能是重复的]。

MPC-HC 播放器中 vid90 的第一个视频帧:

Python(matplotlib)中 vid90 的第一个视频帧: