用OpenMV自動識別顏色序列


用OpenMV自動識別顏色序列

新年假期過去啦~

主控:OpenMV3 M7攝像頭(STM32F765)
IDE:OPENMV官方IDE

我將Capstone期間做的代碼上傳到Gitee啦,后續還會陸續上傳代碼上去的,地址:Capstone,如果對你有幫助的話不妨點個⭐支持一下~

OpenMV需要識別顏色順序的位置是第一個區域,區域中的物料擺放如下圖所示
image

對於OpenMV識別顏色,很大一部分人都是采用了使用閾值調節,通過拍回來的照片修改閾值得到想要的區域,這種情況一般都會存在調試時間長,受光照影響大的限制。

通過分析本項目的顏色識別部分,小車到達粗加工區后開始顏色識別,識別到序列之后在開始抓取,車子在識別顏色時的位置是大致不變的,所以本文將閾值->顏色識別的流程轉化為區域->顏色的識別,可以減少調試時間,但解決不了受光照影響的問題。

OpenMV使用的是LAB色域,如下圖所示
image

根據任務要求,物料顏色分別有紅綠藍三色,則對上圖進行觀察對比,可以發現紅綠藍三色均在球形的外端,有非明顯的區別,比如紅色的a值為正數藍色的b值為負數綠色的a值為負數。因此可以根據這些特征篩選出所需顏色。

在實際運行過程中,我們將OpenMV的畫面分成上下兩部分,然后在每次運行到粗加工區位置時都運行一遍識別程序,避免因顏色識別不全卡在粗加工區。

在此處放出獲取區域顏色的代碼
function:GetColor

def GetColor(Rev_Num):
    global Left_x
    global Middle_x
    global Right_x
    global Left_y
    global Middle_y
    global Right_y
    global LeftMean_Shang
    global MiddleMean_Shang
    global RightMean_Shang
    global LeftMean_Xia
    global MiddleMean_Xia
    global RightMean_Xia
    if (Rev_Num == 1):
        #獲取左中右三個位置的X坐標和Y坐標
        Left_x = LeftROI_Shang[0] + (LeftROI_Shang[2] / 2)
        Middle_x = MiddleROI_Shang[0] + (MiddleROI_Shang[2] / 2)
        Right_x = RightROI_Shang[0] + (RightROI_Shang[2] / 2)
        Left_y = LeftROI_Shang[1] + (LeftROI_Shang[3] / 2)
        Middle_y = MiddleROI_Shang[1] + (MiddleROI_Shang[3] / 2)
        Right_y = RightROI_Shang[1] + (RightROI_Shang[3] / 2)
        for i in range(100):
            img = sensor.snapshot()
            img.draw_rectangle(LeftROI_Shang)
            img.draw_rectangle(MiddleROI_Shang)
            img.draw_rectangle(RightROI_Shang)
            img.draw_cross(int(Left_x), int(Left_y))
            img.draw_cross(int(Middle_x), int(Middle_y))
            img.draw_cross(int(Right_x), int(Right_y))
            Left_Stat = img.get_statistics(roi = LeftROI_Shang)
            Middle_Stat = img.get_statistics(roi = MiddleROI_Shang)
            Right_Stat = img.get_statistics(roi = RightROI_Shang)
            #獲取上層左側ROI的LAB均值
            LeftMean_Shang[0] = LeftMean_Shang[0] + (Left_Stat.l_mean() / 100)
            LeftMean_Shang[1] = LeftMean_Shang[1] + (Left_Stat.a_mean() / 100)
            LeftMean_Shang[2] = LeftMean_Shang[2] + (Left_Stat.b_mean() / 100)
            #獲取上層中間ROI的LAB均值
            MiddleMean_Shang[0] = MiddleMean_Shang[0] + (Middle_Stat.l_mean() / 100)
            MiddleMean_Shang[1] = MiddleMean_Shang[1] + (Middle_Stat.a_mean() / 100)
            MiddleMean_Shang[2] = MiddleMean_Shang[2] + (Middle_Stat.b_mean() / 100)
            #獲取上層右側ROI的LAB均值
            RightMean_Shang[0] = RightMean_Shang[0] + (Right_Stat.l_mean() / 100)
            RightMean_Shang[1] = RightMean_Shang[1] + (Right_Stat.a_mean() / 100)
            RightMean_Shang[2] = RightMean_Shang[2] + (Right_Stat.b_mean() / 100)
    elif (Rev_Num == 2):
        #獲取左中右三個位置的X坐標和Y坐標
        Left_x = LeftROI_Xia[0] + (LeftROI_Xia[2] / 2)
        Middle_x = MiddleROI_Xia[0] + (MiddleROI_Xia[2] / 2)
        Right_x = RightROI_Xia[0] + (RightROI_Xia[2] / 2)
        Left_y = LeftROI_Xia[1] + (LeftROI_Xia[3] / 2)
        Middle_y = MiddleROI_Xia[1] + (MiddleROI_Xia[3] / 2)
        Right_y = RightROI_Xia[1] + (RightROI_Xia[3] / 2)
        for i in range(100):
            img = sensor.snapshot()
            img.draw_rectangle(LeftROI_Xia)
            img.draw_rectangle(MiddleROI_Xia)
            img.draw_rectangle(RightROI_Xia)
            img.draw_cross(int(Left_x), int(Left_y))
            img.draw_cross(int(Middle_x), int(Middle_y))
            img.draw_cross(int(Right_x), int(Right_y))
            Left_Stat = img.get_statistics(roi = LeftROI_Xia)
            Middle_Stat = img.get_statistics(roi = MiddleROI_Xia)
            Right_Stat = img.get_statistics(roi = RightROI_Xia)
            #獲取下層左側ROI的LAB均值
            LeftMean_Xia[0] = LeftMean_Xia[0] + (Left_Stat.l_mean() / 100)
            LeftMean_Xia[1] = LeftMean_Xia[1] + (Left_Stat.a_mean() / 100)
            LeftMean_Xia[2] = LeftMean_Xia[2] + (Left_Stat.b_mean() / 100)
            #獲取下層中間ROI的LAB均值
            MiddleMean_Xia[0] = MiddleMean_Xia[0] + (Middle_Stat.l_mean() / 100)
            MiddleMean_Xia[1] = MiddleMean_Xia[1] + (Middle_Stat.a_mean() / 100)
            MiddleMean_Xia[2] = MiddleMean_Xia[2] + (Middle_Stat.b_mean() / 100)
            #獲取下層右側ROI的LAB均值
            RightMean_Xia[0] = RightMean_Xia[0] + (Right_Stat.l_mean() / 100)
            RightMean_Xia[1] = RightMean_Xia[1] + (Right_Stat.a_mean() / 100)
            RightMean_Xia[2] = RightMean_Xia[2] + (Right_Stat.b_mean() / 100)

簡單介紹一下函數,函數內容挺簡單的,將畫面中三個區域中的LAB閾值提出來做均分再相加,就得到了三個區域中L、A、B三個通道的顏色均值,后面再做對比就行

還有調試用的函數,這個函數是用來調試找到三個區域的
function:Get_ROI

def Get_ROI(Rev_Num):
    global Left_x
    global Middle_x
    global Right_x
    global Left_y
    global Middle_y
    global Right_y
    if (Rev_Num == 1):
        #裁剪窗口
        sensor.set_windowing(ROI_Shang)
        #獲取左中右三個位置的X坐標和Y坐標
        Left_x = LeftROI_Shang[0] + (LeftROI_Shang[2] / 2)
        Middle_x = MiddleROI_Shang[0] + (MiddleROI_Shang[2] / 2)
        Right_x = RightROI_Shang[0] + (RightROI_Shang[2] / 2)
        Left_y = LeftROI_Shang[1] + (LeftROI_Shang[3] / 2)
        Middle_y = MiddleROI_Shang[1] + (MiddleROI_Shang[3] / 2)
        Right_y = RightROI_Shang[1] + (RightROI_Shang[3] / 2)
        img = sensor.snapshot()
        img.draw_rectangle(LeftROI_Shang)
        img.draw_rectangle(MiddleROI_Shang)
        img.draw_rectangle(RightROI_Shang)
        img.draw_cross(int(Left_x), int(Left_y))
        img.draw_cross(int(Middle_x), int(Middle_y))
        img.draw_cross(int(Right_x), int(Right_y))
    elif (Rev_Num == 2):
        #裁剪窗口
        #sensor.set_windowing(ROI_Xia)
        #獲取左中右三個位置的X坐標和Y坐標
        Left_x = LeftROI_Xia[0] + (LeftROI_Xia[2] / 2)
        Middle_x = MiddleROI_Xia[0] + (MiddleROI_Xia[2] / 2)
        Right_x = RightROI_Xia[0] + (RightROI_Xia[2] / 2)
        Left_y = LeftROI_Xia[1] + (LeftROI_Xia[3] / 2)
        Middle_y = MiddleROI_Xia[1] + (MiddleROI_Xia[3] / 2)
        Right_y = RightROI_Xia[1] + (RightROI_Xia[3] / 2)
        img = sensor.snapshot()
        img.draw_rectangle(LeftROI_Xia)
        img.draw_rectangle(MiddleROI_Xia)
        img.draw_rectangle(RightROI_Xia)
        img.draw_cross(int(Left_x), int(Left_y))
        img.draw_cross(int(Middle_x), int(Middle_y))
        img.draw_cross(int(Right_x), int(Right_y))

完整的代碼發在了Gitee上

程序的運行結果如下圖,可以成功的識別得到顏色的序列
image

手上沒有openmv,測試圖就這一張


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM