0

How to add a cv2 trackbar to a Tkinter window?

I have 2 snippets of code that my teammates have made, but it is difficult to integrate them in the same window. I am able to use them in separate windows but I want to use them in the same window.

CODE FOR THE VIDEO PLAYING IN TKINTER:

import cv2
import tkinter as tk
from tkinter import *
# from tkinter import ttk
# from ttk import Frame
# import ImageTk

white       = "#ffffff"
lightBlue2  = "#adc5ed"
font        = "Constantia"
fontButtons = (font, 12)
maxWidth    = 800
maxHeight   = 480

#Graphics window
mainWindow = tk.Tk()
mainWindow.configure(bg=lightBlue2)
mainWindow.geometry('%dx%d+%d+%d' % (maxWidth,maxHeight,0,0))
mainWindow.resizable(0,0)
# mainWindow.overrideredirect(1)

mainFrame = Frame(mainWindow)
mainFrame.place(x=20, y=20)                

#Capture video frames
lmain = tk.Label(mainFrame)
lmain.grid(row=0, column=0)

cap = cv2.VideoCapture('test.mp4')

def show_frame():
    ret, frame = cap.read()

    cv2image   = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)

    img   = Image.fromarray(cv2image).resize((760, 400))
    imgtk = ImageTk.PhotoImage(image = img)
    lmain.imgtk = imgtk
    lmain.configure(image=imgtk)
    lmain.after(10, show_frame)

closeButton = Button(mainWindow, text = "CLOSE", font = fontButtons, bg = white, width = 20, height= 1)
closeButton.configure(command= lambda: mainWindow.destroy())              
closeButton.place(x=270,y=430)  

show_frame()  #Display
mainWindow.mainloop() #Starts GUI

And I have a second snippet of code that uses cv2 to display the track bar and changes the position of the video.

import cv2

CURRENT_FRAME_FLAG = cv2.CAP_PROP_POS_FRAMES
TOTAL_FRAMES_FLAG = cv2.CAP_PROP_FRAME_COUNT
WIN_NAME = "Frame Grabber"
POS_TRACKBAR = "pos_trackbar"

cap = cv2.VideoCapture('C:/Users/ayush/Desktop/test.mp4')

ret, frame = cap.read()


def dummy():
    pass


def save_image():
    filename = "image_%0.5f.png" % t.time()
    cv2.imwrite(filename, frame)


def seek_callback(x):
    global frame
    i = cv2.getTrackbarPos(POS_TRACKBAR, WIN_NAME)
    cap.set(CURRENT_FRAME_FLAG, i-1)
    _, frame = cap.read()
    cv2.imshow(WIN_NAME, frame)


def mouse_callback(event,x,y,flags,param):

    if event == cv2.EVENT_LBUTTONDBLCLK:
        save_image()


def skip_frame_generator(df):

    def skip_frame():
        global frame
        cf = cap.get(CURRENT_FRAME_FLAG) - 1
        cap.set(CURRENT_FRAME_FLAG, cf+df)
        cv2.setTrackbarPos(POS_TRACKBAR, WIN_NAME, int(cap.get(CURRENT_FRAME_FLAG)))
        _, frame = cap.read()

    return skip_frame


cv2.namedWindow(WIN_NAME)
cv2.createTrackbar(POS_TRACKBAR, WIN_NAME, 0, int(cap.get(TOTAL_FRAMES_FLAG)), seek_callback)
cv2.setMouseCallback(WIN_NAME, mouse_callback)

actions = dict()

actions[ord("D")] = skip_frame_generator(10)
actions[ord("d")] = skip_frame_generator(1)
actions[ord("a")] = skip_frame_generator(-1)
actions[ord("A")] = skip_frame_generator(-10)
actions[ord("q")] = lambda: exit(0)
actions[ord("s")] = save_image

while True:

    cv2.imshow(WIN_NAME, frame)
    key = cv2.waitKey(0) & 0xFF
    actions.get(key, dummy)()

I have to integrate the cv2 trackbar into the Tkinter window. I am able to integrate but as I don't know how to use implement CV2 trackbar in tkinter, I am not able to do anything.

Please Help.

Ayush Pant
  • 31
  • 1
  • 6
  • Read [Is this bad programming practice in tkinter?](https://stackoverflow.com/a/25454433/7414759) follow the pattern of **Alternative to the main classmethod:** [Best way to structure a tkinter application](https://stackoverflow.com/a/17470842/7414759) – stovfl Jan 29 '19 at 13:57
  • Can you please still help me with this? – Ayush Pant Jan 29 '19 at 15:16
  • It's to broad for SO, setup a [GitHubGist](https://gist.github.com) let's try this second approach [Displaying TkInter and OpenCV windows on the same time](https://stackoverflow.com/a/30347713/7414759) – stovfl Jan 29 '19 at 16:20

1 Answers1

0

Try using tkinter Scale widgets instead of cv2 trackbars. They are slightly different but they should be fairly easy to swap out and work about the same. Then you can easily add them in your tkinter window/frame.