在 Tkinter 主循环期间录制 OpenCV 视频

2024-01-15

我正在开发一项心理学实验,分析用户在完成行为任务时所做的面部表情。该应用程序主要通过 Tkinter 运行,我使用 openCV 来捕获视频。

在最小的情况下,我需要根据用户响应开始和停止录制。例如,在下面的代码中,我希望用户使用鼠标按下按钮来指定何时开始和停止录制视频。

import Tkinter as tk
import cv2

# -------begin capturing and saving video
def startrecording():
    cap = cv2.VideoCapture(0)
    fourcc = cv2.cv.CV_FOURCC(*'XVID')
    out = cv2.VideoWriter('output.avi',fourcc,  20.0, (640,480))

    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret==True:
            out.write(frame)
        else:
            break

# -------end video capture and stop tk
def stoprecording():
    cap.release()
    out.release()
    cv2.destroyAllWindows()

    root.quit()
    root.destroy()

# -------configure window
root = tk.Tk()
root.geometry("%dx%d+0+0" % (100, 100))
startbutton=tk.Button(root,width=10,height=1,text='START',command = startrecording)
stopbutton=tk.Button(root,width=10,height=1,text='STOP', command = stoprecording)
startbutton.pack()
stopbutton.pack()

# -------begin
root.mainloop()

问题在于 OpenCV 使用循环来录制视频,在此期间 Tkinter 无法监听用户响应。程序陷入 OpenCV 循环,用户无法继续。如何同时录制视频并聆听用户响应?

我研究过并行处理(例如,使用多处理在 tkinter 中显示 OpenCV 视频 https://stackoverflow.com/questions/17073227/),但这听起来像是一个比看起来必要的更大的努力。

我还研究过使用 root.after 命令(例如,显示网络摄像头序列 TkInter https://stackoverflow.com/questions/16366857/),但使用此功能似乎只能捕获单个帧,而我想要一个视频。

还有别的办法吗?我需要使用两个处理流吗?


通过处理这个multiprocessing比你想象的更容易:

import multiprocessing
import Tkinter as tk
import cv2

e = multiprocessing.Event()
p = None

# -------begin capturing and saving video
def startrecording(e):
    cap = cv2.VideoCapture(0)
    fourcc = cv2.cv.CV_FOURCC(*'XVID')
    out = cv2.VideoWriter('output.avi',fourcc,  20.0, (640,480))

    while(cap.isOpened()):
        if e.is_set():
            cap.release()
            out.release()
            cv2.destroyAllWindows()
            e.clear()
        ret, frame = cap.read()
        if ret==True:
            out.write(frame)
        else:
            break

def start_recording_proc():
    global p
    p = multiprocessing.Process(target=startrecording, args=(e,))
    p.start()

# -------end video capture and stop tk
def stoprecording():
    e.set()
    p.join()

    root.quit()
    root.destroy()

if __name__ == "__main__":
    # -------configure window
    root = tk.Tk()
    root.geometry("%dx%d+0+0" % (100, 100))
    startbutton=tk.Button(root,width=10,height=1,text='START',command=start_recording_proc)
    stopbutton=tk.Button(root,width=10,height=1,text='STOP', command=stoprecording)
    startbutton.pack()
    stopbutton.pack()

    # -------begin
    root.mainloop()

我们所做的就是添加一个调用multiprocessing.Process https://docs.python.org/2/library/multiprocessing.html#the-process-class以便您的视频捕获代码在子进程中运行,并在捕获完成时将代码移动到该进程中进行清理。与单进程版本相比,唯一的额外问题是使用multiprocessing.Event https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Event当需要关闭时向子进程发出信号,这是必要的,因为父进程无权访问out or cap.

你可以尝试使用threading相反(只需替换multiprocessing.Process with threading.Thread, and multiprocessing.Event with threading.Event),但我怀疑 GIL 会绊倒你并损害 GUI 线程的性能。出于同样的原因,我认为不值得尝试通过以下方式将读/写流集成到事件循环中root.after- 它只会损害性能,并且由于您不尝试将所做的事情集成到 GUI 本身中,因此没有理由尝试将其保留在与事件循环相同的线程/进程中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Tkinter 主循环期间录制 OpenCV 视频 的相关文章

随机推荐

  • Visual Studio 2013 C++ lambda 捕获参数包

    目前 Visual Studio 2013 update 2 不支持完整的 C 11 其中一项功能是捕获 lambda 中的参数包 有没有一种简单的方法可以解决这个问题 或者我是否必须放弃 Visual Studio 并使用兼容的编译器 例
  • IE7:如何让TD浮动?

    我想要一套 td s 在 IE7 中向左浮动 如果窗口太小 它们应该中断到下一行 CSS table width 100 td border 1px solid red tr f td width 500px float left HTML
  • 托管 Angular 2 应用程序

    我是新来的Angular 2 我认识楼主Angular 1 x在共享主机上 例如GoDaddy 但我不知道如何发布Angular 2应用程序 例如我有这个结构文件夹 angular2 quickstart app app component
  • 如何使用所有模型的通用 Trait 在 Laravel 中实现 eloquent 事件

    我在用拉拉维尔 5 4创建一个网络应用程序 我创建了一个特征来实现创建 更新 删除和恢复雄辩事件的事件 我创建了一个trait如下
  • 如何使用 AngularJS 更改一个 div 上的类,同时将鼠标悬停在另一个 div 上?

    我想使用 AngularJS 指令更改一个 div 的类 同时将鼠标悬停在另一个 div 上 这是我到目前为止所拥有的http jsfiddle net E8nM5 38 http jsfiddle net E8nM5 38 HMTL di
  • 当indexedDB被阻止时应用程序应该如何反应

    我在另一个地方被告知question https stackoverflow com questions 39997018关于检测阻止和解除阻止事件 阻止的打开 或删除 不会被取消 只是 被阻止 一旦解除阻止 打开 或删除 将继续 我想知道
  • Wcf 基本身份验证

    通过简单的测试 Wcf 服务使用基本身份验证时遇到一些问题 我遇到了一个例外 无法激活请求的服务 http qld tgower test Service svc 有关详细信息 请参阅 gt 服务器的诊断跟踪日志 在跟踪日志中它显示 在主机
  • WPF DataGrid实际ColumnHeaderHeight

    当我将 WPF DataGrid 的 ColumnHeaderHeight 设置为 Auto double NaN 时 如何获取列标题的实际呈现高度 我似乎无法在 DataGrid 类中找到该属性 您可以通过在视觉树中搜索来获取它DataG
  • 按照教程 AWS Elastic Beanstalk 的 Flask 教程时出现错误“Your requests.txt is invalid”

    我正在关注 AWS Elastic Beanstalk 的烧瓶教程 http docs aws amazon com elasticbeanstalk latest dg create deploy python flask html部署示
  • 用于确定测试成绩通过/失败的 MIPS 程序

    我正在编写一个 MiPS 程序 该程序将检查 15 个测试分数的列表 它将从终端输入 通过标准是 50 分 终端的输出将包括每个类别的分数以及通过和失败的学生人数 我应该使用输入提示和输出语句 请我需要一些帮助 只需要一些建议如何去做 ma
  • 禁用 GridView 列调整大小

    有什么方法可以在 WPF 中禁用 GridViewColumn 调整大小吗 我不想设置控件的样式 请参阅此链接 ListView 中的固定宽度列 无法调整大小的列 http blogs msdn com b atc avalon team
  • Spark 如何向工作线程发送闭包?

    当我编写 RDD 转换时 例如 val rdd sc parallelise 1 to 1000 rdd map x gt x 3 据我了解 关闭 x gt x 3 这只是一个 Function1 需要可序列化 并且我想我在某处读过编辑 它
  • 有没有办法在 CSS 中查询具有多个类的元素?

    如何查询同时具有两个类的元素 例如 div span class major minor Test span div 我想对同时具有 主要 和 次要 类的所有跨度进行样式设置 以下应该可以解决问题 span major minor colo
  • 添加黑条以创建 16x9 图像

    我的服务器上有一张jpg 我用 imagecreatefromjpeg imgPath 打开它 我想通过在顶部 底部或左侧 右侧添加黑条来使其成为 16x9 图像 思考background size contain background p
  • 使用 pandoc 从 Markdown 转换为 PDF 时设置双倍间距和行号

    我正在使用 markdown 和 pandoc 进行科学写作 我知道我可以使用以下命令更改最终 pdf 的边距 使用 pandoc 从 Markdown 转换为 PDF 时设置边距大小 https stackoverflow com que
  • Jackson @ResponseBody 上的内部服务器错误

    我只想将我的用户对象作为 JSON 返回 以供客户端的 ajax 调用使用 这在某一时刻是有效的 经过一些更新 即 将应用程序更改为部署到 在 Jetty 中 后 现在就不行了 我没有从代码中抛出异常 它返回得很好 但在尝试将对象转换为 J
  • 如何使用 Rxjs 实现队列?

    有了 Promise 就可以很容易地实现一个队列来防止多个 HTTP 请求并行运行 class Runner private promise constructor http this promise q resolve getUrl re
  • QtCreator 中使用 Clang 支持 C++14

    如何使用 Clang 3 5 在 QtCreator 3 3 中启用 C 14 支持 我添加了一个 Clang 套件并且添加了CONFIG c 14在我的项目文件中 然而 当使用例如返回类型推导 https stackoverflow co
  • 如何将多个函数应用于 groupby 对象

    例如 我有两个 lambda 函数可应用于分组数据框 df groupby A B apply lambda g df groupby A B apply lambda g 两者都可以工作 但组合起来就不行了 df groupby A B
  • 在 Tkinter 主循环期间录制 OpenCV 视频

    我正在开发一项心理学实验 分析用户在完成行为任务时所做的面部表情 该应用程序主要通过 Tkinter 运行 我使用 openCV 来捕获视频 在最小的情况下 我需要根据用户响应开始和停止录制 例如 在下面的代码中 我希望用户使用鼠标按下按钮