前言
说起目标检测大家往往想到的是“有监督”检测,这里例如(ssd\yolo等模型);然而还有另外的一种思路供我们思考使用:聚类(K-means)。在本文中我提供一个例子讲解下聚类思想在目标检测中的应用并简要分析“有监督”与“无监督”模型之间的差异。
需求表述
例如有如下场景:在一条传送带上传送着红色、绿色、黄色和黑色的电缆圈,现在在传送带上进行传送,每次只过一卷电缆,需要检测出通过传送带指定位置的电缆颜色为后续分揽件做准备。
根据上述的需求对现有设备进行统计:
- 深绿色传送带一条
- 闸机一套
- 工业相机一台
- PC工控机一台
分析
业务逻辑
对上述的需求部分进行分析,可以清晰的知道在传送带上的电缆是单卷进行运送,电缆颜色也不同于传送带的颜色,数据采集的设备(工业相机也具备了)。这样我们可以做如下设计:在闸机前安装工业相机(下面简称相机),使相机画面仅能容下传送带上的物品(这里特指电缆),在检测到电缆的颜色后把信息传递给闸机。
算法逻辑
主要目标是对传送带上的电缆的颜色进行识别,这里我们考虑到电缆的颜色只有四种且电缆颜色与传送带的颜色也不一样,那么可以对传送带上的电缆图像进行颜色聚类,通过颜色聚类我们可以得到两种颜色:传送带的背景色与电缆的颜色,我们在聚类的结果中将背景颜色剔除掉后那么剩下的就是电缆的颜色了。
有/无监督
K-means是非常典型的无监督模型的范例,通过上述的业务逻辑与算法逻辑分析来看,避免了有监督模型的繁琐的数据采集与标注,使用无监督模型的优点在这里显现出来了:不需要大量的数据进行训练,仅需要对业务场景以及业务逻辑的详细清晰的判研即可实现项目需求。
结束
这里为大家带来了一个解决检测目标颜色的可执行方案,希望对大家有帮助。
demo
main.py
from sklearn.cluster import KMeans
import cv2
import numpy as np
import color
def centroid_histogram(clt):
numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
hist, _ = np.histogram(clt.labels_, bins=numLabels)
hist = hist.astype("float")
hist /= hist.sum()
return hist
if __name__ == '__main__':
image = cv2.imread("126.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = image.reshape((image.shape[0] * image.shape[1], 3))
clt = KMeans(n_clusters=2)
clt.fit(image)
hist = centroid_histogram(clt)
LabelRgb = clt.cluster_centers_
for lab1, lab2, lab3 in LabelRgb:
LabR, LabG, LabB = int(lab1), int(lab2), int(lab3)
Color = color.Is_Ture(LabR, LabG, LabB)
if Color is not None:
print(Color)
color.py
def in_range(num, MaxNum, MinMun=0):
return MaxNum <= num <= MinMun if MinMun >= MaxNum else MinMun <= num <= MaxNum
def Is_Ture(LabR, LabG, LabB):
Color = None
"""
检测输入的电缆颜色RGB是否满足标准,当满足标准的时候输出字符
"""
Yellow_R_min, Yellow_R_max, Yellow_G_min, Yellow_G_max, Yellow_B_min, Yellow_B_max = 130, 140, 110, 120, 50, 60
Is_Yellow_R = in_range(LabR, Yellow_R_max, Yellow_R_min)
Is_Yellow_G = in_range(LabG, Yellow_G_max, Yellow_G_min)
Is_Yellow_B = in_range(LabB, Yellow_B_max, Yellow_B_min)
if Is_Yellow_R is True and Is_Yellow_G is True and Is_Yellow_B is True:
Color = "黄色"
Red_R_min, Red_R_max, Red_G_min, Red_G_max, Red_B_min, Red_B_max = 50, 60, 50, 60, 50, 60
Is_Red_R = in_range(LabR, Red_R_min, Red_R_max)
Is_Red_G = in_range(LabG, Red_G_min, Red_G_max)
Is_Red_B = in_range(LabB, Red_B_min, Red_B_max)
if Is_Red_R is True and Is_Red_G is True and Is_Red_B is True:
Color = "红色"
Green_R_min, Green_R_max, Green_G_min, Green_G_max, Green_B_min, Green_B_max = 30, 40, 30, 40, 30, 40
Is_Green_R = in_range(LabR, Green_R_min, Green_R_max)
Is_Green_G = in_range(LabG, Green_G_max, Green_G_min)
Is_Green_B = in_range(LabB, Green_B_max, Green_B_min)
if Is_Green_R is True and Is_Green_G is True and Is_Green_B is True:
Color = "绿色"
Blue_R_min, Blue_R_max, Blue_G_min, Blue_G_max, Blue_B_min, Blue_B_max = 10, 20, 10, 20, 10, 20
Is_Blue_R = in_range(LabR, Blue_R_min, Blue_R_max)
Is_Blue_G = in_range(LabG, Blue_G_min, Blue_G_max)
Is_Blue_B = in_range(LabB, Blue_B_min, Blue_B_max)
if Is_Blue_R is True and Is_Blue_G is True and Is_Blue_B is True:
Color = "蓝色"
Black_R_min, Black_R_max, Black_G_min, Black_G_max, Black_B_min, Black_B_max = 0, 10, 0, 10, 0, 10
Is_Black_R = in_range(LabR, Black_R_max, Black_R_min)
Is_Black_G = in_range(LabG, Black_G_max, Black_G_min)
Is_Black_B = in_range(LabB, Black_B_max, Black_B_min)
if Is_Black_R is True and Is_Black_G is True and Is_Black_B is True:
Color = "黑色"
return Color
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情