前言
最近几天被项目折腾的头痛,经过一顿收拾,理清楚了解决思路。在此特分享给大家(回想起来,完全不难,为什么当初就是想不明白呢?)
设计分析
项目需求
现有5种颜色(颜色记为:1,2,3,4,5)的物品需要在传送带上过闸机进行检测(这里物品颜色检测可参考使用K-means在对图像进行目标颜色检测)并统计各物品的检测的总数。
已知条件
这里需要注意的是传送带是非目标物体的颜色(这里我们记为:0),物品之间的通过为顺序且每个物品通过时有一定的间隙:
- 即传送带是可以视作匀速运行;
- 物品在传送带上匀速前进;
- 一次只通过一个物品;
- 物品颜色与传送带颜色相异;
- 每种物品的颜色相异;
- 视频画面中不会存在两个及以上的物品同时存在;
- 已经可以完成目标的颜色检测(return color_num)
剖析
根据上述的已知条件进行分析我们需要注意以下问题:物品通过视频画面的时候会持续一段时间(从进入到离开),这个过程中检测函数是一直在return color_num,在后续我们进行统计该物品的时候仅需记录一次(color_lab + 1)。
另外分析检测的过程可以得到除上述情景外还有如下情景:当检测出第一个物品和第二个物品之间必然会有一个空档期,这个空档期检测的颜色为传送带的颜色(记为:0)。 那么可以按如下逻辑进行操作:
异常分析
如上逻辑流程图所示是建立在检测物品颜色无误的情况下,然而在实际生产中会出现各种各样的情况是需要我们考虑到的。例如在检测颜色标签为1的物品时,会出现持续return color_num 过程中,某一帧检测存在失误,没有检测到,这个时候的color_num = 0 (但也就这一个数字),后续仍然return color_num=1 ,那么按照上述的逻辑,此时的这个物品我们检测统计了两次,相当于多统计了一次。
这个时候我们就需要建立剔除异常值的机制,对连续 return color_num 的数字是相同数字的时候,中途出现的某个不相同的数字进行剔除;当然这个不相同的数字出现的地方可能在首位,也可能在末位。
demo
对上述流程进行简化替代,有如下代码逻辑:a = random.randint(0, 100)代表检测到的目标类别数
import random import cv2 RawNum = 0 # 原始数据 # 各类别的总数 Lab1 = 0 Lab2 = 0 Lab3 = 0 Lab4 = 0 Lab5 = 0 while 1: frame = cv2.imread("111.jpg") a = random.randint(0, 100) if a != RawNum: if a == 1: RawNum = a Lab1 += 1 elif a == 2: RawNum = a Lab2 += 1 elif a == 3: RawNum = a Lab3 += 1 elif a == 4: RawNum = a Lab4 += 1 elif a == 5: RawNum = a Lab5 += 1 else: RawNum = a Text1 = "Yellow-Num:%s " % Lab1 Text2 = "Red-Num:%s " % Lab2 Text3 = "Green-Num:%s " % Lab3 Text4 = "black-Num:%s " % Lab4 Text5 = "blue-Num:%s " % Lab5 cv2.putText(frame, Text1, (5, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) cv2.putText(frame, Text2, (5, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) cv2.putText(frame, Text3, (5, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) cv2.putText(frame, Text4, (5, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) cv2.putText(frame, Text5, (5, 100), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) cv2.imshow("video", frame) key = cv2.waitKey(1) & 0xFF if key == 27: break