Skip to content

Instantly share code, notes, and snippets.

@bhind
Last active March 10, 2017 01:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhind/7c169917e2e52e2529636b45020a588f to your computer and use it in GitHub Desktop.
Save bhind/7c169917e2e52e2529636b45020a588f to your computer and use it in GitHub Desktop.
# coding: utf-8
# USAGE
# opencv_colorpicker.py
# import the necessary packages
from Tkinter import Tk
from Tkinter import *
from PIL import Image
from PIL import ImageTk
import tkFileDialog
import cv2
import numpy as np
class OpenCVColorPicker:
def select_image(self):
# open a file chooser dialog and allow the user to select an input
# image
self.path = tkFileDialog.askopenfilename()
# ensure a file path was selected
if len(self.path) > 0:
# load the image from disk, convert it to grayscale, and detect
# edges in it
self.cv2_image = cv2.imread(self.path)
self.root.geometry('%dx%d' % self.cv2_image.shape[-2::-1])
self.attatch_filter()
def create_window(self):
# initialize the window toolkit along with the two image panels
# root = Tk()
self.controll_window = Toplevel()
self.controll_window.title('controller')
# create a button, then when pressed, will trigger a file chooser
# dialog and allow the user to select an input image; then add the
# button the GUI
btn = Button(self.controll_window, text="Select an image", command=self.select_image)
btn.pack(side="top", fill="both", expand="yes", padx="10", pady="10")
btn = Button(self.controll_window, text="attatch filter", command=self.attatch_filter)
btn.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
w = Scale(self.controll_window, label="Brightness min", from_=0, to=255, orient=HORIZONTAL, variable=self.v_min, command=self.attatch_filter)
w.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
w = Scale(self.controll_window, label="Brightness max", from_=0, to=255, orient=HORIZONTAL, variable=self.v_max, command=self.attatch_filter)
w.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
w = Scale(self.controll_window, label="Saturation min", from_=0, to=255, orient=HORIZONTAL, variable=self.s_min, command=self.attatch_filter)
w.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
w = Scale(self.controll_window, label="Saturation max", from_=0, to=255, orient=HORIZONTAL, variable=self.s_max, command=self.attatch_filter)
w.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
w = Scale(self.controll_window, label="Hue min", from_=0, to=179, orient=HORIZONTAL, variable=self.h_min, command=self.attatch_filter)
w.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
w = Scale(self.controll_window, label="Hue max", from_=0, to=179, orient=HORIZONTAL, variable=self.h_max, command=self.attatch_filter)
w.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
self.frame = Frame(self.root)
self.frame.pack(fill=BOTH, expand=YES)
self.canvas = Canvas(self.frame)
self.canvas_image = self.canvas.create_image(0, 0, anchor=NW, image=None)
self.canvas.pack(fill=BOTH, expand=YES)
self.canvas.bind('<Configure>', self.canvas_resize)
self.root.update()
self.controll_window.update()
self.controll_window.minsize(width=320, height=self.controll_window.winfo_height())
def canvas_resize(self, event):
return
def attatch_filter(self, val=None):
if self.path == "":
return
if self.cv2_image is None:
return
# self.image = cv2.imread(self.path)
self.mask = self.create_mask(self.cv2_image)
_edged = cv2.bitwise_and(self.cv2_image, self.cv2_image, mask=self.mask)
# OpenCV represents images in BGR order; however PIL represents
# images in RGB order, so we need to swap the channels
_image = cv2.cvtColor(self.cv2_image, cv2.COLOR_BGR2RGB)
_edged = cv2.cvtColor(_edged, cv2.COLOR_BGR2RGB)
# convert the images to PIL format...
_image = Image.fromarray(_image)
_edged = Image.fromarray(_edged)
# ...and then to ImageTk format
self.image = ImageTk.PhotoImage(_image)
self.edged = ImageTk.PhotoImage(_edged)
# if the panels are None, initialize them
# if self.panelA is None:
# # the first panel will store our original image
# # self.panelA = Label(image=self.image)
# self.panelA = Label(image=self.edged)
# self.panelA.image = self.image
# self.panelA.pack(side="left", padx=10, pady=10)
#
# # while the second panel will store the edge map
# # self.panelB = Label(image=self.edged)
# # self.panelB.image = self.edged
# # self.panelB.pack(side="right", padx=10, pady=10)
#
# # otherwise, update the image panels
# else:
# # update the pannels
# if self.orgflag:
# self.panelA.configure(image=self.image)
# self.panelA.image = self.edged
# else:
# self.panelA.configure(image=self.edged)
# self.panelA.image = self.edged
img = None
if self.orgflag:
img = self.image
else:
img = self.edged
self.canvas.itemconfigure(self.canvas_image, image=img)
# self.root.update()
def create_mask(self, image):
h_min_ = self.h_min.get()
h_max_ = self.h_max.get()
if (h_min_ <= h_max_):
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower_red = np.array([h_min_, self.s_min.get(), self.v_min.get()])
upper_red = np.array([h_max_, self.s_max.get(), self.v_max.get()])
return cv2.inRange(hsv, lower_red, upper_red)
# h_max_ > h_min_
hsv = cv2.cvtColor(self.cv2_image, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, self.s_min.get(), self.v_min.get()])
upper_red = np.array([h_max_, self.s_max.get(), self.v_max.get()])
mask = cv2.inRange(hsv, lower_red, upper_red)
lower_red = np.array([h_min_, self.s_min.get(), self.v_min.get()])
upper_red = np.array([179, self.s_max.get(), self.v_max.get()])
mask2 = cv2.inRange(hsv, lower_red, upper_red)
return cv2.bitwise_or(mask, mask2)
def keyup(self, e):
if e.char == ' ':
self.orgflag = not self.orgflag
self.attatch_filter()
def __init__(self):
self.root = Tk()
self.root.title('Main')
self.root.bind("<KeyRelease>", self.keyup)
self.path = ''
self.controll_window = None
self.cv2_image = None
self.image = None
self.mask = None
# self.panelA = None
self.frame = None
self.canvas = None
self.canvas_image = None
self.h_max = IntVar()
self.h_max.set(20)
self.h_min = IntVar()
self.h_min.set(160)
self.s_max = IntVar()
self.s_max.set(200)
self.s_min = IntVar()
self.s_min.set(0)
self.v_max = IntVar()
self.v_max.set(255)
self.v_min = IntVar()
self.v_min.set(200)
self.orgflag = False
self.create_window()
self.select_image()
# kick off the GUI
self.root.mainloop()
obj = OpenCVColorPicker()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment