python卸载opencv_OpenCV(Python中的cv2)VideoCapture删除后不释放相机

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

我已经获得了一个Tkinter GUI来显示来自网络摄像头的馈送,作为画布上不断更新的图像的循环.退出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

发生错误时,不会读取任何图像,并且视频片段不会收到任何图像来更新画布.脚本正常运行,第一次和第二次没有错误.从之前使用cv2模块中的VideoCapture函数进行的测试,我发现我必须删除相机对象以释放它,以便后续运行能够捕获相机流而没有任何问题.通过在控制台中键入谁不显示凸轮来检查命名空间,因此我知道在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)” “to”update_video(cam,root,canvas,event = None)“或者使用以下格式将参数传递给回调:”root.after(time_to_wait,callback,arguments,master)“修复了第二个错误(以及我做过的其他错误)不发布).另外正如kobejohn指出的那样,添加一个try:except块也可以修复第二个错误.有关详细信息,请参阅他的回答.

2 – 在cv2中有比.read()更快,更有效的功能吗?编辑:有没有办法重构我的代码以获得更高的帧速率? read函数是文档中列出的唯一函数,我只是在某处阅读,如果它不在文档中,那么它就不可用了.这个方法只给我大约5fps,其中10-20fps会更容易接受.

更新:根据kobejohn的测试与我的不同相机之间的差异,低帧率是低质量网络摄像头的结果.质量更好的网络摄像头可提高帧率.

3 – 我一直在阅读应尽可能避免更新()但是如何让画布重绘图像(或者使用此代码实现update_idletasks())?我是否必须实施某种线程,还是可以避免这种情况?

更新:我已经让代码在不使用update()方法的情况下工作,但是无论如何都必须考虑实现线程,因为当我开始从主GUI的按钮开始录制视频片时,它会冻结/变得无法响应.

完成的程序将用于Ubuntu和windows(也可能在mac上).我正在运行Windows 7,IDE是Spyder 2.1.11(Python 2.7.3).

提前感谢您,任何建议和/或解决方案将不胜感激!

问候,

S. Chia

解决方法:

解决了! python中的OpenCV 2.4.2 / cv2

出于一些奇怪的原因,我在之前找不到’release’方法和其他论坛,页面特别提到了对opencv的python绑定没有包含release方法.也许这只适用于使用’import cv’时.我使用后者进行了初始原型设计,出于某些原因,在寻找ReleaseCapture方法时错过了cv2中的’release’方法.

import cv2

cam=cv2.VideoCapture(0)

cam.release

标签:python,opencv,tkinter,video-capture

来源: https://codeday.me/bug/20190517/1122867.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值