如何对生产线上的物品进行检测并统计?

253 阅读3分钟

前言

  最近几天被项目折腾的头痛,经过一顿收拾,理清楚了解决思路。在此特分享给大家(回想起来,完全不难,为什么当初就是想不明白呢?)

设计分析

项目需求

  现有5种颜色(颜色记为:1,2,3,4,5)的物品需要在传送带上过闸机进行检测(这里物品颜色检测可参考使用K-means在对图像进行目标颜色检测)并统计各物品的检测的总数。

已知条件

  这里需要注意的是传送带是非目标物体的颜色(这里我们记为:0),物品之间的通过为顺序且每个物品通过时有一定的间隙:

  1. 即传送带是可以视作匀速运行;
  2. 物品在传送带上匀速前进;
  3. 一次只通过一个物品;
  4. 物品颜色与传送带颜色相异;
  5. 每种物品的颜色相异;
  6. 视频画面中不会存在两个及以上的物品同时存在;
  7. 已经可以完成目标的颜色检测(return color_num)

剖析

  根据上述的已知条件进行分析我们需要注意以下问题:物品通过视频画面的时候会持续一段时间(从进入到离开),这个过程中检测函数是一直在return color_num,在后续我们进行统计该物品的时候仅需记录一次(color_lab + 1)。

  另外分析检测的过程可以得到除上述情景外还有如下情景:当检测出第一个物品和第二个物品之间必然会有一个空档期,这个空档期检测的颜色为传送带的颜色(记为:0)。 那么可以按如下逻辑进行操作:

          条件判断流程图.jpg

异常分析

  如上逻辑流程图所示是建立在检测物品颜色无误的情况下,然而在实际生产中会出现各种各样的情况是需要我们考虑到的。例如在检测颜色标签为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

结语

今天就先写到这里,如对本文感兴趣的话,欢迎大家三连关注。如对本文的异常分析有建议,还望各路大神赐教! 持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情