OpenCV VideoWriter输出零KB视频文件

62lalag4  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(192)

我有下面的代码:

# Setup Video capture
cap = cv2.VideoCapture(args['video_path'])
# Read a frame from the video
ret, frame = cap.read()
fps = cap.get(cv2.CAP_PROP_FPS)

'''
Print some information about the video
'''
print('\n#######################################')
print(f'Video Resolution: {frame.shape}')
print(f'Video FPS: {fps:.2f}')
total_num_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print(f'Total video frames: {total_num_frames}')
print('#######################################\n')

input('Press Enter to start processing video...\n')

'''
Video Writer
    - output path
    - codec
    - FPS
    - resolution (width,height)    
'''
width = frame.shape[1] #output width
height = frame.shape[0] #output height

fourcc = cv2.VideoWriter_fourcc(*'XVID') # try *'mp4v' instead of XVID
out = cv2.VideoWriter('./demo_output/demo_result.avi', fourcc, 30, (width, height))

# Set current_frame progress to 0 before main loop
current_num_frame = 0
while True:
    # Loop through each frame of the video capture
    try:
        if width < 1920 and height < 1080:
            print('Resolution too small')
            break
        elif width >=3840 and height >=2160:
            ret, frame = cap.read()
            scale_factor = 0.5
            frame = cv2.resize(frame, (0, 0), fx=scale_factor, fy=scale_factor) # interpolation=cv2.INTER_LANCZOS4
            ori_img = frame.copy()
            print('4K Res check: True')
        else:
            ret, frame = cap.read()
            print('Other res chech: True')
    except:
        print("Finished")
        cap.release()
        break

    frame = frame.copy()
    image = tensor_transform(frame)
    image = img_transform(image).unsqueeze(0)
    print('Img transformations: True')

    with torch.no_grad():
        d6 = model(image)
        print('Model output: True')

        count, pred_kpoint = counting(d6) # (540, 960), count = int(scalar)
        # point_map = generate_point_map(pred_kpoint) # (540, 960, 3)
        box_img = generate_bounding_boxes(pred_kpoint, frame) # (540, 960, 3)
        print('box_img output: True')
        # show_fidt = show_fidt_func(d6.data.cpu().numpy()) # (540, 960, 3)

        # res1 = np.hstack((ori_img, show_fidt)) # (540, 1920, 3)
        # res2 = np.hstack((box_img, point_map)) # (540, 1920, 3)
        # res = np.vstack((res1, res2)) # (1080, 1920, 3)

        cv2.putText(box_img, "Count:" + str(count), (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        # cv2.imwrite('./demo_output/demo.jpg', res)
        '''write in out_video'''
        out.write(box_img)
        print('Video write: True')
    current_num_frame += 1
    print(f"Pred: {int(count)}, frame: {current_num_frame} / {total_num_frames}")

而我的目标是读取视频的宽度和高度(分辨率)。根据分辨率,我不想继续,或者缩小视频,或者什么都不做,继续。
在4K视频上,它不起作用,但它确实进入了if语句,因为它是真的。print语句表明。
1080p视频在另一方面工作。它不会被缩小,VideoWriter会产生一个工作。avi文件。
如果我删除if语句,只保留原始视频中的缩小步骤,它仍然不起作用。

while True:
    # Loop through each frame of the video capture
    try:
        ret, frame = cap.read()
        scale_factor = 0.5
        frame = cv2.resize(frame, (0, 0), fx=scale_factor, fy=scale_factor) # interpolation=cv2.INTER_LANCZOS4
        # ori_img = frame.copy()
        print('4K Res check: True')
    except:
        print("Finished")
        cap.release()
        break

    frame = frame.copy()
    image = tensor_transform(frame)
    image = img_transform(image).unsqueeze(0)

在我搞砸之前的原始代码只是缩小视频,它曾经工作过。但是当我用1080p而不是4K来尝试它时,降尺度正在破坏质量。所以我想把一个分辨率检查,以阻止它从降频,如果视频是1080p。
最后一件事是,代码不会产生错误,一切似乎都完美地工作:

编辑:

with torch.no_grad():
    d6 = model(image)

    count, pred_kpoint = counting(d6) # (540, 960), count = int(scalar)
    point_map = generate_point_map(pred_kpoint) # (540, 960, 3)
    box_img = generate_bounding_boxes(pred_kpoint, frame) # (540, 960, 3)
    show_fidt = show_fidt_func(d6.data.cpu().numpy()) # (540, 960, 3)

    res1 = np.hstack((ori_img, show_fidt)) # (540, 1920, 3)
    res2 = np.hstack((box_img, point_map)) # (540, 1920, 3)
    res = np.vstack((res1, res2)) # (1080, 1920, 3)

    cv2.putText(res, "Count:" + str(count), (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    # cv2.imwrite('./demo_output/demo.jpg', res)
    '''write in out_video'''
    out.write(res)

如果我写res变量,它是输出的组合(这是以前的做法),那么它在4K和1080P上都能工作。但是对于我的例子,我只需要box_img变量。所以当我把它放进去。write(),它将停止工作。
我猜这与高度和宽度的形状有关。

biswetbf

biswetbf1#

我想明白了正如我怀疑的那样,这是VideoWriter的分辨率设置。
问题是VideoWriter被设置为以与输入视频相同的分辨率写入。问题是,由于视频是越来越缩小了线,这两个分辨率不匹配。
示例:输入视频-(3840 x 2160)4K VideoWriter的高度和宽度相同。
但随后来了调整大小部分,分辨率从3840 x 2160变成了1920 x 1080;但是视频写入器试图写入3840 × 2160的分辨率。
所以我做的是在开始添加这段代码:

if inp_width >= 3840 and inp_height >= 2160:
    out_width = int(inp_width * 0.5)
    out_height = int(inp_height * 0.5)
elif inp_width == 1920 and inp_height == 1080:
    out_width = int(inp_width)
    out_height = int(inp_height)

out = cv2.VideoWriter('./demo_output/demo_result.avi', fourcc, 30, (out_width, out_height))

它的作用是检查初始输入视频分辨率并将输出分辨率设置为正确的大小。问题解决了!

相关问题