【问题标题】:Camera starts too late in Python application: what is the reason?相机在Python应用程序中启动太晚:原因是什么?
【发布时间】:2021-06-02 21:34:50
【问题描述】:

你能帮我解决这个问题吗?我创建了一个 Python 应用程序,它使用 opencv 记录/处理视频文件。它适用于我以前的所有相机。

最近我们购买了 3 款罗技网络摄像头:质量非常好,FPS 可控,您可以手动更改亮度、色彩、距离等,实际上是所有测试中最好的摄像头。但是,它需要的时间太长(在我的应用程序中启动 Logitech 相机大约需要 2-2.5 分钟)。

所有其他相机,包括我的笔记本电脑相机,都会立即启动或在几秒钟后启动。这种迟到的原因是什么?我使用以下链接中建议的代码进行 AV 录制:How to capture a video (AND audio) in python, from a camera (or webcam)

【问题讨论】:

  • 你什么时候尝试this simple example从你的相机流式传输,最近这也打开了你的相机吗?共享相机模型也很有帮助

标签: python opencv cv2 video-recording


【解决方案1】:

我使用了该代码并遇到了同样的问题。开始录制的延迟不一致,有时线程会在录制后挂起并使我的程序崩溃。我想出了一个更简单的解决方案,对我来说效果很好。最后,我还获得了质量更高的视频。使用 ffmpeg 重新编码 openCV 视频总是会在我的视频中产生一些奇怪的失真。

该解决方案目前仅适用于 Windows,因为它使用 pywinauto 和内置的 Windows 相机应用程序。脚本的最后一点通过检查视频名称的时间戳来进行一些错误检查以确认视频成功录制。

https://gist.github.com/mjdargen/956cc968864f38bfc4e20c9798c7d670

import pywinauto
import time
import subprocess
import os
import datetime

def win_record(duration):
    subprocess.run('start microsoft.windows.camera:', shell=True)  # open camera app

    # focus window by getting handle using title and class name
    # subprocess call opens camera and gets focus, but this provides alternate way
    # t, c = 'Camera', 'ApplicationFrameWindow'
    # handle = pywinauto.findwindows.find_windows(title=t, class_name=c)[0]
    # # get app and window
    # app = pywinauto.application.Application().connect(handle=handle)
    # window = app.window(handle=handle)
    # window.set_focus()  # set focus
    time.sleep(2)  # have to sleep

    # take control of camera window to take video
    desktop = pywinauto.Desktop(backend="uia")
    cam = desktop['Camera']
    # cam.print_control_identifiers()
    # make sure in video mode
    if cam.child_window(title="Switch to Video mode", auto_id="CaptureButton_1", control_type="Button").exists():
        cam.child_window(title="Switch to Video mode", auto_id="CaptureButton_1", control_type="Button").click()
    time.sleep(1)
    # start then stop video
    cam.child_window(title="Take Video", auto_id="CaptureButton_1", control_type="Button").click()
    time.sleep(duration+2)
    cam.child_window(title="Stop taking Video", auto_id="CaptureButton_1", control_type="Button").click()

    # retrieve vids from camera roll and sort
    dir = 'C:/Users/michael.dargenio/Pictures/Camera Roll'
    all_contents = list(os.listdir(dir))
    vids = [f for f in all_contents if "_Pro.mp4" in f]
    vids.sort()
    vid = vids[-1]
    # compute time difference
    vid_time = vid.replace('WIN_', '').replace('_Pro.mp4', '')
    vid_time = datetime.datetime.strptime(vid_time, '%Y%m%d_%H_%M_%S')
    now = datetime.datetime.now()
    diff = now - vid_time
    # time different greater than 2 minutes, assume something wrong & quit
    if diff.seconds > 120:
        quit()
    
    subprocess.run('Taskkill /IM WindowsCamera.exe /F', shell=True)  # close camera app
    print('Recorded successfully!')


win_record(2)

【讨论】:

  • 您可以在OpenCV上更改后端而不使用其他库
  • 谢谢你,mjdargen,你的回答。尝试将您的代码用作 ffmpeg 确实会导致问题 - 停止录制时应用程序偶尔会崩溃,这可能是由于 cpu 使用过多。但是,得到属性错误。 AttributeError:模块“pywinauto”没有属性“桌面”。无法解决。有什么办法吗?
  • @RuzannaOrdyan 如果 pywinauto 中的桌面不适合您,您可以打开相机应用程序,使用应用程序设置焦点(代码的注释部分),然后发送击键('SPACE')控制相机。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 2021-12-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
相关资源
最近更新 更多