2015-08-28 40 views
1

我正在使用Tkinter来制作一个GUI来显示USB摄像头的输出。这是一个显微镜实验的想法是,gui显示低分辨率的实时流,但点击一个按钮时会拍摄高分辨率图像。我已经能够使用我的笔记本电脑的内置摄像头(VideoCapture(0))工作,但是当我尝试在预期的摄像头(https://www.leopardimaging.com/uploads/LI-OV5640-USB-72_datasheet.pdf - VideoCapture(1))上使用代码时,它会崩溃。 的代码是这样的:第一次按下按钮,出现以下错误Python 2.7 CV2和Tkinter与摄像头

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Python27\lib\lib-tk\Tkinter.py", line 1486, in __call__ 
    return self.func(*args) 
    File "C:\Python27\lib\lib-tk\Tkinter.py", line 533, in callit 
    func(*args) 
    File "C:/Users/.../LI_USB_GUI_RR_worksWithInBuiltCam2.py", line 109, in show_frame 
    cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) 
error: ..\..\..\..\opencv\modules\imgproc\src\color.cpp:3648: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor 

,是为了被写入文件后

import Tkinter as tk 
import cv2 
import cv2.cv as cv 
import numpy as np 
from PIL import Image, ImageTk 

global counter 
counter = 0 
global save_dir 
save_dir = "C:/Users/etc..." 
global runner 
runner = 50 
global run_num 
run_num = "50" 
########################################################################## 
global hi_w, hi_h 
global lo_w, lo_h 
hi_w, hi_h = 640,480 # Camera intended resolution 2592,1944 
lo_w, lo_h = 320,240 # Camera intended resolution 640,480 
cap = cv2.VideoCapture(1) 
cap.set(3, lo_w) 
cap.set(4, lo_h) 
cap.set(5,15) 
########################################################################## 
# Define the Tkinter functions 

#-- QUIT_ --# 
#-----------# 
def quit_(root): 
    root.destroy()  
#--------------------- 
#-- FUNCTION1 --# 
#---------------# 
def function1(root): 
    global counter 
    counter = 1  
#--------------------- 
#-- FUNCTION2 --# 
#---------------# 
def function2(root): 
    global counter 
    counter = 2  
#--------------------- 
#-- FUNCTION3 --# 
#---------------# 
def function3(root): 
    global counter 
    counter = 3  
#--------------------- 
def capture(filename): 
    print 'capturing' 
    global hi_w, hi_h, lo_w, lo_h 
    cap.set(3, hi_w) 
    cap.set(4, hi_h) 
    flag2, frame2 = cap.read() 
    frame2 = cv2.flip(frame2, 1) 
    print 'writing' 
    cv2.imwrite(filename, frame2) 
    print 'resetting' 
    cap.set(3, lo_w) 
    cap.set(4, lo_h) 
    del flag2, frame2 
    global counter 
    counter = 0 

def show_frame(): 
    #Set up dummy frame 
    global counter, save_dir, runner, run_num 
    if counter == 1: 
     flag,frame = cap.read() 
     filename = save_dir + "z01_" + run_num + ".jpeg" 
     capture(filename) 
    elif counter == 2: 
     flag, frame = cap.read() 
     filename = save_dir + "z02_" + run_num + ".jpeg" 
     capture(filename) 
    elif counter == 3: 
     flag, frame = cap.read() 
     filename = save_dir + "z03_" + run_num + ".jpeg" 
     capture(filename) 
     runner = runner + 1 
     run_num = '{0:02d}'.format(runner) 
     counter = 0 
    else: 
      flag, frame = cap.read() 
      frame = cv2.flip(frame, 1) 

    cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) 
    img = Image.fromarray(cv2image) 
    imgtk = ImageTk.PhotoImage(image=img) 
    lmain.imgtk = imgtk 
    lmain.configure(image=imgtk) 
    lmain.after(10, show_frame) 


if __name__ == '__main__': 
    root = tk.Tk() 
    lmain = tk.Label(master=root) 
    lmain.grid(column=0, rowspan=4, padx=5, pady=5) 

    button1 = tk.Button(master=root, text='Function 1', command=lambda: function1(root)) 
    button1.grid(column=1, columnspan=2, row=0, padx=5, pady=5) 
    button2 = tk.Button(master=root, text='Function 2', command=lambda: function2(root)) 
    button2.grid(column=1, columnspan=2, row=1, padx=5, pady=5) 
    button3 = tk.Button(master=root, text='Function 3', command=lambda: function3(root)) 
    button3.grid(column=1, columnspan=2, row=2, padx=5, pady=5) 
    quit_button = tk.Button(master=root, text='Quit',bg="red3", fg="white", command=lambda: quit_(root)) 
    quit_button.grid(column=1, row=3, padx=5, pady=5) 

    show_frame() 
    root.mainloop() 
    cap.release() 

的程序崩溃是在大小零个字节。尽管相机仍然处于开启状态并且可以通过外壳进行控制,但应该在此处进行显示的框架已变空。我真的很困惑,为什么内置摄像头可以工作,但USB不会有相同的代码。

请帮忙...

+0

您的行'cv2image = cv2.cvtColor(frame,cv2.COLOR_BGR2RGBA)'中的对象'frame'是'None'。您可能需要检查cap.read()正在返回的值。或者如果'frame = cv2.flip(frame,1)'返回一个'None'对象。 –

+0

嗨,我不幸离开了我的办公桌几天,所以我不能做任何明确的检查,但作为记忆服务你是对的。 'cap.read()'当我尝试调整feed大小时返回None,但是fed仍然处于活动状态,当它崩溃时,我仍然可以控制shell中的相机。这很奇怪! – Chris

+0

我做了一点挖掘,发现此前[answer](http://stackoverflow.com/a/8046886/5066845)。它看起来像OpenCV有关于网络摄像头的问题。是否可以停用内置摄像头?我有一个不同的硬件设置,所以我不能再现这种行为。 –

回答

1

好吧,我想我已经解决了这个问题。 基本上,在更改分辨率之后,程序在准备就绪之前一直试图要求相机显示下一帧。因此它返回了一个None,程序崩溃了。我已经通过制作与预览图像大小相同的虚拟框架来解决此问题,并使用相机最后一个有效框架填充它。当节目录制高分辨率静止图像时,会显示最后一帧。此外,为了让程序有足够的时间来记录图像,我已经设置了一个while循环,以给摄像机设置一段时间来自己配置并记录图像。如果出现故障并且超时,我可以创建一种安全关闭程序的方式。新的代码如下,除了处理例外情况 - 安全关闭应用程序的样板文件可以放在那里。

import Tkinter as tk 
import cv2 
import cv2.cv as cv 
import numpy as np 
from PIL import Image, ImageTk 
import time 

global save_dir 
save_dir = "C:/Users/.../" 
global runner 
runner = 00 
global run_num 
run_num = "00" 

########################################################################## 
########################################################################## 
global hi_w, hi_h 
global lo_w, lo_h 
hi_w, hi_h = 2592,1944 
lo_w, lo_h = 640,480 
#Set up dummy frame 
global last_frame 
last_frame = np.zeros((lo_h, lo_w, 3), dtype=np.uint8) 
global cap 
cap = cv2.VideoCapture(1) 
cap.set(3, lo_w) 
cap.set(4, lo_h) 

########################################################################## 
########################################################################## 
# Define the Tkinter functions 

#-- QUIT_ --# 
#-----------# 
def quit_(root): 
    root.destroy() 

#--------------------- 


#-- FUNCTION1 --# 
#---------------# 
def function1(root): 
    global save_dir, run_num 
    filename = save_dir + "z01_" + run_num + ".jpeg" 
    capture(filename) 

#--------------------- 


#-- FUNCTION2 --# 
#---------------# 
def function2(root): 
    global save_dir, run_num 
    filename = save_dir + "z02_" + run_num + ".jpeg" 
    capture(filename) 

#--------------------- 


#-- FUNCTION3 --# 
#---------------# 
def function3(root): 
    global save_dir, runner, run_num 
    filename = save_dir + "z03_" + run_num + ".jpeg" 
    capture(filename) 
    runner = runner + 1 
    run_num = '{0:02d}'.format(runner) 

#--------------------- 

def capture(filename): 
    print 'capturing' 
    cap.set(3, hi_w) 
    cap.set(4, hi_h) 
    print time.time() 

    timeout = time.time() + 30 
    while time.time() < timeout: 
     flag2, frame2 = cap.read() 
     if flag2: 
      frame2 = cv2.flip(frame2,1) 
      cv2.imwrite(filename, frame2) 
      cap.set(3, lo_w) 
      cap.set(4, lo_h) 
      time.sleep(1) 
      global counter 
      counter = 0 
      break 
     else: 
      time.sleep(1) 
    else: 
     <code to handle timeout appropriately> 

#---------------------  

def show_frame(): 
    global counter, save_dir, runner, run_num 
    flag, frame = cap.read() 
    frame = cv2.flip(frame, 1) 
    if flag is None: 
     print "Major error!" 
     <code to handle exception> 
    elif flag: 
     global last_frame 
     last_frame = frame.copy() 
    else: 
     print "Cant process the image" 
     <code to handle exception> 

    cv2image = cv2.cvtColor(last_frame, cv2.COLOR_BGR2RGBA) 
    img = Image.fromarray(cv2image) 
    imgtk = ImageTk.PhotoImage(image=img) 
    lmain.imgtk = imgtk 
    lmain.configure(image=imgtk) 
    lmain.after(10, show_frame) 



########################################################################## 
########################################################################## 


if __name__ == '__main__': 
    root = tk.Tk() 
    lmain = tk.Label(master=root) 
    lmain.grid(column=0, rowspan=4, padx=5, pady=5) 

    button1 = tk.Button(master=root, text='Function 1', command=lambda: function1(root)) 
    button1.grid(column=1, columnspan=2, row=0, padx=5, pady=5) 
    button2 = tk.Button(master=root, text='Function 2', command=lambda: function2(root)) 
    button2.grid(column=1, columnspan=2, row=1, padx=5, pady=5) 
    button3 = tk.Button(master=root, text='Function 3', command=lambda: function3(root)) 
    button3.grid(column=1, columnspan=2, row=2, padx=5, pady=5) 
    quit_button = tk.Button(master=root, text='Quit',bg="red3", fg="white", command=lambda: quit_(root)) 
    quit_button.grid(column=1, row=3, padx=5, pady=5) 


    show_frame() 
    root.mainloop() 
    cap.release() 

谢谢大家谁帮助。