0

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

1 Answers1

-1

I first ran the main loop with Tkinter, then in this loop I ran loop Opencv. and in it sent frames to interfeis

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 29 '22 at 12:42