视频捕获后旋转整个帧
The entire frame is rotated after video capture
帧变量像素是整个帧
环境
- python版本
3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0]
- opencv 版本
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
的第一个视频帧:
帧变量像素是整个帧
环境
- python版本
3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0]
- opencv 版本
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
的第一个视频帧: