1 #实现颜色识别与标记 2 #实现原理:LAB颜色空间与欧几里得距离 3 4 from scipy.spatial import distance as dist 5 from collections import OrderedDict 6 import numpy as np 7 import cv2 8 9 class ColorLabeler: 10 def __init__(self): 11 #初始化颜色词典 12 colors = OrderedDict({ 13 "红色":(255, 0, 0), 14 "绿色":(0, 255, 0), 15 "蓝色":(0, 0, 255), 16 "黑色":(0, 0, 0), 17 "白色":(255, 255, 255) }) 18 19 #初始化属性(变量) 20 #为lab图像分配空间 21 #为颜色分配列表 22 self.lab = np.zeros((len(colors), 1, 3), dtype="uint8") 23 self.colorName =[] 24 25 #枚举,以词典长度为循环次数-->更新数字阵列与色名列表 26 #将rgb值赋予lab空间 27 #将name变量的值一次次加入列表中(此处name还未分配值) 28 for(i, (name, rgb)) in enumerate(colors.items()): 29 self.lab[i] = rgb 30 self.colorName.append(name) 31 32 #颜色空间转换 33 self.lab = cv2.cvtColor(self.lab,cv2.COLOR_RGB2LAB) 34 # 为什么选择LAB空间?-->其中与欧几里得距离的关系帮助我们标记颜色 35 36 # 将选择最小化欧几里德距离的已知颜色作为颜色标识。 37 def label(self, image, c): 38 #标志mask,绘制轮廓 shape属性用来查看图像结构,返回行和列 39 mask = np.zeros(image.shape[:2], dtype="uint8") 40 cv2.drawContours(mask, [c], -1, 255, -1) 41 mask = cv2.erode(mask, None, iterations=2)#腐蚀 42 mean = cv2.mean(image, mask=mask)[:3]#均值 43 44 #初始化最小距离 45 minDist = (np.inf, None)#np.inf表示无穷大的正数 46 47 # 遍历已知的LAB颜色值 48 for (i, row) in enumerate(self.lab): 49 # 计算当前l*a*b*颜色值与图像平均值之间的距离 50 d = dist.euclidean(row[0], mean) 51 52 # 如果当前的距离小于最小的距离,则进行变量更新 53 if d < minDist[0]: 54 minDist = (d, i) 55 56 # 返回最小距离对应的颜色值 57 return self.colorNames[minDist[1]]
效果图: