Reader to create a simple Windows-styled GUI app to read datamatrixfrom the webcam video stream. i'm trying to use OpenCV for Python to capture webcam frames with tkinter GUI .I am trying with pylibdmtx which works well for images but lags and doesn't detect in video. When using tkinter, we cannot keep drawing the frames in an infinite loop in the main thread. we can use OpenCV to capture a frame and decode the frame by calling the pylibdmtx. Note: before creating a TKImage with the frame, we have to convert the color space of the frame from BRG to RGB.
from tkinter import *
import time
from pylibdmtx.pylibdmtx import decode
import numpy as np
from PIL import Image, ImageTk
import cv2
import tkinter
from tkinter import ttk
from tkinter.ttk import Progressbar
w = Tk()
width_of_window = 427
height_of_window = 250
screen_width = w.winfo_screenwidth()
screen_height = w.winfo_screenheight()
x_coordinate = (screen_width / 2) - (width_of_window / 2)
y_coordinate = (screen_height / 2) - (height_of_window / 2)
w.geometry("%dx%d+%d+%d" % (width_of_window, height_of_window, x_coordinate, y_coordinate))
w.overrideredirect(1)
s = ttk.Style()
s.theme_use('clam')
s.configure("red.Horizontal.TProgressbar", foreground='red', background='#172884')
progress = Progressbar(w, style="red.Horizontal.TProgressbar", orient=HORIZONTAL, length=500, mode='determinate', )
def bar():
l4 = Label(w, text='Loading...', fg='white', bg=a)
lst4 = ('Calibri (Body)', 10)
l4.config(font=lst4)
l4.place(x=18, y=210)
import time
r = 0
for i in range(100):
progress['value'] = r
w.update_idletasks()
time.sleep(0.03)
r = r + 1
w.destroy()
progress.place(x=-10, y=235)
a = '#172884'
Frame(w, width=427, height=241, bg=a).place(x=0, y=0) # 249794
b1 = Button(w, width=10, height=1, text='Get Started', command=bar, border=0, fg=a, bg='white')
b1.place(x=170, y=200)
l1 = Label(w, text='TUNI', fg='#198cdd', bg=a)
lst1 = ('Calibri (Body)', 24, 'bold')
l1.config(font=lst1)
l1.place(x=50, y=80)
l1 = Label(w, text='TECH', fg='white', bg=a)
lst1 = ('Calibri (Body)', 24, 'bold')
l1.config(font=lst1)
l1.place(x=126, y=80)
l2 = Label(w, text='Engineering', fg='#198cdd', bg=a)
lst2 = ('Calibri (Body)', 9)
l2.config(font=lst2)
l2.place(x=55, y=115)
l3 = Label(w, text='services', fg='#198cdd', bg=a)
lst3 = ('Calibri (Body)', 9)
l3.config(font=lst3)
l3.place(x=130, y=115)
w.mainloop()
Detection_start = False
def start():
global Detection_start
Detection_start = not Detection_start
cameratest = tkinter.Tk()
cameratest.geometry("800x800")
cameratest.resizable(800, 600)
cameratest.title("CAMERA DISPLAY")
cameratest.configure(bg="#172884")
panel_image = tkinter.Label(cameratest, width=800, height=500)
panel_image.place(x=15, y=60)
message = "Press ''Start'' to search for code"
panel_text = tkinter.Label(cameratest, text=message, fg='green', bg=a)
poly = ('Times New Roman (Body)', 18)
panel_text.config(font=poly)
panel_text.grid(row=1, column=1, pady=1, padx=220)
Button_start = Button(cameratest, text="Start", command=start, fg=a)
poly1 = ('Times New Roman (Body)', 12)
Button_start.config(font=poly1)
Button_start.place(x=650, y=1)
cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
while True:
start()
cameratest.update()
ret, frame = cam.read()
# Update the image to tkinter...
t0 = time.time()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
frame = cv2.GaussianBlur(gray, (5, 5), 0)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
lower_white = np.array([170, 170, 170])
upper_white = np.array([255, 255, 255])
white_mask = cv2.inRange(frame, lower_white, upper_white)
ret, im_th = cv2.threshold(white_mask, 90, 255, cv2.THRESH_BINARY_INV)
contours, hierarchy = cv2.findContours(white_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
x, y, w, h = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 3)
if Detection_start:
frame1 = cv2.resize(frame, (0, 0), fx=0.2, fy=0.2)
code = decode(frame1, max_count=1, corrections=3)
if code:
print((time.time() - t0) * 1000)
print(code)
print(code[0].data.decode('utf-8'))
print(code[0].rect)
x, y, w, h = code[0].rect
cv2.rectangle(frame, (x * 5, y * 5), (x * 5 + w * 5, y * 5 + h * 5), (0, 255, 0), 2)
else:
panel_text.configure(text="no code found ! ", fg='red')
else:
panel_text.configure(text="Press ''Start'' to search for code", fg='blue')
img_update = ImageTk.PhotoImage(Image.fromarray(frame))
panel_image.configure(image=img_update)
panel_image.image = img_update
panel_image.update()