import numpy as np
import collections
# 定义字典存放颜色分量上下限
# 例如:{颜色: [min分量, max分量]}
# {'red': [array([160, 43, 46]), array([179, 255, 255])]}
def getColorList():
dict = collections.defaultdict(list)
# 黑色
lower_black = np.array([0, 0, 0])
upper_black = np.array([180, 255, 46])
color_list = []
color_list.append(lower_black)
color_list.append(upper_black)
dict['black'] = color_list
#灰色
lower_gray = np.array([0, 0, 46])
upper_gray = np.array([180, 43, 220])
color_list = []
color_list.append(lower_gray)
color_list.append(upper_gray)
dict['gray']=color_list
# 白色
lower_white = np.array([0, 0, 221])
upper_white = np.array([180, 30, 255])
color_list = []
color_list.append(lower_white)
color_list.append(upper_white)
dict['white'] = color_list
# 红色
lower_red = np.array([156, 43, 46])
upper_red = np.array([180, 255, 255])
color_list = []
color_list.append(lower_red)
color_list.append(upper_red)
dict['red'] = color_list
# 红色2
lower_red = np.array([0, 43, 46])
upper_red = np.array([10, 255, 255])
color_list = []
color_list.append(lower_red)
color_list.append(upper_red)
dict['red2'] = color_list
# 橙色
lower_orange = np.array([11, 43, 46])
upper_orange = np.array([25, 255, 255])
color_list = []
color_list.append(lower_orange)
color_list.append(upper_orange)
dict['orange'] = color_list
# 黄色
lower_yellow = np.array([26, 43, 46])
upper_yellow = np.array([34, 255, 255])
color_list = []
color_list.append(lower_yellow)
color_list.append(upper_yellow)
dict['yellow'] = color_list
# 绿色
lower_green = np.array([35, 43, 46])
upper_green = np.array([77, 255, 255])
color_list = []
color_list.append(lower_green)
color_list.append(upper_green)
dict['green'] = color_list
# 青色
lower_cyan = np.array([78, 43, 46])
upper_cyan = np.array([99, 255, 255])
color_list = []
color_list.append(lower_cyan)
color_list.append(upper_cyan)
dict['cyan'] = color_list
# 蓝色
lower_blue = np.array([100, 43, 46])
upper_blue = np.array([124, 255, 255])
color_list = []
color_list.append(lower_blue)
color_list.append(upper_blue)
dict['blue'] = color_list
# 紫色
lower_purple = np.array([125, 43, 46])
upper_purple = np.array([155, 255, 255])
color_list = []
color_list.append(lower_purple)
color_list.append(upper_purple)
dict['purple'] = color_list
return dict
import cv2
import numpy as np
#
# filename = './8.png'
#
#
# # 处理图片
# def get_color(frame):
# #print('go in get_color')
# hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# maxsum = -100
# color = None
# color_dict = getColorList()
# for d in color_dict:
# #print(color_dict[d][0], color_dict[d][1], d)
# mask = cv2.inRange(hsv, color_dict[d][0], color_dict[d][1]) # 将高于或者低于该颜色的hsv都设置成0
#
# cv2.imwrite(d + '.jpg', mask)
# # binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]
# binary = cv2.dilate(mask, None, iterations=2)
# cnts, hiera = cv2.findContours(binary.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# sum = 0
# for c in cnts:
# sum += cv2.contourArea(c) # 计算所有轮廓的面积
# if sum > maxsum:
# maxsum = sum
# color = d
#
# return color
#
#
# if __name__ == '__main__':
# frame = cv2.imread(filename)
# #print(get_color(frame))
def rgb2hsv(r, g, b):
r, g, b = r/255.0, g/255.0, b/255.0
mx = max(r, g, b)
mn = min(r, g, b)
m = mx-mn
if mx == mn:
h = 0
elif mx == r:
if g >= b:
h = ((g-b)/m)*60
else:
h = ((g-b)/m)*60 + 360
elif mx == g:
h = ((b-r)/m)*60 + 120
elif mx == b:
h = ((r-g)/m)*60 + 240
if mx == 0:
s = 0
else:
s = m/mx
v = mx
H = h / 2
S = s * 255.0
V = v * 255.0
return H, S, V
import ctypes
from ctypes import wintypes
WH_MOUSE_LL = 14 # 低级鼠标钩子常量
WM_LBUTTONDOWN = 0x0201 # 左键按下事件常量
WM_LBUTTONUP = 0x0202 # 左键回弹事件常量
HC_ACTION = 0
user32 = ctypes.WinDLL('user32', use_last_error=True)
gdi32 = ctypes.WinDLL('gdi32', use_last_error=True)
# 定义一些wintypes中没有的类型
ULONG_PTR = wintypes.WPARAM
LRESULT = wintypes.LPARAM
HOOKPROC = ctypes.WINFUNCTYPE(LRESULT, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM)
LPMSG = ctypes.POINTER(wintypes.MSG)
class MSLLHOOKSTRUCT(ctypes.Structure):
_fields_ = (
('pt', wintypes.POINT),
('mouseData', wintypes.DWORD),
('flags', wintypes.DWORD),
('time', wintypes.DWORD),
('dwExtraInfo', ULONG_PTR),
)
'''
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644986
LowLevelMouseProc回调函数原型:
LRESULT CALLBACK LowLevelMouseProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
'''
LowLevelMouseProc = ctypes.WINFUNCTYPE(LRESULT, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM)
# 注册user32中的各API参数和返回值
user32.SetWindowsHookExW.restype = wintypes.HHOOK
user32.SetWindowsHookExW.argtypes = (ctypes.c_int, HOOKPROC, wintypes.HINSTANCE, wintypes.DWORD)
user32.CallNextHookEx.restype = LRESULT
user32.CallNextHookEx.argtypes = (wintypes.HHOOK, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM)
user32.GetMessageW.restype = wintypes.BOOL
user32.GetMessageW.argtypes = (LPMSG, wintypes.HWND, wintypes.UINT, wintypes.UINT)
user32.TranslateMessage.restype = wintypes.BOOL
user32.TranslateMessage.argtypes = (LPMSG,)
user32.DispatchMessageW.restype = LRESULT
user32.DispatchMessageW.argtypes = (LPMSG,)
user32.GetDC.restype = wintypes.HDC
user32.GetDC.argtypes = (wintypes.HWND,)
user32.ReleaseDC.restype = ctypes.c_int
user32.ReleaseDC.argtypes = (wintypes.HWND, wintypes.HDC)
# 注册GetPixel
gdi32.GetPixel.restype = wintypes.COLORREF
gdi32.GetPixel.argtypes = (wintypes.HDC, ctypes.c_int, ctypes.c_int)
# 鼠标事件回调函数, wParam是事件类型,lParam是一个MSLLHOOKSTRUCT的结构体,其中包括鼠标坐标等信息
@LowLevelMouseProc
def callback_func(nCode, wParam, lParam):
if nCode == HC_ACTION:
if wParam == WM_LBUTTONDOWN: # 左键按下
# 解析鼠标坐标
ms_ll_msg = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT))[0]
# 获取对应点像素值
hdc = user32.GetDC(None)
x, y = ms_ll_msg.pt.x, ms_ll_msg.pt.y
color = gdi32.GetPixel(hdc, x, y)
r = color & 0xFF
g = (color >> 2) & 0xFF
b = (color >> 4) & 0xFF
# #print('coord=(%d,%d), color=#%02X%02X%02X' % (x, y, r, g, b))
# #print(rgb2hsv(195, 206, 216))
h, s, v = rgb2hsv(r, g, b)
color_dict = getColorList()
for d in color_dict:
# #print(color_dict[d][0], color_dict[d][1], d)
if h > color_dict[d][0][0] and h < color_dict[d][1][0] and s > color_dict[d][0][1] and s < \
color_dict[d][1][1] and v > color_dict[d][0][2] and v < color_dict[d][1][2]:
print(h, s, v, d)
user32.ReleaseDC(None, hdc)
return user32.CallNextHookEx(None, nCode, wParam, lParam)
# Windows消息循环
def event_loop():
msg = wintypes.MSG()
while True:
bRet = user32.GetMessageW(ctypes.byref(msg), None, 0, 0)
if bRet == 0: # WM_QUIT消息
#print('bye')
exit(0)
elif bRet == -1: # 错误
#print('an error happened')
exit(-1)
else:
user32.TranslateMessage(ctypes.byref(msg))
user32.DispatchMessageW(ctypes.byref(msg))
if __name__ == '__main__':
# 注册鼠标钩子
hMouseHook = user32.SetWindowsHookExW(WH_MOUSE_LL, callback_func, None, 0)
event_loop()