【问题标题】:OpenCV Not Properly Writing Adding Frames to VideoOpenCV 没有正确编写向视频添加帧
【发布时间】:2023-01-25 23:03:26
【问题描述】:

我正在使用 mss、numpy 和 OpenCV 制作自己的录制软件,但是当我录制时,我所有的视频最终都是 258 字节的文件大小(无论视频长度如何),而且我无法查看视频。我的视频中似乎没有帧​​。我究竟做错了什么?

这是我的代码,任何帮助将不胜感激:

import datetime
import numpy as np
import cv2
import mss
import mss.tools


time_stamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
fourcc = cv2.VideoWriter_fourcc("m", "p", "4", "v")
captured_video = cv2.VideoWriter(f"{time_stamp}.mp4", fourcc, 20.0, (1080, 720))

with mss.mss() as sct:
    monitor = {"top": 0, "left": 0, "width": 1080, "height": 720}
    while True:
        img = np.array(sct.grab(monitor))
        img_final0 = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
        img_final = cv2.cvtColor(img_final0, cv2.COLOR_BGR2RGB)
        cv2.imshow('LevelRecorder', img_final)
        capture = captured_video.write(img_final)
        print(capture)
        if cv2.waitKey(10) == ord("q"):
            break

【问题讨论】:

    标签: python numpy opencv screen-capture mss


    【解决方案1】:

    “258 字节”文件大小是有用的信息。由于您的文件很小,VideoWriter 实际上甚至不写入任何视频数据。

    • 制作当然write() 的帧大小为 1080 x 720 和 3 通道(形状 (720, 1080, 3)),正如您在 VideoWriter 对象的构造函数(参数 (1080, 720))中宣布的那样。
    • 您错过了captured_video.release() 电话。如果 MP4 文件没有正确定稿,它们将被损坏,即使视频数据确实进入了文件。
    • 那些cvtColor操作毫无意义。您只需在不需要时来回转换即可。
    • 查看print(cv.getBuildInformation()) 中的视频 I/O 部分并确认您有 ffmpeg 支持。否则,mp4v视频和.mp4容器将不可用。

    如有疑问,请使用MJPGfourcc 和.avi容器。这两个内置于 OpenCV 中,始终可用。

    【讨论】:

    • 嗯...我尝试了你的第一点,出于某种原因,我的帧是 2160x1440 并且有 4 个通道,这根本不是我指定的
    • 我听说有些屏幕捕获库只为您提供整个屏幕。我也很惊讶你可以告诉它一个区域并且它只是忽略它。 docs 建议这应该有效。检查你的mss的版本。
    • 它实际上似乎并没有忽略我输入的值。现在我将 2160x1440 放在监视器行中,img.shape 的输出声称帧是 4320x2880。它将我的价值观扩大 2 倍?另外我的mss版本是6.1.0,是最新的版本
    • 我发现发生的事情真的很奇怪,我已经按照我能找到的每一个 API 文档或教程或帖子进行操作,但结果由于某些莫名其妙的原因而失败。
    • 你是在 Mac 上还是什么? DPI 缩放通常是一个问题,无处不在。编写库的人在平庸的机器上运行,因为没有人付钱让他们拥有最新最好的 :P 向 github.com/BoboTiG/python-mss/issues 提交错误,但不要期望太多。回购的最后一次提交是 6 个月前
    【解决方案2】:

    最后,我终于找到了我的答案。事实证明,这个问题有一个超级简单的解决方案,但我一直都错过了。

    事实证明,无论是 NumPy 还是 Open Cv(我不知道两者中的哪一个),真的真的讨厌 mss,但真的很喜欢 Python Pillow,所以,您所要做的就是将它转换为像 Python Pillow 这样的图像,然后就可以了!这是我的新代码(对我有用)

    import datetime
    from PIL import Image
    import numpy as np
    import cv2
    from mss import mss
    
    
    time_stamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
    fourcc = cv2.VideoWriter_fourcc("m", "p", "4", "v")
    captured_video = cv2.VideoWriter(f"{time_stamp}.mp4", fourcc, 20.0, (2880, 1800), 3)
    sct = mss()
    
    while True:
        img0 = sct.grab(sct.monitors[1])
        img_PIL = Image.frombytes('RGB', img0.size, img0.bgra, 'raw', 'BGRX') #This is where we convert it to a Pillow-like image
        img1= np.array(img_PIL) #Sorry about my variables, I was too lazy to change them :P
        img = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
        cv2.imshow('LevelRecorder', img)
        captured_video.write(img)
        if cv2.waitKey(1) == ord("q"):
            cv2.destroyAllWindows()
            break
    

    就是这样!只需使用 Python Pillow 将每一帧转换为 NumPy 和 Open Cv,就像使用 Image.frombytes() 一样。非常感谢 Christoph Rackwitz 的帮助,我无法用言语表达你提供的帮助有多大 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 2017-01-11
      • 1970-01-01
      相关资源
      最近更新 更多