莱莱 发表于 2025-3-4 20:31:19

工创视觉——Openmv(开源)



目次
前言
一、结果展示
二、完整代码展示
三、关键词
前言

各位小伙伴大家好,今天我来分享一下我所利用的工创视觉代码。openmv做视觉是非常方便的,因为他有各种集成好的API,功能都已经封装好了,我们要利用什么功能就直接调用对应的API就可以了,并且只要我们了解API的参数的含义,就可以调解到我们想要的结果(openmv官网有对API参数的表明 )。openmv对于视觉小白们来说,照旧容易上手的。下面我就利用openmv来实现工创视觉任务。本人学识尚浅,如有不对的地方,还望各位大佬批评指正,谢谢。
阅读保举:
有一些底子的小伙伴们可以先大要看一遍代码,然后在继承任意看看本人的浅见。
没有底子或者没了解过openmv的小伙伴。可以直接利用我提供的代码去运行,整体代码我也调节测试过了。
一、结果展示

色环
https://i-blog.csdnimg.cn/direct/e871bc7f86914d61bcf8b8677975405e.png

https://i-blog.csdnimg.cn/direct/64ec792d972a4b758192cfa70de2f26c.png



二、完整代码展示

在代码中我已经标注了详细的解释,假如另有不理解的参数,可以去openmv的文档看一下。
#视觉部分代码
#整体以状态机方式运行

import sensor, image
importtime,json
import struct
from machine import UART
from pyb import UART
import pyb


uart=UART(3,9600)   #初始化串口3



#状态机初始状态
flag=0x02

ACK=0x00

#默认为0x00无色,0x01为红色,0x02为蓝色,0x03为绿色
colour=0x01

#工作变量次数
ACK_num=0


#发送数据包
def send_data(x,y):

    #包头 数据位 状态机状态 目标级别 x坐标 y坐标 包尾
    UART_Date=bytearray([
                        0XFF,
                        0x04,
                        flag,
                        colour,
                        x,
                        y,
                        0XFE])
    print(UART_Date)
    uart.write(UART_TXDATA)


#应答数据包
def send_ACK():

    #包头 数据位 应答位 包尾
    UART_Date=bytearray([
                        0XFF,
                        0x01,
                        0x11,
                        0XFE])
    print(UART_Date)
    uart.write(UART_TXDATA)

#接收数据包
def RX_date():

    if len(data) >= 5:
      if data == 0x00 and data == 0x02 and data==0x11:
            data1 = data
            data2 = data
            print("数据1:", data1, "数据2:", data2)
      else:
            data1=0x00
            data2=0x00
            print("数据格式错误")
    else:
      data1=0x00
      data2=0x00
      print("接收到的数据长度不足")


sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.set_auto_whitebal(False)
sensor.skip_frames(30)
sensor.set_auto_gain(False)



#色环阈值#红、蓝、绿
ring_colour=[(40, 71, 11, 40, -1, 69),

                (28, 62, -72, 20, -81, -22),

                (56, 77, -53, -18, -72, 33)]



Binarzation=[(100,255)]#二值化阈值





while(True):


    #图像帧
    img = sensor.snapshot()




    #二维码查找部分
    if flag==0x00:

      #在二维码部分要关闭自动白平衡部分
      #sensor.set_auto_whitebal(False)
      #桶形畸变,调节下面这个函数参数大小即可
      img.lens_corr(1.8)
      #寻找二维码
      for code in img.find_qrcodes():
            #打印二维码信息
            #code数组说明:0为x坐标,1为y坐标,2像素宽,3像素高,4二维码内容
            print(code)




            #串口发送部分(hex格式为准)
            UART_TXDATA=bytearray(,code,code,code,0XFE])
            uart.write(UART_TXDATA)


            #等待下位机确认信息并发送ACK
            if uart.any():
                ACK=uart.read()

            #状态机置1
            if ACK==0x11:
                ACK=0x00
                flag=1



    #物流识别拿取部分
    #后期还要调节最小像素大小threshold,根据摄像头高度调节



    #货物颜色阈值
    #(30, 57, 25, 54, 10, 42)红色机器阈值
    #(0, 57, -128, 53, -128, -35)蓝色机器阈值
    #(59, 87, -73, -31, -128, 62)绿色机器阈值



    if flag==0x01:

      #降低图像分辨率避免openmv物理空间栈不足
      sensor.reset()
      sensor.set_pixformat(sensor.RGB565)
      sensor.set_framesize(sensor.QQVGA)
      sensor.skip_frames(time = 2000)
      #关闭摄像头自动增益
      sensor.set_auto_gain(False)
      #关闭自动白平衡
      sensor.set_auto_whitebal(False)
      clock = time.clock()


      #一次拿取3次物品,应答3次就退出当前状态

      while(True):

            #图像帧
            img = sensor.snapshot()




            #红部分
            if colour==0x01:

                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)
                  #阈值调节
                  if 30<statistics.l_mode()<57 and 25<statistics.a_mode()<54 and 10<statistics.b_mode()<42:
                        #白色的圆框出来
                        img.draw_circle(c.x(), c.y(), c.r(), color = (255, 255, 255))
                        #打印坐标信息
                        print(c.x(),c.y())


                #打印运行帧率
                print("FPS %f" % clock.fps())



            #蓝部分
            if colour==0x02:

                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)
                  #阈值调节
                  if 0<statistics.l_mode()<57 and -128<statistics.a_mode()<53 and -128<statistics.b_mode()<-35:
                        #白色的圆框出来
                        img.draw_circle(c.x(), c.y(), c.r(), color = (255, 255, 255))
                        #打印坐标信息
                        print(c.x(),c.y())


                #打印运行帧率
                print("FPS %f" % clock.fps())


            #绿部分
            if colour==0x03:

                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)
                  #阈值调节
                  if 59<statistics.l_mode()<87 and -73<statistics.a_mode()<31 and -128<statistics.b_mode()<62:
                        #白色的圆框出来
                        img.draw_circle(c.x(), c.y(), c.r(), color = (255, 255, 255))

                        #打印坐标信息
                        print(c.x(),c.y())



                #打印运行帧率
                print("FPS %f" % clock.fps())




            if ACK_num==3:
                ACK_num=0
                flag=2
                break





    if flag==0x02:


      #一共识别三次色环

      while True:

            #图像帧
            img = sensor.snapshot()

            #红部分
            if colour==0x01:
                img.binary(])#红色阈值,图像二值化
                #滤波器的直径是2,0.1较小的值意味着将只模糊与中心像素颜色相近的像素,1滤波器在颜色空间中的敏感度
                img.bilateral(2, color_sigma=0.1, space_sigma=1)#双边滤波
                #卷积核越大运算量越大
                img.dilate(5)#卷积核为5x5的膨胀


                #graythreshold颜色阈值,pixels_threshold的最大像素数量,area_threashold的最小像素数量,merge允许相近图像重叠合并
                #返回一个符合图像对象的列表
                blobs=img.find_blobs(Binarzation,pixels_threshold=2025,area_threashold=1600,merge=True)
                #判断满足要求的对象是否只有一个
                if len(blobs)==1:

                  #比较色块大小,取最大
                  Blobmax=blobs
                  for blob in blobs:
                        if blob.pixels() > Blobmax.pixels():
                            Blobmax=blob

                        else:

                            Blobmax=Blobmax



                  #返回边沿信息并画框
                  img.draw_rectangle(Blobmax.rect())
                  #打印中心坐标S
                  print(Blobmax.cx(),Blobmax.cx())


            #蓝部分
            if colour==0x02:
                img.binary(])#蓝色阈值,图像二值化
                #滤波器的直径是2,0.1较小的值意味着将只模糊与中心像素颜色相近的像素,1滤波器在颜色空间中的敏感度
                img.bilateral(2, color_sigma=0.1, space_sigma=1)#双边滤波
                #卷积核越大运算量越大
                img.dilate(5)#卷积核为5x5的膨胀


                #graythreshold颜色阈值,pixels_threshold的最大像素数量,area_threashold的最小像素数量,merge允许相近图像重叠合并
                #返回一个符合图像对象的列表
                blobs=img.find_blobs(Binarzation,pixels_threshold=2025,area_threashold=1600,merge=True)
                #判断满足要求的对象是否只有一个
                if len(blobs)==1:

                  #比较色块大小,取最大
                  Blobmax=blobs
                  for blob in blobs:
                        if blob.pixels() > Blobmax.pixels():
                            Blobmax=blob

                        else:

                            Blobmax=Blobmax



                  #返回边沿信息并画框
                  img.draw_rectangle(Blobmax.rect())
                  #打印中心坐标S
                  print(Blobmax.cx(),Blobmax.cx())


            #绿部分
            if colour==0x03:
                img.binary(])#绿色阈值
                #滤波器的直径是2,0.1较小的值意味着将只模糊与中心像素颜色相近的像素,1滤波器在颜色空间中的敏感度
                img.bilateral(2, color_sigma=0.1, space_sigma=1)#双边滤波
                #卷积核越大运算量越大
                img.dilate(5)#卷积核为5x5的膨胀


                #graythreshold二值化阈值,pixels_threshold的最大像素数量,area_threashold的最小像素数量,merge允许相近图像重叠合并
                #返回一个符合图像对象的列表
                blobs=img.find_blobs(Binarzation,pixels_threshold=2025,area_threashold=1600,merge=True)
                #判断满足要求的对象是否只有一个
                if len(blobs)==1:

                  #比较色块大小,取最大
                  Blobmax=blobs
                  for blob in blobs:
                        if blob.pixels() > Blobmax.pixels():
                            Blobmax=blob

                        else:

                            Blobmax=Blobmax



                  #返回边沿信息并画框
                  img.draw_rectangle(Blobmax.rect())
                  #打印中心坐标S
                  print(Blobmax.cx(),Blobmax.cx()) 三、关键词

帧率

实在假如有利用openmv做过一些小玩具或者项目标小伙伴们应该都发现了一个小题目,那就是他的帧率。每次当我们编写步调复杂了一些,他的帧率就会特别低。帧率低代表的他的图像流也会很小,普通一点就是机器反应变慢了。那我们要是想进步机器反应的速度,那我们可以优化我们的代码,比如淘汰数据空间栈,减小图像处置惩罚的卷积核大小,减小运算量等等。都是是可以进步帧率的办法。
例如(减小图像处置惩罚卷积核大小):
https://i-blog.csdnimg.cn/direct/739ca23590374891ba61a99b0d2fabc3.png
在这个代码里面我利用的卷积核大小为5X5的,如许他的结果就会好一些,不过同时也会低落帧率的大小。有利有弊,假如你的openmv提示你的空间栈不足,你可以把卷积核大小改成3X3的,如许应该就可以了。
阈值

颜色阈值设置,我们可以利用openmv的阈值编辑器来调节出符合的结果。调节技巧,可以在我已经调节好的阈值上面举行微调,正负3的调节。
例如(每次调解阈值都要上电检测比对结果):
要调节红色物体的阈值
调节前参考标准:(30, 57, 25, 54, 10, 42)
调节过程:(33, 60, 28, 57, 13, 45)
发现结果变好,那就再次增加
调节过程:(36, 63, 31, 60, 16, 48)
结果开始变差
那就知道阈值结果差不多在(33-36, 60-63, 28-31, 57-60, 13-16, 45-48)之间。
https://i-blog.csdnimg.cn/direct/6377c8c79ea24aaba6d9262581aca230.png
色环

实在这个色环一开始我利用的处置惩罚办法和物资的处置惩罚办法一样都是利用霍尔圆API直接检测的,但是我发现结果不行(网络模型练习应该也是不可以的)。以是我跑到网上去拜读了几篇处置惩罚的办法,就有了现在简洁的办法。
色环检测思绪:
图像帧的颜色筛选并二值化——再举行简朴的滤波——再举行膨胀(连接每个小色环,使其为整体)——再利用API返回处置惩罚后的图像帧(包罗了辨认到的对象)——末了再利用API筛选出全部对象中最大的色块(这个色块就是色环)
物资

物资辨认就应该没啥可以说的了,就是把颜色阈值调节好和把要辨认的霍尔圆像素大小设置好,应该就没啥了。(可以装车了在调节一遍)
https://i-blog.csdnimg.cn/direct/32b572f611484d748e570f0aa38ae79a.png
二维码

二维码我利用的就是openmv官网的历程,辨认结果看起来还不错。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 工创视觉——Openmv(开源)