【问题标题】:opencv - video looks good but frames are rotated 90 degreesopencv - 视频看起来不错,但帧旋转了 90 度
【发布时间】:2021-04-06 18:44:50
【问题描述】:

我们将视频保存在移动客户端上并将其发送到服务器。在服务器上,我使用以下代码保存帧:>

import skvideo.io
import cv2

haar = 
'/home/ubuntu/opencv/data/haarcascades/haarcascade_frontalface_alt.xml'
face_cascade = cv2.CascadeClassifier(haar)

ret = True

video = 'my_video.mov'
i = 0
while ret == True:
    cap = skvideo.io.VideoCapture(video)
    ret, frame = cap.read()
    cv2.imwrite('frame_'+str(i)+'.jpg',frame)
    i+=1

当我们在 windows 媒体播放器或 iTunes 上播放视频时,它看起来不错。 IE。玩家知道如何定位它。

但是 skvideo.io 不知道,我们保存的那些帧是逆时针旋转 90 度的。

我们如何将信息嵌入到该 skvideo 知道正确方向的视频文件(.mov)文件中?

【问题讨论】:

  • 有什么理由使用skvideo.io 而不是cv2.VideoCapture API?

标签: python opencv


【解决方案1】:

skvideo 出现故障,它没有读取可用的元数据。对于手机拍摄的视频是旋转的,但元数据包含这样的参数。 skvideo 团队进行了修复,当前 skvideo 版本 1.1.7 会从移动设备读取元数据,这表明应该对视频进行轮播。 skvideo.io.vread 然后旋转文件:

1) 使用更新的 skvideo 版本,1.1.7,可以在https://github.com/scikit-video/scikit-video进行克隆

2)您可以使用以下代码读取视频中的所有帧,很可能会读取元数据

import skvideo.io
videogen = skvideo.io.vread(f.name)

如果以纵向模式拍摄,它将自动旋转视频。

3) 在 skvideo repo 上创建了一个问题,进一步参考:https://github.com/scikit-video/scikit-video/issues/40

【讨论】:

  • 谢谢!如果您支持我的解决方案,我不会生气! :)
  • 确认即使使用 OpenCV 4 这仍然是一个问题...使用 scikit-video 对我有用,这要归功于它与 ffmpeg 集成以读取视频方向/旋转元数据。
  • 显然在opencv 4.5中解决了github.com/opencv/opencv/issues/15499
【解决方案2】:

看起来OpenCV 没有记录带有VideoCapture() 的视频文件的旋转元数据,您可以从它存储的propIds 中看到。

我不确定scikit-video 是否可以。看起来他们有一个名为 ffprobe 的元数据提取器,它可能能够拉动旋转。有关如何调用和查看输出的示例,请参阅 here。这显示了大量元数据列表——没有旋转——但这可能只是因为它没有设置或者是没有旋转元数据的电影类型。

获取它的另一种方法是直接从ffmpeg 读取元数据。我找到了一个old StackOverflow answer,它写了一点python 代码,专门使用ffmpeg 从视频中提取旋转元数据。

【讨论】:

  • @AlejandroSimkievich 如果您确实找到了 scikit-videoffmpeg 的精确解决方案,您应该使用它编辑您的原始问题,以便其他有此问题的人可以轻松找到可行的方法!跨度>
【解决方案3】:

我安装了“ffmpeg”(“ffprobe”)。我的电脑是 Ubuntu 18.04。 然后 Python,get_rotation() 函数为我工作。

功能代码:

import subprocess
import shlex
import json
def get_rotation(self, file_path_with_file_name):
    cmd = "ffprobe -loglevel error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1"
    args = shlex.split(cmd)
    args.append(file_path_with_file_name)
    ffprobe_output = subprocess.check_output(args).decode('utf-8')
    if len(ffprobe_output) > 0:  # Output of cmdis None if it should be 0
        ffprobe_output = json.loads(ffprobe_output)
        rotation = ffprobe_output
    else:
        rotation = 0
    return rotation

【讨论】:

    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    相关资源
    最近更新 更多