Compare commits

...

3 Commits

Author SHA1 Message Date
raiots 06d9d82392 feat: hsv 可视化筛选器及路径框选模块 2023-05-18 22:46:48 +08:00
raiots b627fd0afa change gitignore 2023-05-16 21:00:42 +08:00
raiots 639d4816ea init 2023-05-16 20:59:23 +08:00
5 changed files with 294 additions and 1 deletions

3
.gitignore vendored
View File

@ -4,6 +4,7 @@ __pycache__/
*.py[cod]
*$py.class
data/*
# C extensions
*.so
@ -158,5 +159,5 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/*

67
main.py Normal file
View File

@ -0,0 +1,67 @@
import cv2
import numpy as np
def test():
raw = cv2.imread("./data/003.png")
# 设定颜色HSV范围假定为红色
redLower = np.array([30, 0, 0])
redUpper = np.array([255, 193, 255])
img = raw
# 将图像转化为HSV格式
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 去除颜色范围外的其余颜色
mask = cv2.inRange(hsv, redLower, redUpper)
cv2.imshow("mask", mask)
# 二值化操作
ret, binary = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY)
# 膨胀操作,因为是对线条进行提取定位,所以腐蚀可能会造成更大间隔的断点,将线条切断,因此仅做膨胀操作
kernel = np.ones((5, 5), np.uint8)
dilation = cv2.dilate(binary, kernel, iterations=1)
#
# img2 = cv2.bitwise_and(img, img, mask=mask)
# cv2.imshow('image', mask)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# 获取图像轮廓坐标其中contours为坐标值此处只检测外形轮廓
contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
aim_box = (0, 0, 0, 0)
if len(contours) > 0:
print('Run!')
# cv2.boundingRect()返回轮廓矩阵的坐标值四个值为x, y, w, h 其中x, y为左上角坐标w,h为矩阵的宽和高
boxes = [cv2.boundingRect(c) for c in contours]
for box in boxes:
x, y, w, h = box
if box[2] * box[3] > aim_box[2] * aim_box[3]:
aim_box = box
# print(box)
else:
pass
# x, y, w, h = aim_box
# gray = cv2.GaussianBlur(raw, (5, 5), 0)
# canny = cv2.Canny(gray, 70, 210)
# contours, hierarchy = cv2.findContours(canny.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# contours = sorted(contours, key=cv2.contourArea, reverse=True)[:3]
#
# drawed = cv2.drawContours(raw, contours, -1, (0, 0, 255), 2)
# print(f"轮廓数量:{len(contours)}")
# cv2.imshow("raw", cv2.imread("./data/003.png"))
# cv2.imshow("test1", drawed)
# cv2.imshow("test", canny)
cv2.waitKey(0)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
test()
# See PyCharm help at https://www.jetbrains.com/help/pycharm/

29
sim_control.py Normal file
View File

@ -0,0 +1,29 @@
import airsim
import os
# connect to the AirSim simulator
client = airsim.MultirotorClient()
client.confirmConnection()
# get control
client.enableApiControl(True)
# unlock
client.armDisarm(True)
# Async methods returns Future. Call join() to wait for task to complete.
client.takeoffAsync().join()
# keep fly in square path until get images
client.moveByVelocityAsync(0, 0, 0, 1).join()
# client.moveOnPathAsync([airsim.Vector3r(100, 0, -10)], 0.1, 60, airsim.DrivetrainType.ForwardOnly, airsim.YawMode(False, 0)).join()
# take video from bottom camera and show using cv2
raw = client.simGetImage("bottom_center", airsim.ImageType.Scene)
airsim.write_file(os.path.normpath("./data/004.png"), raw)
client.landAsync().join()
# lock
client.armDisarm(False)
# release control
client.enableApiControl(False)

159
utils/hsv_pick.py Normal file
View File

@ -0,0 +1,159 @@
import os
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
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()
GUI.gui_start()

37
utils/path_detect.py Normal file
View File

@ -0,0 +1,37 @@
import cv2
import numpy as np
# https://www.cnblogs.com/meikaiyuan/p/16805539.html
def read_image(path):
raw = cv2.imread(path)
# 设定颜色HSV范围假定为红色
color_lower = np.array([0, 0, 150])
color_upper = np.array([255, 255, 209])
# 将图像转化为HSV格式
hsv = cv2.cvtColor(raw, cv2.COLOR_BGR2HSV)
# 去除颜色范围外的其余颜色
mask = cv2.inRange(hsv, color_lower, color_upper)
cv2.imshow("mask", mask)
# 二值化操作
ret, binary = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY)
# 膨胀操作,因为是对线条进行提取定位,所以腐蚀可能会造成更大间隔的断点,将线条切断,因此仅做膨胀操作
kernel = np.ones((5, 5), np.uint8)
dilation = cv2.dilate(binary, kernel, iterations=1)
#
# img2 = cv2.bitwise_and(img, img, mask=mask)
# cv2.imshow('image', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 获取图像轮廓坐标其中contours为坐标值此处只检测外形轮廓
contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if __name__ == '__main__':
read_image("../data/004.png")