2016-12-11 58 views
0

我正在创建一个程序来检测使用Tkinter-OpenCV-Python的对象。 我已经创建与跟踪条的界面和我上传的图片,但在改变的TrackBar这不是在图像更新后的值的时刻Trackbar HSV OpenCv Tkinter Python

from Tkinter import *   # Para Interfaz Grafica 
import Tkinter 
import gtk      # Para Obtener Ancho/Alto 
import tkFileDialog    # Para Buscar Archivo 
import cv2      # Libreria OpenCV 
from PIL import Image, ImageTk 
import numpy as np 

#******************************************************************* 
#Se crea la Pantalla Principal, tomando el Ancho/Alto de la Pantalla 
#Se captura el ancho y alto 
width = gtk.gdk.screen_width() 
height = gtk.gdk.screen_height() 
app = Tk() 
#app.config(bg="red") # Le da color al fondo 
app.geometry(str(width)+"x"+str(height)) # Cambia el tamaño de la ventana 
app.title("TEST") 
#******************************************************************* 
#Buscar Imagen 
def select_image(): 
    # open a file chooser dialog and allow the user to select an input 
    # image 
    path = tkFileDialog.askopenfilename() 
    if len(path) > 0: # Si se ha cargado la imagen 
     # cargar imagen del disco 
     image = cv2.imread(path,1) 
     data = image.shape 
     # OpenCV representa imagenes en BGR ; sin embargo PIL representa 
     # imagenes en RGB , es necesario intercambiar los canales 
     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 

     hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 
     lw_range = np.array([0, 0, 0]) 
     up_range = np.array([255, 255, 255]) 
     mask = cv2.inRange(hsv, lw_range, up_range) 
     res = cv2.bitwise_and(image,image, mask= mask) 
     # convertir la imagen a formato PIL 
     image = Image.fromarray(res).resize((570,570),Image.ANTIALIAS) 
     # ...Luego a formato ImageTk 
     image=ImageTk.PhotoImage(image) 
     label_img = Label(app, image = image,relief=SOLID) 
     label_img.image=image 
     label_img.pack() 
     label_img.place(x=790,y=5) 

     label1 = Label(app, text="Informacion Imagen\nAlto:{}\nAncho:{}\nCanales:{}".format(data[0],data[1],data[2])) 
     label1.pack() 
     label1.place(x=790,y=577) 


btn = Button(app, text="Abrir Imagen", command=select_image) 
btn.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10") 
btn.place(x=5,y=5) 
btn.configure(width=12) 

#******************************************** 
#LABEL H 
label2=Label(app,text = 'Filtro HSV') 
label2.place(x=0,y=50) 
label2.configure(width=7) 
label2.configure(height=2) 
#LABEL H 
label10=Label(app,text = 'Hue') 
label10.place(x=0,y=70) 
label10.configure(width=7) 
label10.configure(height=2) 

#SLIDER H MINIMO 
Hmin = StringVar() 
w1 = Scale(app, from_=0, to=255, orient=HORIZONTAL,variable = Hmin) 
w1.pack() 
w1.place(x=70,y=70) 
w1.configure(width=15) 

#SLIDER H MAXIMO 
Hmax= StringVar() 
w2 = Scale(app, from_=0, to=255, orient=HORIZONTAL,variable = Hmax) 
w2.pack() 
w2.place(x=190,y=70) 
w2.configure(width=15) 

#LABEL S 
label11=Label(app,text = 'Saturation') 
label11.place(x=0,y=120) 
label11.configure(width=7) 
label11.configure(height=2) 

#SLIDER S MINIMO 
Smin= StringVar() 
w3 = Scale(app, from_=0, to=255, orient=HORIZONTAL,variable = Smin) 
w3.pack() 
w3.place(x=70,y=120) 
w3.configure(width=15) 

#SLIDER S MAXIMO 
Smax= StringVar() 
w4 = Scale(app, from_=0, to=255, orient=HORIZONTAL, variable = Smax) 
w4.pack() 
w4.place(x=190,y=120) 
w4.configure(width=15) 

#LABEL V 
label11=Label(app,text = 'Value') 
label11.place(x=0,y=170) 
label11.configure(width=7) 
label11.configure(height=2) 

#SLIDER V MINIMO 
Vmin = StringVar() 
w5 = Scale(app, from_=0, to=255, orient=HORIZONTAL, variable = Vmin) 
w5.pack() 
w5.place(x=70,y=170) 
w5.configure(width=15) 

#SLIDER V MAXIMO 
Vmax = StringVar() 
w6= Scale(app, from_=0, to=255, orient=HORIZONTAL,variable = Vmax) 
w6.pack() 
w6.place(x=190,y=170) 
w6.configure(width=15) 
#******************************************** 

app.mainloop() 

test 图像不发生任何变化

+0

不使用'的地方()'和'包()'(和'格( )'),他们是不同的布局管理者,他们使用不同的规则将窗口部件放在窗口中。如果你使用其中两个,那么你可以得到有冲突的错误信息,或者只使用其中的一个。 – furas

+0

tkinter有自己的方法来获得屏幕大小,你不需要gtk - http://stackoverflow.com/questions/3949844/how-to-get-the-screen-size-in-tkinter – furas

+0

首先你需要的功能将更新图像并将其替换为窗口。我没有看到任何更新图像的功能。稍后,您必须将此功能分配给滑块或按钮。 – furas

回答

0

您必须为每个Scale分配功能,并且当您移动滑块时它将被执行。

tk.Scale(..., command=function_name) 

完整版只能从Scale

import Tkinter as tk 
import tkFileDialog 

import cv2 
from PIL import Image, ImageTk 
import numpy as np 

# --- functions --- 

def select_image(): 

    path = tkFileDialog.askopenfilename() 

    if path: 

     image = cv2.imread(path, 1) 

     data = image.shape 

     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 
     hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 

     lw_range = np.array([0, 0, 0]) 
     up_range = np.array([255, 255, 255]) 

     mask = cv2.inRange(hsv, lw_range, up_range) 
     res = cv2.bitwise_and(image, image, mask= mask) 

     image = Image.fromarray(res).resize((570,570), Image.ANTIALIAS) 

     image = ImageTk.PhotoImage(image) 
     label_img = tk.Label(app, image=image, relief=tk.SOLID) 
     label_img.image = image 
     label_img.place(x=790, y=5) 

     label1 = tk.Label(app, text="Informacion Imagen\nAlto:{}\nAncho:{}\nCanales:{}".format(data[0], data[1], data[2])) 
     label1.place(x=790, y=577) 

def modify_image(name, value): 
    print(name, value) 

# --- main --- 

app = tk.Tk() 

width = app.winfo_screenwidth() 
height = app.winfo_screenheight() 

app.geometry('{}x{}'.format(width, height)) 
app.title("TEST") 

btn = tk.Button(app, text="Abrir Imagen", command=select_image, width=12) 
btn.place(x=5, y=5) 

#******************************************** 
#LABEL H 
label2 = tk.Label(app, text='Filtro HSV', width=7, height=2) 
label2.place(x=0, y=50) 
#LABEL H 
label10 = tk.Label(app, text='Hue', width=7, height=2) 
label10.place(x=0, y=70) 

#SLIDER H MINIMO 
Hmin = tk.StringVar() 
w1 = tk.Scale(app, from_=0, to=255, orient=tk.HORIZONTAL, variable=Hmin, width=15, command=lambda value:modify_image('h_min', value)) 
w1.place(x=70, y=70) 

#SLIDER H MAXIMO 
Hmax= tk.StringVar() 
w2 = tk.Scale(app, from_=0, to=255, orient=tk.HORIZONTAL, variable=Hmax, width=15, command=lambda value:modify_image('h_max', value)) 
w2.place(x=190, y=70) 

#LABEL S 
label11 = tk.Label(app, text='Saturation', width=7, height=2) 
label11.place(x=0, y=120) 

#SLIDER S MINIMO 
Smin = tk.StringVar() 
w3 = tk.Scale(app, from_=0, to=255, orient=tk.HORIZONTAL, variable=Smin, width=15, command=lambda value:modify_image('s_min', value)) 
w3.place(x=70, y=120) 

#SLIDER S MAXIMO 
Smax = tk.StringVar() 
w4 = tk.Scale(app, from_=0, to=255, orient=tk.HORIZONTAL, variable=Smax, width=15, command=lambda value:modify_image('s_max', value)) 
w4.place(x=190, y=120) 

#LABEL V 
label11 = tk.Label(app, text='Value', width=7, height=2) 
label11.place(x=0, y=170) 

#SLIDER V MINIMO 
Vmin = tk.StringVar() 
w5 = tk.Scale(app, from_=0, to=255, orient=tk.HORIZONTAL, variable=Vmin, width=15, command=lambda value:modify_image('v_min', value)) 
w5.place(x=70, y=170) 

#SLIDER V MAXIMO 
Vmax = tk.StringVar() 
w6 = tk.Scale(app, from_=0, to=255, orient=tk.HORIZONTAL,variable=Vmax, width=15, command=lambda value:modify_image('v_max', value)) 
w6.place(x=190, y=170) 
#******************************************** 

app.mainloop() 
+1

非常感谢你我解决了它:D https://youtu.be/2_2X-MyLau4 –

+0

顺便说一句:你可以添加你的代码作为回答并接受它:) – furas

1

大显示值:d

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

# Interfaz para procesar Imagenes 

import Tkinter as tk 
from PIL import Image 
from PIL import ImageTk 
import tkFileDialog 
import time 
import cv2 
import numpy as np 
from subprocess import check_output 
from pyscreenshot import grab 
from threading import Thread, Lock 

once = True 
img_screenshot = None 

class App: 
    original_image = None 
    hsv_image = None 
    # switch to make sure screenshot not taken while already pressed 
    taking_screenshot = False 

    def __init__(self, master): 
     self.img_path = None 
     frame = tk.Frame(master) 
     frame.grid() 
     root.title("Cultivos") 

     width = root.winfo_screenwidth() 
     height = root.winfo_screenheight() 

     root.geometry('{}x{}'.format(width,height)) 

     #self.hue_lbl = tk.Label(text="Hue", fg='red') 
     #self.hue_lbl.grid(row=2) 

     self.low_hue = tk.Scale(master, label='Low',from_=0, to=179, length=200,showvalue=2,orient=tk.HORIZONTAL, command=self.show_changes) 
     self.low_hue.place(x=0, y=50) 

     self.high_hue = tk.Scale(master,label='High', from_=0, to=179, length=200,orient=tk.HORIZONTAL, command=self.show_changes) 
     self.high_hue.place(x=200, y=50) 
     self.high_hue.set(179) 
########################################################################################################### 
     #self.sat_lbl = tk.Label(text="Saturation", fg='green') 
     #self.sat_lbl.grid(row=5) 

     self.low_sat = tk.Scale(master, label='Low',from_=0, to=255, length=200,orient=tk.HORIZONTAL, command=self.show_changes) 
     self.low_sat.place(x=0,y=120) 

     self.high_sat = tk.Scale(master, label="High", from_=0, to=255, length=200,orient=tk.HORIZONTAL, command=self.show_changes) 
     self.high_sat.place(x=200,y=120) 
     self.high_sat.set(255) 
########################################################################################################### 
     #self.val_lbl = tk.Label(text="Value", fg='Blue') 
     #self.val_lbl.grid(row=8) 

     self.low_val = tk.Scale(master, label="Low",from_=0, to=255, length=200,orient=tk.HORIZONTAL, command=self.show_changes) 
     self.low_val.place(x=0,y=190) 

     self.high_val = tk.Scale(master, label="High",from_=0, to=255, length=200,orient=tk.HORIZONTAL, command=self.show_changes) 
     self.high_val.place(x=200,y=190) 
     self.high_val.set(255) 
     #self.high_val.grid(row=10) 

########################################################################################################### 
# buttons 
     #self.print_btn = tk.Button(text='Print', command=self.print_values) 
     #self.print_btn.place(x=0,y=250) 

     # Open 
     self.open_btn = tk.Button(text="Open", command=self.open_file) 
     self.open_btn.place(x=0,y=10) 
     #self.open_btn.grid(row=6, column=1) 

########################################################################################################### 
     # timer label 
     #self.screenshot_timer_lbl = tk.Label(text="Timer", fg='Red') 
     #self.screenshot_timer_lbl.grid(row=8, column=1) 

########################################################################################################## Images 
     # images 
     self.hsv_img_lbl = tk.Label(text="HSV", image=None) 
     self.hsv_img_lbl.place(x=790,y=380) 
     #self.hsv_img_lbl.grid(row=0, column=0) 

     self.original_img_lbl = tk.Label(text='Original',image=None) 
     self.original_img_lbl.place(x=790,y=0) 
     #self.original_img_lbl.grid(row=0, column=1) 
########################################################################################################## 
    def open_file(self): 
     global once 
     once = True 
     img_file = tkFileDialog.askopenfilename() # Buscar Archivo 
     # this makes sure you select a file 
     # otherwise program crashes if not 
     if img_file != '':  # Si La imagen existe 
      self.img_path = img_file 
      # Esto solo se asegura de que la imagen se muestra despues de abrirlo 
      self.low_hue.set(self.low_hue.get()+1) 
      self.low_hue.set(self.low_hue.get()-1) 
     else: 
      print('No se Selecciono Nada') 
      return 0 


    def show_changes(self, *args): 
     global once, img_screenshot 

     if self.img_path == None: # Si la imagen no hace nada 
      return 0 

     # obtener valores de los sliders 
     # Bajos 
     low_hue = self.low_hue.get() 
     low_sat = self.low_sat.get() 
     low_val = self.low_val.get() 
     # Altos 
     high_hue = self.high_hue.get() 
     high_sat = self.high_sat.get() 
     high_val = self.high_val.get() 
     # No hace nada si los valores bajos van mas altos que los valores altos 
     if low_val > high_val or low_sat > high_sat or low_hue > high_hue: 
      return 0 

     # Establece la imagen original una vez, manipula la copia en las siguientes iteraciones 
     if once: 
      # Obtiene la imagen del archivo 
      if self.img_path != 'screenshot': 
       #img_path = 'objects.png' 
       # carga BGR 
       self.original_image = cv2.imread(self.img_path,1) 
       # image resized 
       self.original_image = self.resize_image(self.original_image) 
       self.hsv_image = self.original_image.copy() 
       #convierte imagen a HSV 
       self.hsv_image = cv2.cvtColor(self.hsv_image, cv2.COLOR_BGR2HSV) 

      # gets screenshot 
      else: 
       self.original_image = img_screenshot 
       self.hsv_image = img_screenshot.copy() 
       #converts image to HSV 
       self.hsv_image = cv2.cvtColor(self.hsv_image, cv2.COLOR_BGR2HSV) 

      # OpenCV representa imagenes en orden BGR; 
      #Sin embargo PIL representa imagenes en orden RGB, por lo que tenemos que intercambiar los canales 
      self.original_image = cv2.cvtColor(self.original_image, cv2.COLOR_BGR2RGB) 

      # convierte imagen a formato PIL 
      self.original_image = Image.fromarray(self.original_image)#.resize((500,500), Image.ANTIALIAS) 
      # convierta a formato ImageTk 
      self.original_image = ImageTk.PhotoImage(self.original_image) 
      # Actualizar la etiqueta de la imagen original 
      self.original_img_lbl.configure(image=self.original_image) 
      # Keeping a reference! b/ need to! 
      #Mantener una referencia! B/necesidad de! 
      self.original_img_lbl.image = self.original_image 
      once = False 




     # Define los valores inferior y superior de la mascara 
     # define range of colors in HSV (hue up to 179, sat-255, value-255 
     lower_color = np.array([low_hue,low_sat,low_val]) 
     upper_color= np.array([high_hue,high_sat,high_val]) 
     # red - 0,255,255 (low (hue-10,100,100) high(hue+10,255,255) 
     # green 60,255,255 
     # blue -120,255,255 

     #crea una mascara con el resultado 
     mask = cv2.inRange(self.hsv_image, lower_color, upper_color) 
     #res = cv2.bitwise_and(self.original_image.copy(), self.original_image.copy(), mask=mask) 

     # convierte a formato RGB 
     #maskbgr = cv2.cvtColor(mask, cv2.COLOR_HSV2BGR) 
     #maskrgb = cv2.cvtColor(maskbgr, cv2.COLOR_BGR2RGB) 
     # convierte a formato PIL 
     mask = Image.fromarray(mask) 
     # convierte a formato ImageTk 
     mask = ImageTk.PhotoImage(mask) 
     # Ajuste de la imagen de hsv a tk etiqueta de imagen 
     self.hsv_img_lbl.configure(image=mask) 
     # adding a reference to the image to Prevent python's garbage collection from deleting it 
     #Anadiendo una referencia a la imagen para evitar que python garbage collection lo elimine 
     self.hsv_img_lbl.image = mask 


    def resize_image(self,img,*args): 
     # Desembala anchura, altura 
     height, width,_ = img.shape 
     print("Original size: {} {}".format(width, height)) 
     count_times_resized = 0 
     while width > 500 or height > 500: 
     #if width > 300 or height > 300: 
      # divides images WxH by half 
      width = width/2 
      height = height /2 
      count_times_resized += 1 
     # prints x times resized to console 
     if count_times_resized != 0: 
      print("Resized {}x smaller, to: {} {}".format(count_times_resized*2,width, height)) 
     # makes sures image is not TOO small 
     if width < 300 and height < 300: 
      width = width * 2 
      height = height * 2 

     img = cv2.resize(img,(width,height)) 

     return img 


# Instance of Tkinter 
root = tk.Tk() 
# New tkinter instnace of app 
app = App(root) 
# loops over to keep window active 
root.mainloop()