2015-08-28 63 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() 

謝謝大家誰幫助。