gpt4 book ai didi

python - OpenCV(Python中的cv2)VideoCapture在删除后不释放相机

转载 作者:太空狗 更新时间:2023-10-30 01:02:32 28 4
gpt4 key购买 nike

我对 Python 比较陌生,只是在过去一个月左右的时间里学习了它,并根据示例和我在网上找到的其他人的代码一起破解了它。

我有一个 Tkinter GUI 可以将来自网络摄像头的提要显示为 Canvas 上不断更新的图像循环。每隔一段时间退出 GUI 并重新运行脚本会导致此错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 495, in callit
func(*args)
File "C:\...\cv2_cam_v8.py", line 20, in update_video
(self.readsuccessful,self.f) = self.cam.read()
SystemError: NULL object passed to Py_BuildValue

当错误发生时,没有图像被读取,视频源也没有接收到图像来更新 Canvas 。该脚本第一次和第二次都正常运行,没有错误。从之前使用 cv2 模块中的 VideoCapture 函数进行的测试中,我发现我必须删除相机对象才能释放它,以便后续运行能够毫无问题地捕获相机流。通过在控制台中键入 who 检查 namespace 不显示 cam 所以我知道它在 GUI 关闭后被正确删除。我不明白为什么 cv2 的读取函数会出错。我认为它只会每隔两次发生一次,因为当错误发生时,一些垃圾收集或错误处理会删除或释放与相机有关的东西,但我不知道这是什么......

这是我的代码:

import cv2
import Tkinter as tk
from PIL import Image, ImageTk


class vid():
def __init__(self,cam,root,canvas):
self.cam = cam
self.root = root
self.canvas = canvas

def update_video(self):
(self.readsuccessful,self.f) = self.cam.read()
self.gray_im = cv2.cvtColor(self.f, cv2.COLOR_RGB2GRAY)
self.a = Image.fromarray(self.gray_im)
self.b = ImageTk.PhotoImage(image=self.a)
self.canvas.create_image(0,0,image=self.b,anchor=tk.NW)
self.root.update()
self.root.after(33,self.update_video)


if __name__ == '__main__':
root = tk.Tk()
videoframe = tk.LabelFrame(root,text='Captured video')
videoframe.grid(column=0,row=0,columnspan=1,rowspan=1,padx=5, pady=5, ipadx=5, ipady=5)
canvas = tk.Canvas(videoframe, width=640,height=480)
canvas.grid(column=0,row=0)
cam = cv2.VideoCapture(2)
x = vid(cam,root,canvas)
root.after(0,x.update_video)
button = tk.Button(text='Quit',master=videoframe,command=root.destroy)
button.grid(column=0,row=1)
root.mainloop()
del cam

像这样重构代码:

def update_video(cam,root,canvas):
(readsuccessful,f) = cam.read()
gray_im = cv2.cvtColor(f, cv2.COLOR_RGB2GRAY)
a = Image.fromarray(gray_im)
b = ImageTk.PhotoImage(image=a)
canvas.create_image(0,0,image=b,anchor=tk.NW)
root.update()
root.after(33,update_video(cam,root,canvas))

if __name__ == '__main__':
root = tk.Tk()
videoframe = tk.LabelFrame(root,text='Captured video')
videoframe.grid(column=0,row=0,columnspan=1,rowspan=1,padx=5, pady=5, ipadx=5, ipady=5)
canvas = tk.Canvas(videoframe, width=640,height=480)
canvas.grid(column=0,row=0)
cam = cv2.VideoCapture(2)
root.after(0,update_video(cam,root,canvas))
button = tk.Button(text='Quit',master=videoframe,command=root.destroy)
button.grid(column=0,row=1)
root.mainloop()
del cam

不在 GUI 中显示按钮并在关闭窗口后出现此错误:

RuntimeError: Too early to create image

我有3个问题

1 - 我怎样才能防止任何一个异常? 更新:将“root.after(0,update_video(cam,root,canvas))”更改为“root.after(0,lambda: update_video(cam,root,canvas))”和“update_video(cam,root,canvas)” "到 "update_video(cam,root,canvas,event=None)"或使用以下格式将参数传递给回调:"root.after(time_to_wait, callback, arguments, master)"修复了第二个错误(以及我做的其他错误)不发帖)。同样正如 kobejohn 指出的那样,添加一个 try: except block 也修复了第二个错误。有关详细信息,请参阅他的回答。

2 - cv2 中有没有比 .read() 更快、更高效的函数?编辑:有没有办法重构我的代码以获得更高的帧率?读取函数是文档中唯一列出的函数,我只是在某处读到如果它不在文档中,那么它不可用。这种方法只给我大约 5fps,其中 10-20fps 会更可接受。 更新:从 kobejohn 的测试和我用不同相机进行的测试之间的差异来看,低帧率是网络摄像头质量差的结果。质量更好的网络摄像头会产生更高的帧速率。

3 - 我一直在读到应该尽可能避免使用 update(),但是如何让 Canvas 重新绘制图像(或者使用此代码实现 update_idletasks())?我必须实现某种线程还是可以避免? 更新:我已经让代码在不使用 update() 方法的情况下工作,但无论如何都必须考虑实现线程,因为当我从主 GUI 的按钮开始录制视频源时,它会卡住/变得无响应。

完成的程序将在 Ubuntu 和 Windows 中使用(也可能在 Mac 上)。我正在运行 Windows 7,IDE 是 Spyder 2.1.11 (Python 2.7.3)。

提前致谢,如有任何建议和/或解决方案,我们将不胜感激!

问候,

S。奇亚籽

最佳答案

解决了! Python 中的 OpenCV 2.4.2/cv2

由于某些奇怪的原因,我之前找不到'release'方法和其他论坛,页面特别提到opencv的python绑定(bind)不包括release方法。也许这只适用于使用“导入简历”时。我使用后者进行了初始原型(prototype)设计,但由于某种原因,当我在寻找 ReleaseCapture 方法时错过了 cv2 中的“release”方法。

刚刚在文档中找到它:http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html

import cv2

cam=cv2.VideoCapture(0)
cam.release

关于python - OpenCV(Python中的cv2)VideoCapture在删除后不释放相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15460706/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com