【问题标题】:Python OpenCV `ZeroDivisionError: float division by zero` in loopPython OpenCV`ZeroDivisionError:在循环中浮点除以零
【发布时间】:2021-02-15 15:16:33
【问题描述】:

编辑:

简而言之:

cap = cv2.VideoCapture(input_loc); 
fps = cap.get(cv2.CAP_PROP_FPS)

从循环中的第二个视频开始返回 ZeroDivisionError: float division by zero。 (在第一个视频上工作正常)

注意:已经在Python OpenCV video.get(cv2.CAP_PROP_FPS) returns 0.0 FPS 中尝试过解决方案,但没有解决我的问题。


很抱歉,由于我不确定如何描述我的问题,所以标题似乎很模糊。

简而言之,我猜 OpenCV 无法从第二个视频开始加载视频。也许是因为我忘了重置一些东西?

我的目标是从多个视频中提取帧,所以我实现了一个函数来做到这一点:

def video_to_frames(input_loc, output_loc, filename, sec):
    """Function to extract frames from input video file
    and save them as separate frames in an output directory.
    Args:
        input_loc: Input video file.
        output_loc: Output directory to save the frames.
        filename: name of the video file
        sec: how many seconds per frame
    """
    
    try:
        os.mkdir(output_loc)
    except OSError:
        pass

    # Start capturing the feed
    cap = cv2.VideoCapture(input_loc)
        
    # Find the total duration of videos
    fps = cap.get(cv2.CAP_PROP_FPS)
    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    video_length = frame_count/fps
 
    print("Video Length:", video_length)
    

    count = 1
    timepoint = count*sec*1000
    
    # Start converting the video
    while cap.isOpened():
        # Extract the frame
        cap.set(cv2.CAP_PROP_POS_MSEC,(timepoint))      
        ret, frame = cap.read()
        
        for t in range(-2, 3):
            cap.set(cv2.CAP_PROP_POS_MSEC,(timepoint + t*50))
            ret, frame = cap.read()
            cv2.imwrite("{}{}-{}-{}.png".format(output_loc, filename[:-4], count-1, t+2), frame[:480, :640, :]) # the shape of frame should be consistent

        count = count + 1 # jump to the next frame
        timepoint = count*sec*1000


        # If there are no more frames left
        if (timepoint > ((video_length -1 ) *1000)):
            # Release the feed
            cap.release()
            # Print stats
            print ("{} frames extracted".format(count-1))

            break
    
    return  video_length, count

为了执行这个函数,我把它放在一个循环中

frames = 0
extracts = 0
total_frames = 0

for file_name in video_list:

    input_path = input_path + "{}".format(f)
    print (file_name)
    video_to_frames(input_path, output_path, file_name, 2)

cv2.destroyAllWindows()

我的问题是提取第一个文件似乎很好,但是一旦它移动到下一个文件,就会出现一些问题,所以我收到如下错误:

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-55-002937137b8e> in <module>()
      7     input_path = input_path + "{}".format(f)
      8     print (file_name)
----> 9     video_to_frames(input_path, output_path, file_name, 2)
     10 
     11 cv2.destroyAllWindows()

<ipython-input-52-e4a4392eaa12> in video_to_frames(input_loc, output_loc, filename, sec)
     22     fps = cap.get(cv2.CAP_PROP_FPS)
     23     frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
---> 24     video_length = frame_count/fps
     25 
     26     print("Video Length:", video_length)

ZeroDivisionError: float division by zero

任何人都知道为什么以及如何处理这个问题?

【问题讨论】:

  • 很明显,您得到了除以 0。您可以将脚本缩减为 cap = cv2.VideoCapture(input_loc); fps = cap.get(cv2.CAP_PROP_FPS),并询问为什么 fps 为 0 以获得等效但更简洁的问题。
  • 我尝试了该链接中的解决方案,但它实际上返回了Requirements already satisfied
  • 你能验证input_loc 的文件确实存在吗? cv2.VideoCapture() 在尝试加载不存在的文件时不会引发错误,并且提取 fps 显然会返回 0。
  • 循环的列表是由video_list = sorted(os.listdir(input_path))生成的,所以我猜这不是问题?

标签: python opencv


【解决方案1】:

问题发生是因为

input_path = input_path + "{}".format(f)

这一行使输入文件名错误,变成了这样:

clip_2.avi24.36

【讨论】:

    猜你喜欢
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多