提取后,视频中的帧倒置

时间:2018-11-01 07:48:07

标签: python video-processing opencv3.0

我的问题是,当我使用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

这是我从此代码中获得的帧的示例。 flip 我使用的原始视频是哪个倒过来的:enter image description here

因此,就我而言,我必须进行更改以使其不像我的第一张照片那样翻转。它与视频的分辨率或帧速率有关吗?我使用1280x720分辨率的视频进行了测试,提取的所有帧都上下颠倒,但是从568x320的视频中提取的帧是正常的

谢谢

编辑: 因此,我查看了视频的信息,发现在元数据中,视频旋转180度以将视频提取到上下颠倒的帧中 enter image description here 但是当我检查产生不上下颠倒帧的普通视频时,它没有旋转:180 enter image description here

因此,我该如何处理具有旋转角度的视频?

4 个答案:

答案 0 :(得分:0)

对于仍在研究此问题的任何人,我只是停留在同一问题上。事实证明,一些Android手机和iPhone可以横向拍摄图像/帧,并根据exif的“旋转”标签即时对其进行转换以显示图像/帧。

OpenCV中奇怪的设计选择是cv2.imread(img_file)已经通过读取图像的rotate标签以正确的方向读取了图像,但是cv2.VideoStream的{​​{1}}方法却没有做这个。

因此,要解决此问题,我使用了read()来读取'rotate'标签并将视频帧旋转到正确的方向。(非常感谢上面的评论,使我的方向正确)

以下是代码:

  • 确保您有ffmpeg用于python。 (ffmpeg
  • 创建一种方法来检查video_file是否需要旋转:

    pip install ffmpeg-python
  • 创建一种方法来纠正视频文件中帧的旋转:

    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) 
    

希望这会有所帮助

答案 1 :(得分:0)

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

答案 2 :(得分:0)

有时候下面会解决一些视频打开颠倒的问题。

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

答案 3 :(得分:-1)

我会在您的帧处理循环中执行此操作:

frame = cv2.flip(frame,0)

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