【问题标题】:opencv VideoWriter under OSX producing no outputOSX下的opencv VideoWriter不产生输出
【发布时间】:2012-05-23 05:25:39
【问题描述】:

我正在尝试从 Python 包装器为 OSX 下的 OpenCV 创建一个视频。我正在使用 python 2.7.1、opencv 2.3.1a 和来自 willowgarage 的 python 包装器,这些包装器随该版本的 opencv 一起提供。我有:

import cv,cv2
w = cv2.VideoWriter('foo.avi', cv.FOURCC('M','J','P','G'), 25, (100,100))
for i in range(100):
    w.write(np.ones((100,100,3), np.uint8))

OpenCV 说

WARNING: Could not create empty movie file container.
Didn't successfully update movie file.
... [ 100 repetitions]

我不确定下一步该尝试什么

【问题讨论】:

    标签: python opencv


    【解决方案1】:

    关于这个主题有很多过时和不正确的在线指南——我想我几乎每一个都试过了。在查看了 Mac OSX 上基于 QTKit 的 VideoWriter 源代码实现后,我终于能够使用以下代码让 VideoWriter 输出有效的视频文件:

    fps = 15
    capSize = (1028,720) # this is the size of my source video
    fourcc = cv2.cv.CV_FOURCC('m', 'p', '4', 'v') # note the lower case
    self.vout = cv2.VideoWriter()
    success = self.vout.open('output.mov',fourcc,fps,capSize,True) 
    

    要写一个图像帧(注意imgFrame的大小必须和上面的capSize一样,否则更新会失败):

    self.vout.write(imgFrame) 
    

    完成后请务必:

    vout.release() 
    self.vout = None
    

    这适用于 Mac OS X 10.8.5 (Mountain Lion):不保证其他平台。我希望这个 sn-p 可以节省其他人的实验时间!

    【讨论】:

    • 我可以确认此代码适用于 Mavericks、Python 2.7、openCV2
    • 在到达这里之前至少尝试了五个其他 SO 答案。这是唯一一个在带有 Python 2.7 和 OpenCV 2.4.6.1 的 Mavericks 上为我工作的。
    • 与其他评论者的情况相同。我发现决定性因素是使用小写'm', 'p', '4', 'v'。很多其他示例显示fourcc 使用的大写字母,我不知道它是否区分大小写。
    • 这也适用于我。也使用 OpenCV 2 运行 Mavericks (10.9.4)。谢谢!
    • 非常感谢!在此之前,我遇到了很多错误/过时的答案。
    【解决方案2】:

    我使用的是 macOS High Sierra 10.13.4、Python 3.6.5、OpenCV 3.4.1。

    以下代码(来源:https://www.learnopencv.com/read-write-and-display-a-video-using-opencv-cpp-python/)打开摄像头,按“q”成功关闭窗口,并将视频保存为.avi格式。

    请注意,您需要将其作为 .py 文件运行。如果在 Jupyter Notebook 中运行,窗口在关闭时会挂起,需要强制退出 Python 才能关闭窗口。

    import cv2
    import numpy as np
     
    # Create a VideoCapture object
    cap = cv2.VideoCapture(0)
     
    # Check if camera opened successfully
    if not cap.isOpened(): 
      print("Unable to read camera feed")
     
    # Default resolutions of the frame are obtained.The default resolutions are system dependent.
    # We convert the resolutions from float to integer.
    frame_width = int(cap.get(3))
    frame_height = int(cap.get(4))
     
    # Define the codec and create VideoWriter object.The output is stored in 'outpy.avi' file.
    out = cv2.VideoWriter('outpy.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))
     
    while True:
      ret, frame = cap.read()
     
      if ret: 
         
        # Write the frame into the file 'output.avi'
        out.write(frame)
     
        # Display the resulting frame    
        cv2.imshow('frame',frame)
     
        # Press Q on keyboard to stop recording
        if cv2.waitKey(1) & 0xFF == ord('q'):
          break
     
      # Break the loop
      else:
        break 
     
    # When everything done, release the video capture and video write objects
    cap.release()
    out.release()
     
    # Closes all the frames
    cv2.destroyAllWindows() 
    

    【讨论】:

    • 谢谢!我将输出线切换到“cv2.VideoWriter_fourcc('m','p','4','v')”,它对我有用
    【解决方案3】:

    在尝试了各种选项后,我发现我使用的 frame.size 不适合 VideoWriter 中指定的大小:因此将其设置为 iMac 1280x720 的默认值就可以了!

    import numpy as np
    import cv2
    
    cap = cv2.VideoCapture(0)
    
    # Define the codec and create VideoWriter object
    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
    out = cv2.VideoWriter()
    succes = out.open('output.mp4v',fourcc, 15.0, (1280,720),True)
    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret==True:
            frame = cv2.flip(frame,0)
            # write the flipped frame
            out.write(frame)
            cv2.imshow('frame',frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        else:
            break
    
    # Release everything if job is finished
    cap.release()
    out.release()
    cv2.destroyAllWindows()
    

    【讨论】:

      【解决方案4】:

      这是“大小”问题。

      import cv2
      import time
      
      filename = time.strftime("%m-%d-%H-%M-%S") + '.avi'
      fps = 16
      
      cap = cv2.VideoCapture(0)
      
      #in this way it always works, because your get the right "size"
      size = (int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)),
              int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))
      fourcc = cv2.cv.FOURCC('8', 'B', 'P', 'S')     #works, large
      out = cv2.VideoWriter(filename, fourcc, fps, size, True)
      
      #in this way, you must set the "size" to your size, 
      #because you don't know the default "size" is right or not
      #cap.set(3, 640)
      #cap.set(4, 480)
      #out = cv2.VideoWriter(filename, fourcc, fps, (640, 480), True)
      
      while(cap.isOpened()):
          ret, frame = cap.read()
          if ret == True:
              out.write(frame)
              cv2.imshow('frame', frame)
      
          if cv2.waitKey(1) & 0xFF == ord('q'):
              break;
      
      else:
          print 'Error...'
          break;
      
      cap.release()
      out.release()
      cv2.destroyAllWindows()
      

      【讨论】:

        【解决方案5】:

        这是一个适用的版本:

        • Python 3.6.3
        • OpenCV 3.3.1
        • macOS 10.13.1

        使用brew install opencv 安装。

        #!/usr/bin/env python3
        
        import cv2
        
        def main():
            vc = cv2.VideoCapture()
            if not vc.open('input.mp4'):
                print('failed to open video capture')
                return
        
            fourcc = cv2.VideoWriter_fourcc(*'mp4v')
            # Match source video features.
            fps = vc.get(cv2.CAP_PROP_FPS)
            size = (
                int(vc.get(cv2.CAP_PROP_FRAME_WIDTH)),
                int(vc.get(cv2.CAP_PROP_FRAME_HEIGHT)),
            )
        
            vw = cv2.VideoWriter()
            if not vw.open('output.mp4', fourcc, fps, size):
                print('failed to open video writer')
                return
        
            while True:
                ok, frame = vc.read()
                if not ok:
                    break
        
                # Flip upside down.
                frame = cv2.flip(frame, 0)
        
                # Write processed frame.
                vw.write(frame)
        
                cv2.imshow('frame', frame)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
        
            vc.release()
            vw.release()
            cv2.destroyAllWindows()
        
        if __name__ == "__main__":
            main()
        

        【讨论】:

          【解决方案6】:

          您的 ffmpeg 版本可能已过期。我在使用 ffmpeg 0.8 时遇到了类似的问题,升级到 ffmpeg 0.11 后它运行良好。

          【讨论】:

            【解决方案7】:

            以下是对我有用的@ToddStellanova 答案的变体:

            def write_video(image_dir):
              '''
              Writes a video from a set of images in `image_dir`
              '''
              target = join('data/labelled-videos',
                            basename(image_dir) + '.mp4v')
              codec = cv2.cv.CV_FOURCC('m', 'p', '4', 'v')
              size = (256, 256)
              v = cv2.VideoWriter(target, codec, 16, size)
              for image_name in listdir(image_dir):
                image_filename = join(image_dir, image_name)
                arr = np.asarray(Image.open(image_filename))
                assert arr.shape[:2] == size
                v.write(arr)
            

            【讨论】:

              【解决方案8】:

              我的问题在于 frame_widthframe_height。请尝试以下操作:

              import cv2
              
              cap = cv2.VideoCapture(0)
              
              # Define the codec and create VideoWriter object
              fourcc = cv2.VideoWriter_fourcc(*'MJPG')
              frame_width = int(cap.get(3))
              frame_height = int(cap.get(4))
              size = (frame_width, frame_height)
              fps = 10
              out = cv2.VideoWriter("output.avi", fourcc, fps, size)
              
              while(cap.isOpened()):
                  ret, frame = cap.read()
              
                  if ret:
                      out.write(frame)  # write the frame
                      cv2.imshow('frame', frame)
                  else:
                      break
                  if cv2.waitKey(1) == 27:  # Esc
                      break
              
              # Release everything if job is finished
              cap.release()
              out.release()
              cv2.destroyAllWindows()
              

              【讨论】:

                【解决方案9】:

                这不是个好主意

                你必须创建一个VideoWriter结构并使用方法WriteFrame

                import cv
                cv.NamedWindow('cap', 1)
                w = cv.CreateVideoWriter('test.avi',cv.CV_FOURCC('X','V','I','D'),25,(640,480))
                cap = cv.CaptureFromCAM(0)
                while(1):
                    img = cv.QueryFrame(cap)
                    cv.ShowImage('cap', img)
                    cv.WriteFrame(w, img)
                    if cv.WaitKey(1) == 27:
                        break
                cv.DestroyWindow('cap')
                

                【讨论】:

                • 这个答案现在似乎已经过时了。
                【解决方案10】:

                感谢@TeddStellanova

                这里是 XCode C++ 版本:

                int fWidth = capture.get(CV_CAP_PROP_FRAME_WIDTH);
                int fHeight = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
                string vid_path = path + "frames.mov";
                VideoWriter vid(vid_path,CV_FOURCC('m','p','4','v'),30,Size(fWidth,fHeight),true);
                

                【讨论】:

                  猜你喜欢
                  • 2014-06-06
                  • 1970-01-01
                  • 2014-08-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-06-01
                  • 2019-07-11
                  • 2015-02-01
                  相关资源
                  最近更新 更多