从网络摄像头捕获图像将它们显示在同一窗口上并存储在用户使用python tkinter和opencv指定的目录中

时间:2017-03-21 17:59:02

标签: python opencv tkinter

我正在尝试使用tkinter创建一个gui,其中一个文件夹在C:驱动器的子目录“raw”下创建,在条目widget中有一个用户指定的条目。创建文件夹我想点击来自live的图像我使用opencv的网络摄像头序列。问题:只捕获一张图片!我想捕获30个同一个人的图像并存储在C:/ raw / s中,其中s是用户指定的目录。这是代码。我不知道为什么img_counter变量没有得到更新。任何输入将受到高度赞赏

import tkinter as tk

import cv2
from tkinter import *
from PIL import Image, ImageTk
import os
import tkMessageBox
from multiprocessing import Process, Queue

width, height = 800, 600
cap = cv2.VideoCapture(0)
flag,frame=cap.read()

#cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
#cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
global img_counter

root = tk.Tk()
root.bind('<Escape>', lambda e: root.quit())
lmain = tk.Label(root)
lmain.pack()
tk.Label(text='Enter your name')

entry = tk.Entry(root, width=10)
entry.pack(side=tk.TOP,padx=10,pady=10)

#e = Entry(root,width=10)
#e.pack(side=TOP,padx=10,pady=10)

entry.delete(0, tk.END)
entry.insert(0, "username")

def onok():
    s = entry.get()
    mypath='C:\\raw\\'
    mypath=os.path.join(os.path.dirname(mypath), s)
    os.mkdir(mypath, 0777)
    tkMessageBox.showinfo(title=s,message="Your name is now entered.Start  taking images")
    entry.destroy()
#tk.Button(root,text='click',command=onclick).pack()
    img_counter = 0
    click_button = tk.Button(master=root, text='Click', command=lambda: saveImage(img_counter))
    click_button.pack()

def saveImage(img_counter):


    ret, frame = cap.read()
    cv2.imshow("test", frame)


    img_name = "opencv_frame_{}.png".format(img_counter)



    cv2.imwrite(img_name, frame)
    print("{} written!".format(img_name))
    img_counter += 1

tk.Button(root, text='OK', command=onok).pack(side=tk.LEFT)
#tk.Button(root, text='CLOSE').pack(side= tk.RIGHT)

def show_frame():
    _, 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)

show_frame()
root.mainloop()

1 个答案:

答案 0 :(得分:1)

  

我不确定为什么img_counter变量没有得到更新

首先,你需要阅读Python中的可变和不可变对象,到目前为止整数是immutable ones

之后,您声明全局img_counter并尝试pass it by reference到该函数。 因此,您可以访问值,但无法修改它,因为您错误地使用了global关键字。使用global关键字,您可以bind variable within a scope获得所需的功能!看看下面的代码:

# declare global
counter = int()

# let's try to counter
def try_to_counter():
    global counter
    counter += 1

# simple loop
def main_loop():
    for _ in range(5):
        try_to_counter()
        print(counter)

main_loop()

使用global关键字,您可以在函数内声明全局变量(不要这样做!)

# let's try to counter
def try_to_counter():
    global counter
    if 'counter' not in globals():
        counter = int()
    counter += 1

# simple loop
def main_loop():
    for _ in range(5):
        try_to_counter()
        print(counter)

main_loop()

正如你在两种情况下看到的那样,没有必要传递一些功能!所以在你的代码中你可以摆脱lambda函数。

...
img_counter = int()
...
click_button = tk.Button(master=root, text='Click', command=saveImage)
...
def saveImage():
    global img_counter
    ...
    img_counter += 1
...

后记: Best way to structure a tkinter application