6
votes

I am working with OpenCV and Python Tkinter. I want to get Video frame of OpenCV to Tkinter lable. I have used Threading, because of I have two loop. (I got instruction from this)

When I trying to run the code It shows me,

Press any key to continue . . . Exception in thread Thread-2:Traceback (mostrecent call last):File "C:\Python27\lib\threading.py", line 808, in __bootstrap_inner self.run() File "C:\Python27\lib\threading.py", line 761, in run self.__target(*self.__args, **self.__kwargs)File "c:\users\user1\documents\visual studio 2013\Projects\defTstWindow\defT stWindow\defTstWindow.py", line 26, in makeGUI img = Image.fromarray(cv2image) AttributeError: class Image has no attribute 'fromarray'

I alredy try with Python classes.I got same error.

But, If I run all in one function(like 1st answer of this ),Its working properly.

What is the problem of my code?

Now I have four python modules.

1.Support.py

import cv2

global frame
frame=None

2.CamHandler.py

import cv2
import numpy as np
import Support

cam=cv2.VideoCapture(0)


def getFrame():
    while 1:
     _,frm=cam.read()

     #cv2.imshow('frm',frm)
     Support.frame=frm

     if cv2.waitKey(1) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

3.defTstWindow.py

import sys
import cv2
import Image, ImageTk

from Tkinter import *
import Support

def makeGUI():

    top=Tk()

    top.geometry("600x449+650+151")
    top.title("Test Window")
    top.configure(background="#d9d9d9")

    lblFrame = Label(top)
    lblFrame.place(relx=0.03, rely=0.04, height=411, width=544)
    lblFrame.configure(background="#d9d9d9")
    lblFrame.configure(disabledforeground="#a3a3a3")
    lblFrame.configure(foreground="#000000")
    lblFrame.configure(text='''Label''')
    lblFrame.configure(width=544)

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

    top.mainloop()

4.main.py

    import CamHandler
    import defTstWindow

    import threading
    import time


    threading.Thread(target=CamHandler.getFrame).start()
    time.sleep(1)
    threading.Thread(target=defTstWindow.makeGUI).start()
2

2 Answers

8
votes

The Tkinter namespace includes the class Image, so when you wrote

from Tkinter import *

you replaced the definition of Image with the one from Tkinter.

import * can be convenient, especially when working in an interactive shell, but it is not recommended for scripts and bigger programs, for exactly the reason demonstrated in this question. Change that import to

from Tkinter import Tk, Label

(Add any other names that you need to that import statement.)

6
votes

Better and simple way is change

import Image, ImageTk

to

from PIL import Image as Img
from PIL import ImageTk

and

img = Image.fromarray(cv2image)

to

img = Img.fromarray(cv2image)