用OpenMV自动识别颜色序列


主控:OpenMV3 M7摄像头(STM32F765)

IDE:OPENMV官方IDE


我将Capstone期间做的代码上传到Gitee啦,后续还会陆续上传代码上去的,地址:Capstone,如果对你有帮助的话不妨点个⭐支持一下~


OpenMV需要识别颜色顺序的位置是第一个区域,区域中的物料摆放如下图所示


对于OpenMV识别颜色,很大一部分人都是采用了使用阈值调节,通过拍回来的照片修改阈值得到想要的区域,这种情况一般都会存在调试时间长,受光照影响大的限制。


通过分析本项目的颜色识别部分,小车到达粗加工区后开始颜色识别,识别到序列之后在开始抓取,车子在识别颜色时的位置是大致不变的,所以本文将阈值->颜色识别的流程转化为区域->颜色的识别,可以减少调试时间,但解决不了受光照影响的问题。


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


根据任务要求,物料颜色分别有红绿蓝三色,则对上图进行观察对比,可以发现红绿蓝三色均在球形的外端,有非明显的区别,比如红色的a值为正数蓝色的b值为负数绿色的a值为负数。因此可以根据这些特征筛选出所需颜色。


在实际运行过程中,我们将OpenMV的画面分成上下两部分,然后在每次运行到粗加工区位置时都运行一遍识别程序,避免因颜色识别不全卡在粗加工区。


在此处放出获取区域颜色的代码

function:GetColor


  1. 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


  1. 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上


程序的运行结果如下图,可以成功的识别得到颜色的序列



手上没有openmv,测试图就这一张



  1. <a href="https://www.cnblogs.com/dragonet-Z/p/16304191.html" class="p_n_p_prefix">» </a> 下一篇: <a href="https://www.cnblogs.com/dragonet-Z/p/16304191.html" data-featured-image="" title="发布于 2022-05-24 08:40">毕设(1)——机械臂DH建模</a>