-1

I am trying to create a gui using tkinter in which a folder gets created in the C: drive under subdirectory "raw" with a user-specified entry in the entry widget.on creation of folder i want to click images from live webcam sequence for which i use opencv. Problem: only a single image is getting captured! I want to capture 30 images of the same person and store in C:/raw/s, where s is an user-specified directory.here is the code.I'm not sure why the img_counter variable is not getting updated.Any inputs would be highly appreciated

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()
safruk
  • 23
  • 6
  • thank you!!.i am a newbie to python and opencv.i fixed the rest of my code.Now it does what i intended in the first place. Thanks again@CommonSense – safruk Mar 22 '17 at 10:47
  • glad to help! And look on your imports! You importing `tkinter` twice! You can get rid of `from tkinter import *` line. When you import with asterisk you import all stuff in current namespace, so you can declare/use constants without `tk.` prefix. Since you use `tk.` prefix there is no reason for second import at all! – CommonSense Mar 22 '17 at 11:01

1 Answers1

1

I'm not sure why the img_counter variable is not getting updated

First of all you need to read about mutable and immutable objects in Python and so far integers are immutable ones.

After that you declare the global img_counter and trying to pass it by reference to the function. So you got access to value but can't modifie it because you use global keyword incorrectly. With global keyword you can bind variable within a scope of desired function! Take a look at code below:

# 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()

With global keyword you can declare global variables inside a function (don't do that!)

# 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()

As you see in both cases there's no need to pass something to function! So in you code you can get rid of lambda function.

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

Afterwords: Best way to structure a tkinter application

Community
  • 1
  • 1
CommonSense
  • 4,232
  • 2
  • 14
  • 38