使用滑块编辑颜色值



我的目标是用单独的滑块编辑这6个值,因为我正在查看结果,所以我可以快速完善我的脚本正在检测的内容。

lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255]))

~更新脚本~新问题"我如何去让滑块与值交互,而我正在捕捉帧从我的网络摄像头?"

import cv2
import numpy as np
from Tkinter import *
master = Tk()
w1 = Scale(master, from_=110, to=255, orient=HORIZONTAL)
w1.pack()
w2 = Scale(master, from_=50, to=255, orient=HORIZONTAL)
w2.pack()
w3 = Scale(master, from_=50, to=255, orient=HORIZONTAL)
w3.pack()
w4 = Scale(master, from_=130, to=255, orient=HORIZONTAL)
w4.pack()
w5 = Scale(master, from_=255, to=255, orient=HORIZONTAL)
w5.pack()
w6 = Scale(master, from_=255, to=255, orient=HORIZONTAL)
w6.pack()
w1 = w1.get()
w2 = w2.get()
w3 = w3.get()
w4 = w4.get()
w5 = w5.get()
w6 = w6.get()
cap = cv2.VideoCapture(0)
while(1):
    _, frame = cap.read()
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    lower_blue = np.array([w1,w2,w3])
    upper_blue = np.array([w4,w5,w6])
    mask = cv2.inRange(hsv, lower_blue, upper_blue)
    res = cv2.bitwise_and(frame,frame, mask= mask)
    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
cv2.destroyAllWindows()

所以这里有一些问题。首先,您将覆盖以下行中的w1,w2,w3...变量:

w1 = w1.get()
w2 = w2.get()
w3 = w3.get()
w4 = w4.get()
w5 = w5.get()
w6 = w6.get()

这是删除对Scale小部件的引用,阻止您再次使用它们。

第二个问题是,你正在遇到一种情况,你真的应该使用多线程。理想情况下,while循环将在一个线程中运行,并且为了保持响应,Scale部件也应该在一个线程中运行。

[侧边栏:事实证明,在线程之间共享Scale小部件会导致一些非常奇怪的行为,因此作为一种工作,我已经从multiprocessing模块同步Array,这是线程安全的]

我建议你去阅读Python中的线程。但是,为了让您入门,下面的代码给出了如何在一个线程中运行Scale小部件,同时在另一个线程中循环的示例。

import Tkinter as tk
from threading import Thread,Event
from multiprocessing import Array
from ctypes import c_int32
class CaptureController(tk.Frame):
    NSLIDERS = 6
    def __init__(self,parent):
        tk.Frame.__init__(self)
        self.parent = parent
        # create a synchronised array that other threads will read from
        self.ar = Array(c_int32,self.NSLIDERS)
        # create NSLIDERS Scale widgets
        self.sliders = []
        for ii in range(self.NSLIDERS):
            # through the command parameter we ensure that the widget updates the sync'd array
            s = tk.Scale(self, from_=0, to=255, orient=tk.HORIZONTAL,
                         command=lambda pos,ii=ii:self.update_slider(ii,pos))
            s.pack()
            self.sliders.append(s)
        # Define a quit button and quit event to help gracefully shut down threads 
        tk.Button(self,text="Quit",command=self.quit).pack()
        self._quit = Event()
        self.capture_thread = None
    # This function is called when each Scale widget is moved
    def update_slider(self,idx,pos):
        self.ar[idx] = c_int32(int(pos))
    # This function launches a thread to do video capture
    def start_capture(self):
        self._quit.clear()
        # Create and launch a thread that will run the video_capture function 
        self.capture_thread = Thread(target=video_capture, args=(self.ar,self._quit))
        self.capture_thread.daemon = True
        self.capture_thread.start()
    def quit(self):
        self._quit.set()
        try:
            self.capture_thread.join()
        except TypeError:
            pass
        self.parent.destroy()
# This function simply loops over and over, printing the contents of the array to screen
def video_capture(ar,quit):
    # This while loop would be replaced by the while loop in your original code
    while not quit.is_set():
        print ar[:]
        # the slider values are all readily available through the indexes of ar
        # i.e. w1 = ar[0]
        # w2 = ar[1]
        # etc. 

if __name__ == "__main__":
    root = tk.Tk()
    selectors = CaptureController(root)
    selectors.pack()
    selectors.start_capture()
    root.mainloop()

最新更新