python 3.x tkinter, integrating frames from opencv cv2 into tkinter window - python

I have a question, how do I integrate tkinter with cv2, I mean I can create a tkinter window filled with objects and I can open my laptop camera in a frame, but I want to integrate this "frame" from openCV cv2 into the tkinter window, next to the other objects, How do I do that?
I am using, Python 3.4, OpenCV, Numpy, Scipy, Windows 8
here is my code
import time, serial, sys, os, cv2
import tkinter as tk
from tkinter import *
from cv2 import *
from scipy import *
from numpy import array
from tkinter import ttk
try:
import Tkinter
import ttk
except ImportError:
import tkinter as Tkinter
import tkinter.ttk as ttk
mGui = Tk()
mGui.geometry('120x67+0+0')
mGui.configure(background="Sky Blue")
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
cv2.imshow("Camera's View", frame)
mGui.mainloop()
thanks

I understand now, if you too pull me up
I have to
create a frame
create a label inside of the frame
take the camera's view and convert it into an image
read the image and assigned to a variable
create a new property for the label (image)
assign the red image to the property
configure the label to display the image
so clear now, so obvious
here is the code (include previous libraries)
from PIL import Image, ImageTk (add library)
mGui = Tk()
mGui.geometry('600x600+0+0')
mGui.configure(background="Sky Blue")
fframe = Frame(mGui, width=500, height=500)
fframe.place(x=50, y=50)
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
v1 = Label(fframe, text="fchgvjvjhb")
v1.place(x=0, y=10)
v2 = Label(fframe, text="ajajajaja")
v2.place(x=300, y=10)
def dddd():
ret, frame = cap.read()
img = Image.fromarray(frame)
nimg = ImageTk.PhotoImage(image=img)
v1.n_img = nimg
v1.configure(image=nimg)
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
gimg = Image.fromarray(gray)
gnimg = ImageTk.PhotoImage(image=gimg)
v2.ng_img = gnimg
v2.configure(image=gnimg)
mGui.after(10, dddd)
dddd()
mGui.mainloop()

Related

how to add webcam window inside tkinter UI

i need to to add webcam window inside tkinter UI , what i actually need when the user pressed on start the webcam must appear in white box as it shown in the picture and the code down below also ive made a class that opens the webacam window and recognize faces
canvans=tkinter.Canvas(pro, width =900, height = 700, borderwidth=10, relief="solid",bg="#ffffff",
highlightbackground="#0E6655")
canvans.place(x=300,y=100)
pro.mainloop()
x=Gui()
In comments you get link to example but I made some changes
check if read() gives any frame
use cap.release() after using webcam
(PEP8) import * is not preferred
(PEP8) organize code - put all functions after import
import tkinter as tk # PEP8: `import *` is not preferred
from PIL import Image, ImageTk
import cv2
# --- functions --- # PEP8: all functions after imports
def show_frame():
# get frame
ret, frame = cap.read()
if ret:
# cv2 uses `BGR` but `GUI` needs `RGB`
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# convert to PIL image
img = Image.fromarray(frame)
# convert to Tkinter image
photo = ImageTk.PhotoImage(image=img)
# solution for bug in `PhotoImage`
label.photo = photo
# replace image in label
label.configure(image=photo)
# run again after 20ms (0.02s)
root.after(20, show_frame)
# --- main ---
cap = cv2.VideoCapture(0)
root = tk.Tk()
# create a Label to display frames
label = tk.Label(root)
label.pack(fill='both', expand=True) # to resize label when resize window
# start function which shows frame
show_frame()
root.mainloop()
cap.release()
BTW:
PEP 8 -- Style Guide for Python Code
Tkinter: Why Label doesn't display image? Bug with Garbage Collector in PhotoImage.
EDIT:
The same for Canvas
It uses image's ID to replace PhotoImage on Canvas
import tkinter as tk # PEP8: `import *` is not preferred
from PIL import Image, ImageTk
import cv2
# --- functions ---
def show_frame():
global image_id # inform function to assign new value to global variable instead of local variable
# get frame
ret, frame = cap.read()
if ret:
# cv2 uses `BGR` but `GUI` needs `RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# convert to PIL image
img = Image.fromarray(frame)
# convert to Tkinter image
photo = ImageTk.PhotoImage(image=img)
# solution for bug in `PhotoImage`
canvas.photo = photo
# check if image already exists
if image_id:
# replace image in PhotoImage on canvas
canvas.itemconfig(image_id, image=photo)
else:
# create first image on canvas and keep its ID
image_id = canvas.create_image((0,0), image=photo, anchor='nw')
# resize canvas
canvas.configure(width=photo.width(), height=photo.height())
# run again after 20ms (0.02s)
root.after(20, show_frame)
# --- main ---
image_id = None # default value at start (to create global variable)
cap = cv2.VideoCapture(0)
root = tk.Tk()
# create a Label to display frames
canvas = tk.Canvas(root)
canvas.pack(fill='both', expand=True)
# start function which shows frame
show_frame()
root.mainloop()
cap.release()

How to set the speed of a gif in Python

i am using Python and I inserted a gif in my project. The issue is when i start the application the gif in the application runs in different way than orginal gif. I think that the frames in the gif are run in different speed. How to set the original gif?
I imported PIL and tkinter. This is the code:
import threading
from tkinter import *
from PIL import Image, ImageTk, ImageSequence
def play_gif():
global img
img = Image.open("Gifs/beaming_face_with_smiling_eyes.gif")
lbl = Label(root)
lbl.place(x = 0, y = 0)
for img in ImageSequence.Iterator(img):
img = ImageTk.PhotoImage(img)
lbl.config(image = img)
root.update()
def exit():
root.destroy()
threading.Timer(3.0, play_gif).start()
Button(root,text = "exit", command=exit).place(x = 450, y = 300)
root.mainloop()

How to display the video in tkinter canvas frame by frame?

I am dealing with tkinter and opencv to display frames of video in tkinter canvas. my code is as following :
import tkinter as tk
from PIL import ImageTk as itk
from PIL import Image
from tkinter import filedialog as fd
import cv2
window = tk.Tk()
class window_tk():
def __init__(self,main):
self.canvas = tk.Canvas(main, bg='white' )
self.img = itk.PhotoImage(file=self.init_img_route)
self.bg= self.canvas.create_image(0,0,anchor = tk.NW,image=self.img)
self.vid = None
def load_video(self):
self.foldername = fd.askopenfilename(parent=window,initialdir="C:/",title='Select a video file to load.',filetypes=[('video files','*.wmv *.mp4 *.mov *.avi')])
self.label_foldername.config(text='Video Load : '+self.foldername)
self.current_pic_num=0
try:
self.vid = cv2.VideoCapture(self.foldername)
frame_number =0
print(self.vid,self.vid.isOpened())
self.frame_count = 0
if self.vid.isOpened():
vid_w = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
vid_h = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
vid_f = self.vid.get(cv2.CAP_PROP_FPS)
ret,frame = self.vid.read()
#cv2.imshow('frame',frame)
frame_convert = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
#print(self.frame_count, vid_w,vid_h,vid_f,frame.shape)
imgg = itk.PhotoImage(Image.fromarray(frame_convert))
self.canvas.itemconfig(self.bg, image = imgg)
self.canvas.pack(fill='both',expand=1)
# frame_number+=1
except IndexError:
pass
I confirmed that frame has successfully loaded by checking it as cv2.imshow(), but The canvas only shows the white empty image. Is there anything I missed ?
I found answer and leave the solution for my study.
I changed imgg to self.img and let it globally used in class.
I don't know why it solved the problem so if anyone can explain the reason thank you very much.

How to display an image from OpenCV in a Tkinter interface?

I am trying to continuously display and replace an image in a Tkinter interface taken from OpenCV's VideoCapture. However, I am getting the following error that I think is a result of improper formatting of the image numpy array:
TypeError: unhashable type: 'numpy.ndarray'
How can I reformat it to all it to display properly? Below is my code:
import tkinter as tk
import cv2
import numpy as np
from PIL import ImageTk, Image
main = tk.Tk()
main.title("Hole Pattern Recognition")
main.geometry("300x300")
frame = tk.Frame(main)
frame.pack()
def startScan():
global main, frame
#begins utilizing webcam for scan
cap = cv2.VideoCapture(0)
while(True):
ret,img = cap.read()
img = ImageTk.PhotoImage(img)
panel = tk.Label(main, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
ch = cv2.waitKey(1)
if ch == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
startButton = tk.Button(frame,
text="Start Scan",
fg="blue",
command=startScan)
startButton.pack(side=tk.TOP)
main.mainloop()
First you need to use PIL.Image.fromarray() to convert the captured image to format supported by tkinter.
Second better not use while loop in main thread as it will block the tkinter mainloop. Use after() instead.
import tkinter as tk
from PIL import Image, ImageTk
import cv2
cap = None
main = tk.Tk()
main.title('Hole Pattern Recognition')
#main.geometry('300x300')
frame = tk.Frame(main)
frame.pack()
def startScan():
global cap
def scan():
ret, img = cap.read()
if ret:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
tkimg = ImageTk.PhotoImage(img)
panel.config(image=tkimg)
panel.tkimg = tkimg # save a reference to the image to avoid garbage collection
panel.after(25, scan) # change 25 to other value to adjust FPS
if cap is None:
cap = cv2.VideoCapture(0)
scan() # start the capture loop
else:
print('capture already started')
startButton = tk.Button(frame, text='Start Scan', fg='blue', command=startScan)
startButton.pack()
panel = tk.Label(main)
panel.pack()
main.mainloop()
if cap:
cap.release()

I Cant get an image to be resized and displayed using tkinter

So im trying to make an app that will display images, and the image I have is 1000*1000 but this is way too big, I need a way to resize the image. I've tried using PIL and ImageTK but that didn't work, here's my code so far:
from tkinter import *
app = Tk()
app.title('embeded image')
fname = Canvas(bg = 'black', height=100, width=100)
fname.pack(side=TOP)
image = PhotoImage('Sun.png')
image = image.resize((25, 25), Image.ANTIALIAS)
icon = fname.create_image(image=image)
fname.pack()
app.mainloop()
I've no idea why this doesn't work, im relatively new to Tkinter so sorry if it's obvious.
You mix two differnt class PhotoImage in tkinter which doesn't have resize and PIL.Image which have resize
import tkinter as tk
from PIL import Image, ImageTk
app = tk.Tk()
fname = tk.Canvas(height=200, width=200)
fname.pack()
pil_image = Image.open('Sun.png')
pil_image = pil_image.resize((25, 25), Image.ANTIALIAS)
image = ImageTk.PhotoImage(pil_image)
icon = fname.create_image((0,0), image=image, anchor='nw')
app.mainloop()

Categories

Resources