光電智能垃圾分揀車 第八屆全國大學生光電設計競賽 賽題 2

1 競技重點:

大視場垃圾搜尋、識別、分類、搶運能力。

2 競賽說明:

設計一款光電智能垃圾分揀車,能夠從指定位置出發,快速搜尋垃圾,發現 垃圾後對垃圾識別分類,並根據垃圾類別揀送到指定的垃圾堆放地。按照規定時 間內準確分揀的數量確定比賽名次。

3.2.3 垃圾種類、數量、標識、擺放

3.2.3.1 垃圾種類

競賽用垃圾共 5 種,包括小號礦泉水瓶、7 號電池、一次性紙杯各 1 種,2 種不同形狀的物品。其中,2 種不同形狀的物品是橘子皮(尺寸大於 3 cm×3 cm, 形狀隨機)和 A4 紙紙團(形狀隨機)。礦泉水瓶體爲塑料材質、透明、無色或 淺藍色,瓶內無水,不保留瓶體包裝紙和瓶蓋,水瓶規格爲 330 ml~380 ml。一 次性紙杯的杯體主色爲白色,但可能存在其它顏色的花紋和圖案,杯內無水,紙 杯規格爲 200 ml~250 ml。

3.2.3.2 垃圾數量

比賽使用垃圾數量爲 20 個。其中,小號礦泉水瓶、7 號電池、一次性紙杯、 橘子皮、A4 紙紙團各 1 種,每種 4 個。

3.2.3.3 垃圾分類標識

競賽使用的垃圾分類標準見圖 2-2。
場地內的垃圾被分揀車揀拾後按類堆放 到圖 2-1 中的紅色線框標示的特定堆放區。
5 種競賽用垃圾、垃圾類別、垃圾堆放處顏色之間的對應關係爲:
礦泉水瓶 ——可回收垃圾 ——藍色;
7 號電池 ——有害垃圾 ——紅色;
一次性紙杯 ——其它垃圾 ——黑灰色;
橘子皮 ——廚餘垃圾 ——綠色;
A4 紙紙團 ——可回收垃圾 ——藍色;

圖像識別

識別的區域是: 藍色(面積更大)、紅色、綠色和黑灰色。
識別的物品是: 小號礦泉水瓶、7 號電池、一次性紙杯其中,橘子皮和A4 紙紙團(形狀隨機)。

圖像識別工具:

OpenMV
對OpenMV的介紹和使用,筆者在另一篇文章有較詳細說明:https://blog.csdn.net/smart_99/article/details/104505812

識別思路:

識別區域顏色

識別區域時,因爲區域面積較大,且四種顏色色差較大,我們可以很容易根據OpenMV裏LAB格式設置閾值,從而識別區分。
區分顏色即可。

這裏有三對閾值參數
1.亮度,範圍[0,100],從純黑到純白;2. a表示從紅色到綠色的範圍,[127,-128];3. b表示從黃色到藍色範圍,是[127,-128]

white_threshold_01 = ((95, 100, -18, 3, -8, 4));  #白色閾值
red_threshold_01 = ((35, 100, 41, 77, 24, 59));
green_threshold_01 = ((50, 100, -80, -20, 8, 20));
blue_threshold_01 = ((20, 100, -18, 18, -80, -30));

while(True):
        clock.tick() # Track elapsed milliseconds between snapshots().
        img = sensor.snapshot() # Take a picture and return the image.
        #  pixels_threshold=100, area_threshold=100
        blobs = img.find_blobs([red_threshold_01], pixels_threshold=100, area_threshold=100, merge=True, margin=10);      #紅色物塊
        blobs1 = img.find_blobs([green_threshold_01], pixels_threshold=100, area_threshold=100, merge=True, margin=10); #綠色物塊
        blobs2 = img.find_blobs([blue_threshold_01], pixels_threshold=100, area_threshold=100, merge=True, margin=10);   #藍色物塊
        cx=0;cy=0;cx1=0;cy1=0;cx2=0;cy2=0;
        if blobs:
            #如果找到了目標紅色
            max_b = find_max(blobs);
            # Draw a rect around the blob.
            img.draw_rectangle(max_b[0:4]) # rect
            #用矩形標記出目標顏色區域
            img.draw_cross(max_b[5], max_b[6]) # cx, cy
            img.draw_cross(160, 120) # 在中心點畫標記
            #在目標顏色區域的中心畫十字形標記
            cx=max_b[5];
            cy=max_b[6];
            img.draw_line((160,120,cx,cy), color=(127));
            #img.draw_string(160,120, "(%d, %d)"%(160,120), color=(127));
            img.draw_string(cx, cy, "(%d, %d)"%(cx,cy), color=(127));
blob = blobs[0]
img_ball_r= calc_radius(blob)

識別物體形狀

識別物塊就有很多難點:礦泉水瓶是透明的,7號電池很小,A4紙團是最大的干擾,形狀與橘子皮相似(都隨機),顏色與一次性水杯相似,都爲白色,如何將其區分開來是一大挑戰。橙黃色的橘子皮相對容易識別,而一次性紙杯和A4紙團就是最難以區分的了。

所以我們將從區分形狀下手。

以下是檢測圓形及顏色的OpenMV代碼。

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot().lens_corr(1.8)
    for c in img.find_circles(threshold = 3500, x_margin = 10, y_margin = 10, r_margin = 10,
            r_min = 2, r_max = 100, r_step = 2):
        area = (c.x()-c.r(), c.y()-c.r(), 2*c.r(), 2*c.r())
        #area爲識別到的圓的區域,即圓的外接矩形框
        statistics = img.get_statistics(roi=area)#像素顏色統計
        print(statistics)
        #(0,100,0,120,0,120)是紅色的閾值,所以當區域內的衆數(也就是最多的顏色),範圍在這個閾值內,就說明是紅色的圓。
        #l_mode(),a_mode(),b_mode()是L通道,A通道,B通道的衆數。
        if 0<statistics.l_mode()<100 and 0<statistics.a_mode()<127 and 0<statistics.b_mode()<127:#if the circle is red
            img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))#識別到的紅色圓形用紅色的圓框出來
        else:
            img.draw_rectangle(area, color = (255, 255, 255))
            #將非紅色的圓用白色的矩形框出來
    print("FPS %f" % clock.fps())

以下爲識別矩形的代碼:

# Find Rects Example
#
# 這個例子展示瞭如何使用april標籤代碼中的四元檢測代碼在圖像中找到矩形。 四元檢測算法以非常穩健的方式檢測矩形,並且比基於Hough變換的方法好得多。 例如,即使鏡頭失真導致這些矩形看起來彎曲,它仍然可以檢測到矩形。 圓角矩形是沒有問題的!
# (但是,這個代碼也會檢測小半徑的圓)...

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # grayscale is faster (160x120 max on OpenMV-M7)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()

    # 下面的`threshold`應設置爲足夠高的值,以濾除在圖像中檢測到的具有
    # 低邊緣幅度的噪聲矩形。最適用與背景形成鮮明對比的矩形。

    for r in img.find_rects(threshold = 10000):
        img.draw_rectangle(r.rect(), color = (255, 0, 0))
        for p in r.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))
        print(r)

    print("FPS %f" % clock.fps())

本文持續更新中,進度受特殊時期影響,歡迎留言交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章