opencv 提取后,视频帧上下颠倒

6bc51xsx  于 2022-11-15  发布在  其他
关注(0)|答案(5)|浏览(463)

我的问题是,当我使用opencv将视频提取到一个帧中时,有时我得到的帧会翻转,这在我的机器(窗口)和VM(ubuntu)中都发生过。但我测试的一些视频,帧不会翻转。所以,我想知道应该在我的代码中更改/添加什么因素或什么,以使提取固定而不翻转

def extract_frame(video,folder):
   global fps

   os.mkdir('./green_frame/{folder}/'.format(folder=folder))
   vidcap = cv2.VideoCapture(video)
   success,image = vidcap.read()
   fps = vidcap.get(cv2.CAP_PROP_FPS)
   count = 0
   success = True
   while success:  #os.path.join(pathOut,(name+'.png'))
      cv2.imwrite(os.path.join('./green_frame/{folder}/'.format(folder=folder),"frame%d.png" % count), image)
      success,image = vidcap.read()
      print('Read a new frame: ', success) 
      count += 1

这是我从这个代码中得到的帧的例子。x1c 0d1x我使用的原始视频是这样颠倒的:

所以,在我的情况下,我必须改变,使它不翻转像我的第一张图片。它是与分辨率或帧速率的视频?我测试了一个1280 x720分辨率的视频和所有的帧提取翻转颠倒,但一个帧从视频与568 x320是正常的
谢谢你
编辑:因此,我查看了视频的信息,发现在元数据中,提取到倒置帧

的视频旋转了180,但当我检查产生非倒置帧的正常视频时,它没有旋转:180

因此,如何处理旋转的视频?

2izufjch

2izufjch1#

更新

这个问题现在可以通过简单地更新到OpenCV v4.5和更高版本来解决。
如果升级是个问题,请遵循下面的旧答案。
对于任何还在研究这个问题的人来说,我只是陷入了同样的问题。事实证明,一些Android手机和iPhone在横向拍摄图像/帧,并根据exif“旋转”标签在飞行中转换它们以显示图像/帧。
OpenCV中奇怪的设计选择是cv2.imread(img_file)已经通过阅读图像的rotate标签以正确的方向读取图像,但是cv2.VideoStreamread()方法没有这样做。
所以,为了解决这个问题,我使用ffmpeg来读取'rotate'标签,并将视频帧旋转到正确的方向。(非常感谢上面的评论,为我指出了正确的方向👍)
下面是代码:

  • 确保你有python的ffmpeg。(pip install ffmpeg-python
  • 创建一个方法来检查video_file是否需要旋转:
import ffmpeg    

 def check_rotation(path_video_file):
     # this returns meta-data of the video file in form of a dictionary
     meta_dict = ffmpeg.probe(path_video_file)

     # from the dictionary, meta_dict['streams'][0]['tags']['rotate'] is the key
     # we are looking for
     rotateCode = None
     if int(meta_dict['streams'][0]['tags']['rotate']) == 90:
         rotateCode = cv2.ROTATE_90_CLOCKWISE
     elif int(meta_dict['streams'][0]['tags']['rotate']) == 180:
         rotateCode = cv2.ROTATE_180
     elif int(meta_dict['streams'][0]['tags']['rotate']) == 270:
         rotateCode = cv2.ROTATE_90_COUNTERCLOCKWISE

     return rotateCode
  • 创建一个方法来纠正视频文件中帧的旋转:
def correct_rotation(frame, rotateCode):  
     return cv2.rotate(frame, rotateCode)
  • 最后,在主循环中执行以下操作:
# open a pointer to the video file stream
 vs = cv2.VideoCapture(video_path)

 # check if video requires rotation
 rotateCode = check_rotation(video_path)

 # loop over frames from the video file stream
 while True:
     # grab the frame from the file
     grabbed, frame = vs.read()

     # if frame not grabbed -> end of the video
     if not grabbed:
         break

     # check if the frame needs to be rotated
     if rotateCode is not None:
         frame = correct_rotation(frame, rotateCode)

     # now your logic can start from here

希望这对你有帮助🍻

llycmphe

llycmphe2#

有时,以下方法可以解决颠倒打开某些视频的问题。

cap = cv2.VideoCapture(path, apiPreference=cv2.CAP_MSMF)
tjvv9vkg

tjvv9vkg3#

当我最近遇到这个问题时,我发现所需要的只是更新到OpenCV v4.5:

egmofgnx

egmofgnx4#

rotate标记是可选的,因此check_rotation将失败,以下代码修复了它:

def check_rotation(path_video_file):
    # this returns meta-data of the video file in form of a dictionary
    meta_dict = ffmpeg.probe(path_video_file)
    # from the dictionary, meta_dict['streams'][0]['tags']['rotate'] is the key
    # we are looking for
    rotate_code = None
    rotate = meta_dict.get('streams', [dict(tags=dict())])[0].get('tags', dict()).get('rotate', 0)
    return round(int(rotate) / 90.0) * 90
f0brbegy

f0brbegy5#

我将在帧处理循环中执行以下操作:

frame = cv2.flip(frame,0)

0垂直翻转,有关详细信息,请参见Open CV文档。

相关问题