feat: hsv 可视化筛选器

This commit is contained in:
raiots 2023-05-20 17:14:50 +08:00
parent 06d9d82392
commit d9ffff7228
2 changed files with 46 additions and 159 deletions

View File

@ -1,159 +1,43 @@
import os
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2
import numpy as np
os.chdir('D:\Documents\Programing\PycharmProjects\OrionVision\data')
class GUI():
def __init__(self, window):
self.window = window
# title
self.window.title("fish fish fish")
# siz=800*600,position=(500,200)
self.window.geometry('1600x800+500+200')
self.window["bg"] = "DimGray"
# self.img_src = Image.open("../data/004.png")
self.img_src = Image.open(os.getcwd() + "/004.png")
self.img_src.load()
# icon
# self.icon = ImageTk.PhotoImage(file='hsv_icon.ico')
# self.window.call('wm','iconphoto',self.window._w,self.icon)
def choose_file(self):
self.imgpath = filedialog.askopenfilename()
if self.imgpath:
self.img_src = Image.open(self.imgpath)
self.img_src.load()
self.hmin_scale.set(1)
self.hmin_scale.set(0)
self.smin_scale.set(0)
self.vmin_scale.set(0)
self.hmax_scale.set(255)
self.smax_scale.set(255)
self.vmax_scale.set(255)
def start_mark(self, event):
img_block = self.img_src.copy().convert("HSV")
t = list(img_block.getdata())
t2 = []
# print(len(t))
hmin = self.hmin_scale.get()
hmax = self.hmax_scale.get()
smin = self.smin_scale.get()
smax = self.smax_scale.get()
vmin = self.vmin_scale.get()
vmax = self.vmax_scale.get()
for i in range(0, len(t)):
h = t[i][0]
s = t[i][1]
v = t[i][2]
if (h >= hmin) and (h <= hmax) and (s >= smin) and (s <= smax) and (v >= vmin) and (v < vmax):
t2.append((h, s, v))
else:
t2.append((0, 0, 0))
# t2.append((max(t[i][0]-50,20),t[i][1],t[i][2]))
img_block.putdata(t2)
self.img = img_block.convert("RGB")
self.img = self.img.resize((1200, 675))
self.img = ImageTk.PhotoImage(self.img)
BOARD_HEIGHT = 675
BOARD_WIDTH = 1200
self.canvas.create_image(BOARD_WIDTH / 2 + 1, BOARD_HEIGHT / 2 + 1, image=self.img)
# self.canvas.create_image(0,0,image=self.img)
# my_window.update()
def create_widgets(self):
# scale
self.hmin_label = Label(self.window, text='色调下限', fg='WhiteSmoke', bg="DimGray")
self.hmin_scale = Scale(self.window, orient=HORIZONTAL, from_=0, to=255, resolution=1, command=self.start_mark,
tickinterval=50, length=200, width=7, fg='WhiteSmoke', bg="DimGray")
self.hmax_label = Label(self.window, text='色调上限', fg='WhiteSmoke', bg="DimGray")
self.hmax_scale = Scale(self.window, orient=HORIZONTAL, from_=0, to=255, resolution=1, command=self.start_mark,
tickinterval=50, length=200, width=7, fg='WhiteSmoke', bg="DimGray")
self.smin_label = Label(self.window, text='饱和度下限', fg='WhiteSmoke', bg="DimGray")
self.smin_scale = Scale(self.window, orient=HORIZONTAL, from_=0, to=255, resolution=1, command=self.start_mark,
tickinterval=50, length=200, width=7, fg='WhiteSmoke', bg="DimGray")
self.smax_label = Label(self.window, text='饱和度上限', fg='WhiteSmoke', bg="DimGray")
self.smax_scale = Scale(self.window, orient=HORIZONTAL, from_=0, to=255, resolution=1, command=self.start_mark,
tickinterval=50, length=200, width=7, fg='WhiteSmoke', bg="DimGray")
self.vmin_label = Label(self.window, text='明度下限', fg='WhiteSmoke', bg="DimGray")
self.vmin_scale = Scale(self.window, orient=HORIZONTAL, from_=0, to=255, resolution=1, command=self.start_mark,
tickinterval=50, length=200, width=7, fg='WhiteSmoke', bg="DimGray")
self.vmax_label = Label(self.window, text='明度上限', fg='WhiteSmoke', bg="DimGray")
self.vmax_scale = Scale(self.window, orient=HORIZONTAL, from_=0, to=255, resolution=1, command=self.start_mark,
tickinterval=50, length=200, width=7, fg='WhiteSmoke', bg="DimGray")
self.hmax_scale.set(255)
self.smax_scale.set(255)
self.vmax_scale.set(255)
# scale position
self.hmin_label.grid(row=0, column=0, padx=15)
self.hmin_scale.grid(row=0, column=1, pady=2)
self.hmax_label.grid(row=1, column=0)
self.hmax_scale.grid(row=1, column=1, pady=2)
self.smin_label.grid(row=2, column=0)
self.smin_scale.grid(row=2, column=1, pady=2)
self.smax_label.grid(row=3, column=0)
self.smax_scale.grid(row=3, column=1, pady=2)
self.vmin_label.grid(row=4, column=0)
self.vmin_scale.grid(row=4, column=1, pady=2)
self.vmax_label.grid(row=5, column=0)
self.vmax_scale.grid(row=5, column=1, pady=2)
# img
self.img = Image.open(os.getcwd() + "/004.png")
self.img = self.img.resize((1200, 675))
self.img = ImageTk.PhotoImage(self.img)
self.canvas = Canvas(my_window, width=1200, height=675)
BOARD_HEIGHT = 675
BOARD_WIDTH = 1200
self.canvas.create_image(BOARD_WIDTH / 2 + 1, BOARD_HEIGHT / 2 + 1, image=self.img)
self.canvas.place(x=320, y=30)
# self.canvas.pack()
# self.orign = Label(self.window,image=self.img,width=1200,height=675)
# self.work = Label(self.window,image=self.img,width=800,height=450)
# img position
# self.orign.place(x=320, y=30)
# self.work.place(x=650,y=30)
self.refresh_button = Button(self.window, text='选图', font=('宋体', 12), command=self.choose_file, height=2,
width=15, fg='blue', bg="BurlyWood")
self.refresh_button.place(x=18, y=380)
'''
#Button
self.import_button = Button(self.window, text='导入原图',font=('隶书',45), height=2, width=9,fg='WhiteSmoke',bg="BurlyWood")
self.clear_button = Button(self.window, text='删除所有',font=('隶书',12), height=2, width=15,fg='WhiteSmoke',bg="BurlyWood")
self.delete_button = Button(self.window, text='删除当前',font=('隶书',12), height=2, width=15,fg='WhiteSmoke',bg="BurlyWood")
self.switch_button = Button(self.window,text='区域切换',font=('隶书',12), height=2, width=15,fg='WhiteSmoke',bg="BurlyWood")
self.save_button = Button(self.window, text='区域暂存',font=('隶书',12), height=2, width=15,fg='WhiteSmoke',bg="BurlyWood")
self.merge_button = Button(self.window, text='合并区域',font=('隶书',12), height=2, width=15,fg='WhiteSmoke',bg="BurlyWood")
self.picture_button = Button(self.window, text='生成图片',font=('隶书',12), height=2, width=15,fg='WhiteSmoke',bg="BurlyWood")
#button position
self.import_button.place(x=18,y=400)
self.clear_button.place(x=370,y=420)
self.delete_button.place(x=570,y=420)
self.switch_button.place(x=770,y=420)
self.save_button.place(x=370,y=500)
self.merge_button.place(x=570,y=500)
self.picture_button.place(x=770,y=500)
'''
def gui_start():
global my_window
my_window = Tk()
my_gui = GUI(my_window)
my_gui.create_widgets()
my_window.mainloop()
# 滑动条的回调函数,获取滑动条位置处的值
def empty(a):
h_min = cv2.getTrackbarPos("Hue Min", "TrackBars")
h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
print(h_min, h_max, s_min, s_max, v_min, v_max)
return h_min, h_max, s_min, s_max, v_min, v_max
GUI.gui_start()
path = './data/004.png'
# 创建一个窗口放置6个滑动条
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars", 640, 240)
cv2.createTrackbar("Hue Min", "TrackBars", 0, 120, empty)
cv2.createTrackbar("Hue Max", "TrackBars", 19, 120, empty)
cv2.createTrackbar("Sat Min", "TrackBars", 110, 255, empty)
cv2.createTrackbar("Sat Max", "TrackBars", 240, 255, empty)
cv2.createTrackbar("Val Min", "TrackBars", 153, 255, empty)
cv2.createTrackbar("Val Max", "TrackBars", 255, 255, empty)
while True:
img = cv2.imread(path)
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 调用回调函数,获取滑动条的值
h_min, h_max, s_min, s_max, v_min, v_max = empty(0)
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
# 获得指定颜色范围内的掩码
mask = cv2.inRange(imgHSV, lower, upper)
# 对原图图像进行按位与的操作,掩码区域保留
imgResult = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow("Mask", mask)
cv2.imshow("Result", imgResult)
cv2.waitKey(1)

View File

@ -7,15 +7,15 @@ import numpy as np
def read_image(path):
raw = cv2.imread(path)
# 设定颜色HSV范围假定为红色
color_lower = np.array([0, 0, 150])
color_upper = np.array([255, 255, 209])
color_lower = np.array([0, 148, 116])
color_upper = np.array([50, 220, 203])
# 将图像转化为HSV格式
hsv = cv2.cvtColor(raw, cv2.COLOR_BGR2HSV)
# 去除颜色范围外的其余颜色
mask = cv2.inRange(hsv, color_lower, color_upper)
cv2.imshow("mask", mask)
# cv2.imshow("mask", mask)
# 二值化操作
ret, binary = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY)
@ -25,12 +25,15 @@ def read_image(path):
dilation = cv2.dilate(binary, kernel, iterations=1)
#
# img2 = cv2.bitwise_and(img, img, mask=mask)
# cv2.imshow('image', mask)
cv2.imshow('image', dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 获取图像轮廓坐标其中contours为坐标值此处只检测外形轮廓
contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.approxPolyDP(contours[0], 0.01, True)
if __name__ == '__main__':