精华内容
下载资源
问答
  • 工程训练大赛openmv二维码、色环、色块识别 可通过串口与单片机通信实现openmv的任务切换
  • openmv识别二维码,颜色识别与串口通信

    千次阅读 多人点赞 2020-12-10 13:21:16
    目的: 给二维码指定内容:“xxx+xxx”,识别并返回及发送对应序号到串口,同时,正在执行扫码动作时,亮起绿灯,扫码结束后亮起蓝灯。 import sensor, image, time, pyb import ujson from pyb import UART aa = 0...

    目的

    初始目的

    1.识别二维码
    2.识别物体颜色
    3.与stm32串口通信

    进阶想法

    1.给二维码指定内容:“xxx+xxx”,识别并发送到串口;
    2.识别三种颜色,按顺序发送到串口;
    3.待更新(识别条形码并发送至串口)

    二维码识别

    while(True):
        img = sensor.snapshot()
        img.lens_corr(1.8)
        for code in img.find_qrcodes():
            output_str="%s" % code.payload()
    		#output_str为二维码内容
    

    附(草料二维码生成器

    颜色识别

    #颜色阈值
    green_threshold   = (73, 96, -79, -22, -128, 127)
    red_threshold   = (41, 61, 42, 127, -128, 127)
    blue_threshold   = (22, 67, 9, 127, -128, -54)
    
    blobs = img.find_blobs([green_threshold,red_threshold,blue_threshold],x_stride=25,y_stride=50,area_threshold=1000)
    for b in blobs:
    	img.draw_rectangle(b[0:4]) # rect
        #用矩形标记出目标颜色区域
        img.draw_cross(b[5], b[6]) # cx, cy
        #在目标颜色区域的中心画十字形标记
        print(b[8])#b[8]为颜色代号,red=2,green=1,blue=4
    

    串口通信

    openmv上的P4连接stm32的RX,P5连接TX
    1.简单方法

    from pyb import UART
    uart = UART(3, 19200)
    while(True):
    	if uart.any():#判断是否接收到数据
    		getrx = uart.readline()#读取数据
    		uart.write('abc')#发送数据
    

    虽然此法较为简单,但是数据容易在传输的过程中出错,以下是更为便捷的一种方法。

    2.json发送
    openmv可以通过串口直接发送字符串,具体的教程可戳这里->戳我
    在此不多做赘述。
    但我们想要更稳定,高效的通信方法,以下。

    3.按帧传输
    参照这位博主的文章->戳我
    那么假如我想把读取到格式为"xxx+xxx"的二维码内容发送给串口,可以用以下方式。

    #1.定义帧头
    FH = bytearray([0xb3,0xb3])
    uart.write(FH)#串口发送帧头
    #假如已经识别到二维码
    a1,a2,a3 = int(output_str[0]),int(output_str[1]),int(output_str[2])
    b1,b2,b3 = int(output_str[0]),int(output_str[1]),int(output_str[2])
    data=bytearray([a1,a2,a3,b1,b2,b3])#数据转码
    uart.write(data)#串口发送
    

    stm32接收:

    void USART2_IRQHandler(void){
    	
    	static uint8_t rebuf[8]={0},i=0;
    	
    	if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
    	{
    		rebuf[i++]=USART_ReceiveData(USART2);	
    		if(rebuf[0]!=0xb3)//帧头
    			i=0;
    	  if((i==2)&&(rebuf[1]!=0xb3))//判断帧头
    			i=0;
    		if(i>=7)//代表一帧数据完毕
    		{
    				memcpy(OpenMV_Rx_BUF,rebuf,i);
    			i = 0;
     
    		}
    		USART_ClearFlag(USART2,USART_FLAG_RXNE);
    	}	
    }
    

    另外,我们可以通过写小灯闪烁来判断是否成功执行某一步骤

    import pyb
    
    led.off()#小灯闪烁并变蓝
    time.sleep(100)     #延时100ms
    led = pyb.LED(2)
    led.on()
    

    完整代码

    (这里是早期写的代码,能初步实现一些想法,完善后的过一阵子我就会贴出来哈)

    import sensor, image, time, pyb
    import ujson
    from pyb import UART
    
    green_threshold   = (73, 96, -79, -22, -128, 127)
    #(0, 100, -128, -25, -128, 127)
    red_threshold   = (41, 61, 42, 127, -128, 127)
    #(41, 61, 42, 127, -128, 127)
    blue_threshold   = (22, 67, 9, 127, -128, -54)
    #(15, 100, -128, 127, -128, -41)
    #red=2,green=1,blue=4
    getrx = 0
    getcmd = 0
    renum = 0
    colornum = 0
    ptrposition = 0
    sensor.reset()# 初始化摄像头
    sensor.set_pixformat(sensor.RGB565)# 格式为 RGB565.
    sensor.set_framesize(sensor.QQVGA) # 使用 QQVGA 速度快一些
    sensor.skip_frames(time = 2000) # 跳过2000s,使新设置生效,并自动调节白平衡
    sensor.set_auto_gain(False) # 关闭自动自动增益。默认开启的,在颜色识别中,一定要关闭白平衡。
    sensor.set_auto_whitebal(False)
    #关闭白平衡。白平衡是默认开启的,在颜色识别中,一定要关闭白平衡。
    clock = time.clock() # 追踪帧率
    led = pyb.LED(1) # Red LED = 1, Green LED = 1, Blue LED = 2, IR LEDs = 4.
    uart = UART(3, 115200, timeout_char = 1000)
    led.on()
    
    def Rec_NUM1(lista):
        if (lista[0]=='1' and lista[1]=='2' and lista[2]=='3'):
            return 1
        elif (lista[0]=='1' and lista[1]=='3' and lista[2]=='2'):
            return 2
        elif (lista[0]=='2' and lista[1]=='1' and lista[2]=='3'):
            return 3
        elif (lista[0]=='2' and lista[1]=='3' and lista[2]=='1'):
            return 4
        elif (lista[0]=='3' and lista[1]=='1' and lista[2]=='2'):
            return 5
        elif (lista[0]=='3' and lista[1]=='2' and lista[2]=='1'):
            return 6
    
    def Rec_NUM2(lista):
        if (lista[4]=='1' and lista[5]=='2' and lista[6]=='3'):
            return 1
        elif (lista[4]=='1' and lista[5]=='3' and lista[6]=='2'):
            return 2
        elif (lista[4]=='2' and lista[5]=='1' and lista[6]=='3'):
            return 3
        elif (lista[4]=='2' and lista[5]=='3' and lista[6]=='1'):
            return 4
        elif (lista[4]=='3' and lista[5]=='1' and lista[6]=='2'):
            return 5
        elif (lista[4]=='3' and lista[5]=='2' and lista[6]=='1'):
            return 6
    
    while(True):
        clock.tick() # Track elapsed milliseconds between snapshots().
        if uart.any():
            led.off()
            getrx = uart.readline()
            time.sleep(150)     #延时150ms
            led = pyb.LED(2)
            led.on()
            getcmd = int(getrx)
            print(getcmd)
          #  print(img.find_qrcodes())
        img = sensor.snapshot()# 从感光芯片获得一张图像
        img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
        blobs = img.find_blobs([green_threshold,red_threshold,blue_threshold],x_stride=25,y_stride=50,area_threshold=1000)
        if(getcmd==2):
            for code in img.find_qrcodes():
                output_str="%s" % code.payload() #方式1
                renum = int(Rec_NUM1(output_str)*10 + Rec_NUM2(output_str))
                uart.write(ujson.dumps(renum))
                getcmd = 0
                led.off()
        if blobs and getcmd==3:
            for b in blobs:
                # Draw a rect around the blob.
                img.draw_rectangle(b[0:4]) # rect
                #用矩形标记出目标颜色区域
                img.draw_cross(b[5], b[6]) # cx, cy
                #在目标颜色区域的中心画十字形标记
                #print(b[5], b[6], b[8])
                #uart.write(ujson.dumps(b[8]))
                #将颜色序号转为比赛序号
                if b[8]==1:
                    colornum=2
                elif b[8]==2:
                    colornum=1
                elif b[8]==4:
                    colornum=3
                print('colornum=',colornum,'output_str[ptrposition]=',output_str[ptrposition])
                #若任务码对应
                if (int(output_str[ptrposition]) == colornum):
                    uart.write('t')
                    ptrposition+=1
                    if ptrposition==4:
                        ptrposition+=1
                    getcmd=0
    
    
    展开全文
  • 嵌入式OpenMV识别静态二维码,代码无需更改,有大量注释
  • openmv和stm32串口通信完成二维码识别

    千次阅读 多人点赞 2021-03-21 22:28:25
    openmv和stm32串口通信完成二维码识别 文章目录前言一、所用的硬件:二、openmv端2.stm32端总结 前言 注:我只是个大一的小白,本文只完成基本功能,希望能帮助有困惑的人(我也是刚刚走出谜团,大佬勿喷。) 工训...

    openmv和stm32串口通信完成二维码识别


    前言

    注:我只是个大一的小白,本文只完成基本功能,希望能帮助有困惑的人(我也是刚刚走出谜团,大佬勿喷。)
    工训赛期间,突击学习了二维码识别(基于openmv4)。openmv4通过串口通信加json与stm32f103完成通信,结果由stm32所连的lcd屏显示

    一、所用的硬件:

    openmv4、正点原子的mini板(stm32f103rct6)、正点原子配套的lcd屏。

    二、openmv端

    直接上代码:

    代码如下(示例):

    mport sensor, image, time
    from pyb import UART
    
    uart = UART(3, 115200)
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QQVGA) # can be QVGA on M7...
    sensor.skip_frames(30)
    sensor.set_auto_gain(False) # must turn this off to prevent image washout...
    while(True):
        img = sensor.snapshot()
        img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
        for code in img.find_qrcodes():
            print(code)
            FH= bytearray([0xb3,0xb3])
            uart.write(FH)
            uart.write(code.payload())
            FH = bytearray([0x0d,0x0a])
            uart.write(FH)
            time.sleep_ms(1000)
    
    

    注:
    1、openmv4的 p4为TX p5为RX。(不要接错线哦)
    2、FH为帧头用于检验数据发送是否正确。(不懂的可以结合32端代码理解)
    3、 code.payload()函数记录的二维码内的字符。
    4、波特率设置为115200(要和32端保持一致)。
    5、关于二维码识别的详细代码可以去openmv官网查找。

    2.stm32端

    main.c:

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "lcd.h"
    
    
     int main(void)
     {		
     	u8 len;
    	u8 t,n;
    	u8 UsartDisPlay[200];
    	uart_init(115200);
    	 delay_init();
    	 LCD_Init();
    	POINT_COLOR=RED; 
    while(1)
    {
       if(USART_RX_STA&0x8000)
       {
           len=USART_RX_STA&0x3fff;
    		 for(t=0;t<len;t++)
    		  { if(USART_RX_BUF[t]==0xb3)
    				 if(USART_RX_BUF[t]==0xb3) n=t+1;
    			}
    			for(t=0;n<len;t++,n++)
    			{UsartDisPlay[t]=USART_RX_BUF[n];
    				delay_ms(3000);
    			 }
    			USART_RX_STA=0;
        }
    	 
    LCD_ShowString(15,50,260,16,16,UsartDisPlay);
    	
    }	
    	  
    

    usart1配置:

    void uart_init(u32 bound){
      //GPIO端口设置
      GPIO_InitTypeDef GPIO_InitStructure;
    	USART_InitTypeDef USART_InitStructure;
    	NVIC_InitTypeDef NVIC_InitStructure;
    	 
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
      
    	//USART1_TX   GPIOA.9
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
      GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
       
      //USART1_RX	  GPIOA.10初始化
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
      GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
    
      //Usart1 NVIC 配置
      NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
      
       //USART 初始化设置
    
    	USART_InitStructure.USART_BaudRate = bound;//串口波特率
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
    
      USART_Init(USART1, &USART_InitStructure); //初始化串口1
      USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
      USART_Cmd(USART1, ENABLE);                    //使能串口1 
    
    }
    

    中断函数:

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
    		{
    		Res =USART_ReceiveData(USART1);	//读取接收到的数据
    		
    		if((USART_RX_STA&0x8000)==0)//接收未完成
    			{
    			if(USART_RX_STA&0x4000)//接收到了0x0d
    				{
    				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    				else USART_RX_STA|=0x8000;	//接收完成了 
    				}
    			else //还没收到0X0D
    				{	
    				if(Res==0x0d)USART_RX_STA|=0x4000;
    				else
    					{
    					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
    					USART_RX_STA++;
    					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
    					}		 
    				}
    			}   		 
         } 
    

    注:
    1、PA9为TX,PA10为RX。
    2、openmv和stm32一定要共接GND。


    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    总结

    要源码的可以评论区留邮箱,本人刚入门,有错欢迎指正。

    展开全文
  • OPenMV识别颜色识别物块及检测二维码的进阶应用

    万次阅读 多人点赞 2020-02-25 22:55:12
    摄像头OPenMV入门与Python进阶应用 OpenMV简介 简单的来说,它是一个可编程的摄像头,通过MicroPython语言,可以实现你的逻辑。 而且摄像头本身内置了一些图像处理算法,很容易使用。 适合做DIY相关的项目制作,比如...

    OPenMV摄像头入门与识别颜色物块及二维码的进阶应用

    OpenMV简介

    简单的来说,它是一个可编程的摄像头,通过MicroPython语言,可以实现你的逻辑。
    而且摄像头本身内置了一些图像处理算法,很容易使用。
    适合做DIY相关的项目制作,比如追踪小球的车,云台,或者解魔方的机器人。以及对成本要求很高的嵌入式工业方案,比如流水线物品的分拣。
    足以满足基本的应用功能。目前最新版为OpenMV4,本文也是采用最新版而成。

    前言

    关于openmv IDE的安装与使用,官网就有教程,在此不再赘述。
    笔者以前并未学过Python,但只要有C/C++的基础,对OpenMV编程就不是难事。因为IDE自带了很多例程,在这基础上修改即可。

    软件介绍

    我这次是做嵌入式开发,针对各种颜色的物块进行识别,并且完成了二维码识别。使用stm32F4系列的单片机与OpenMV4进行串口通信。完成这些功能就可以对OpenMV驾轻就熟了。

    识别二维码

    二维码是当今重要的信息载体,并且发展迅速,应用前景很广。
    下附源码:

    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA) # can be QVGA on M7...
    sensor.skip_frames(30) # 修改sensor配置之后, 跳过30帧
    sensor.set_auto_gain(False) # must turn this off to prevent image washout...
    while(a):
        img = sensor.snapshot()
        img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
        for code in img.find_qrcodes():
    

    值得注意的是,由于物体的距离不同,我们可以采用不同的像素去采集图像,所以在第三行中,sensor.set_framesize(sensor.QVGA)我们可以根据需要,选择QQVGA、QVGA、VGA等模式。
    倒数第二行img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
    这是对图像进行校正,参数可以自行修改。

    至此二维码已经成功读取到ode.payload()中, 例如下图调用。

    if code.payload() ==123:
         qr=1;
    

    识别颜色及物块位置

    我认为这是在嵌入式设计和日常应用中最为常用的功能。
    从颜色格式而言,这里是LAB颜色模型,而不是常见的RGB。
    这里有三对阈值参数
    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)
     # 小球离镜头的距离 根据我们的公式计算
    ball_distance = K / img_ball_r
    print("小球距离: %d"%ball_distance)
    

    串口设置与stm32通信

    OpenMV自带几种通讯方式:串口、I2C、SPI
    笔者采用最为方便的串口通讯。
    注意这里的波特率,要配置一致。

    uart = UART(3,115200)   #定义串口3变量
            uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters
    

    然后定义串口发送数据包的格式:

    def sending_data(code,cx,cy,cx1,cy1,cx2,cy2):
                global uart;
                #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
                #data = bytearray(frame)
                data = ustruct.pack("<bbhhhhhhhb",              #格式为俩个字符俩个短整型(2字节)
                               0x2C,                       #帧头1
                               0x12,                       #帧头2
                               int(code), # up sample by 4    #数据1
                               int(cx), # up sample by 4    #数据1
                               int(cy), # up sample by 4    #数据2
                               int(cx1), # up sample by 4    #数据1
                               int(cy1), # up sample by 4    #数据2
                               int(cx2), # up sample by 4    #数据1
                               int(cy2), # up sample by 4    #数据2
                               0x5B)
                uart.write(data);   #必须要传入一个字节数组
    

    我设置了两个帧头,一个帧尾,均为一字节,如下对应“b”。中间的数据为7个两字节,如下对应“h”。
    data = ustruct.pack("<bbhhhhhhhb",
    这一行中可以对应着修改,“b”、"h"等以下表对应。

    #pack各字母对应类型

    #x   pad byte        no value            1
    #c   char            string of length 1  1
    #b   signed char     integer             1
    #B   unsigned char   integer             1
    #?   _Bool           bool                1
    #h   short           integer             2
    #H   unsigned short  integer             2
    #i   int             integer             4
    #I   unsigned int    integer or long     4
    #l   long            integer             4
    #L   unsigned long   long                4
    #q   long long       long                8
    #Q   unsilong long   long                8
    #f   float           float               4
    #d   double          float               8
    #s   char[]          string              1
    #p   char[]          string              1
    #P   void *          long
    

    串口接收函数:

     def recive_data():
            global uart
            if uart.any():
                tmp_data = uart.readline();
                print(tmp_data)
    

    注:本人只让OpenMV对单片机单向通信,所以在例程中并未使用此串口接收函数。

    stm32例程:

    OpenMV.h

    #ifndef __Openmv_H
    #define __Openmv_H
    #include "usart.h"
    struct openmv
    {
    	s16 qr;
    	s16 a;
    	s16 b;
    	s16 c;
    	s16 d;
    	s16 e;
    	s16 f;
    };
     void OpenMV_Handler(UART_HandleTypeDef *huart);
    #endif
    

    OpenMV.c

    #include "OpenMV.h"
    #include <string.h>
    struct openmv 		stcopenmv;
    extern u8 RxTemp ;
    
    
     void OpenMV_Handler(UART_HandleTypeDef *huart)
    {
      /* Prevent unused argument(s) compilation warning */
    	
    static u8 aRxBuffer[20];
    static u8 aRxCnt = 0;	
    static u8 state = 0;	
    
    	if (state == 0&&RxTemp==0x2C) //数据头不对,则重新开始寻找0x2c数据头
    	{
         state = 1;
    	}
    	else if (state == 1&&RxTemp==0x12) //数据头不对,则重新开始寻找0x12数据头
    	{
         state =2;
    		 aRxCnt=0;
    	}
    	else if (state == 2) //数据不满11个,则返回
    	{
    		aRxBuffer[aRxCnt++]=RxTemp;
    		if (aRxCnt>=14)//数据不满11个,返回
    		{
    		memcpy(&stcopenmv,&aRxBuffer[0],14);
    		aRxCnt=0;
    		state=0;
    		}
    	}
    	else state=0;
    	
      /* NOTE: This function should not be modified, when the callback is needed,
               the HAL_UART_RxCpltCallback could be implemented in the user file
       */
    }
    int COLOR_Order()
    {
    	if(stcopenmv.a<stcopenmv.c&&stcopenmv.a<stcopenmv.e)
    	{
    		if(stcopenmv.c<stcopenmv.e)
    				return 1;
    	  else
    		    return 2;	
    	}
    	else if(stcopenmv.c<stcopenmv.a&&stcopenmv.c<stcopenmv.e)
    	{
    		if(stcopenmv.a<stcopenmv.e)
    				return 3;
    	  else
    		   return 4;	
    	}
    	else if(stcopenmv.e<stcopenmv.c&&stcopenmv.e<stcopenmv.a)
    	{
    		if(stcopenmv.a<stcopenmv.c)
    				return 5;
    	  else
    		    return 6;	
    	}
    	return 0;
    }
    

    main函数调用的相关代码:

    #include "OpenMV.h"
    
    extern u8 RxTemp ;
    extern struct openmv 		stcopenmv;
    
      MX_USART3_UART_Init();
      HAL_UART_Receive_IT(&huart3,&RxTemp,1); 
    

    经过以上初始化,就已经可以读取OpenMV串口发过来的值了。
    比如以下就可以通过我自己的LED函数显示出来:
    其中的stcopenmv.qr是读取二维码的值。

    OLED_ShowNum(0,0,stcopenmv.a,3,16);
    OLED_ShowNum(100,0,stcopenmv.qr,3,16);
    OLED_ShowNum(0,2,stcopenmv.c,3,16);
    OLED_ShowNum(0,4,stcopenmv.e,3,16);
    OLED_ShowNum(100,4,stcopenmv.f,3,16);
    

    OpenMV编辑器全例程如下:

    import sensor, image, time, math
    from pyb import UART
    import json
    import ustruct
    
    #亮度,范围[0,100],从纯黑到纯白;a表示从红色到绿色的范围,[127,-128];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));
    threshold = [50, 50, 0, 0, 0, 0] # Middle L, A, B values.
    
    QRCode_1="123";
    QRCode_2="132";
    QRCode_3="213";
    QRCode_4="231";
    QRCode_5="312";
    QRCode_6="321";
    
    qr=0
    a=1
    K=5000 # K是我们计算出来的常数
    
    
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA) # can be QVGA on M7...
    sensor.skip_frames(30) # 修改sensor配置之后, 跳过30帧
    sensor.set_auto_gain(False) # must turn this off to prevent image washout...
    while(a):
        img = sensor.snapshot()
        img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
        for code in img.find_qrcodes():
            if code.payload() == QRCode_1 :
                qr=1;
            elif code.payload() == QRCode_2 :
                qr=2;
            elif code.payload() == QRCode_3 :
                qr=3;
            elif code.payload() == QRCode_4 :
                qr=4;0
                .3
            elif code.payload() == QRCode_5 :
                qr=5;
            elif code.payload() == QRCode_6 :
                qr=6;
            else :
                qr=7;
            a=0
            print(code)
            print(qr)
            print(QRCode_4)
    
    
    else:
            sensor.reset()
            sensor.set_pixformat(sensor.RGB565)
            sensor.set_framesize(sensor.QVGA)
            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()
    
            uart = UART(3,115200)   #定义串口3变量
            uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters
    
            def calc_radius(blob):
                            # 计算图像中色块的半径 , 比较粗暴
                     return (blob.w() + blob.h()) / 2
    
            def find_max(blobs):    #定义寻找色块面积最大的函数
                max_size=0
                for blob in blobs:
                    if blob.pixels() > max_size:
                        max_blob=blob
                        max_size = blob.pixels()
                return max_blob
    
    
    
    
            def sending_data(code,cx,cy,cx1,cy1,cx2,cy2):
                global uart;
                #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
                #data = bytearray(frame)
                data = ustruct.pack("<bbhhhhhhhb",              #格式为俩个字符俩个短整型(2字节)
                               0x2C,                       #帧头1
                               0x12,                       #帧头2
                               int(code), # up sample by 4    #数据1
                               int(cx), # up sample by 4    #数据1
                               int(cy), # up sample by 4    #数据2
                               int(cx1), # up sample by 4    #数据1
                               int(cy1), # up sample by 4    #数据2
                               int(cx2), # up sample by 4    #数据1
                               int(cy2), # up sample by 4    #数据2
                               0x5B)
                uart.write(data);   #必须要传入一个字节数组
    
            def recive_data():
                global uart
                if uart.any():
                    tmp_data = uart.readline();
                    print(tmp_data)
    
    
    
            #mainloop
            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)
                    # 小球离镜头的距离 根据我们的公式计算
                    ball_distance = K / img_ball_r
                    print("小球距离: %d"%ball_distance)
    
                if blobs1:
                        #如果找到了目标颜色
                        max_b = find_max(blobs1);
                        # 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) # 在中心点画标记
                        #在目标颜色区域的中心画十字形标记
                        cx1=max_b[5];
                        cy1=max_b[6];
                        img.draw_line((160,120,cx1,cy1), color=(127));
                        #img.draw_string(160,120, "(%d, %d)"%(160,120), color=(127));
                        img.draw_string(cx1, cy1, "(%d, %d)"%(cx1,cy1), color=(127));
                if blobs2:
                        #如果找到了目标颜色
                        max_b = find_max(blobs2);
                        # 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) # 在中心点画标记
                        #在目标颜色区域的中心画十字形标记
                        cx2=max_b[5];
                        cy2=max_b[6];
                        img.draw_line((160,120,cx2,cy2), color=(127));
                        #img.draw_string(160,120, "(%d, %d)"%(160,120), color=(127));
                        img.draw_string(cx2, cy2, "(%d, %d)"%(cx2,cy2), color=(127));
    #            sending_data(cx,cy,cx,cy,cx,cy); #发送点位坐标
                sending_data(qr,cx,cy,cx1,cy1,cx2,cy2); #发送点位坐标
                recive_data();
                #time.sleep(1000)
    
            #pack各字母对应类型
            #x   pad byte        no value            1
            #c   char            string of length 1  1
            #b   signed char     integer             1
            #B   unsigned char   integer             1
            #?   _Bool           bool                1
            #h   short           integer             2
            #H   unsigned short  integer             2
            #i   int             integer             4
            #I   unsigned int    integer or long     4
            #l   long            integer             4
            #L   unsigned long   long                4
            #q   long long       long                8
            #Q   unsilong long   long                8
            #f   float           float               4
            #d   double          float               8
            #s   char[]          string              1
            #p   char[]          string              1
            #P   void *          long
    

    硬件

    在这里插入图片描述

    电源

    通过USB-type c线供电。据笔者实验,这是仅有的供电方式,如果这里坏了,就得重新买一个了。

    焊接接口

    笔者用的是串口,就连usart3(P10、11) 当然,别忘了共地哈。

    展开全文
  • 到物块位置时,openmv接受到arduino发送信号,获取颜色标识,然后识别下一个,识别三次后得到物块颜色顺序,发送给arduino,到二维码识别二维码发送给arduino
  • 一个基于openmv二维码识别程序,可以实现手自动一体的二维码识别
  • 利用openmv识别二维码信息,可用于液晶显示屏显示的内容
  • 我用openmv二维码识别、条形码识别、颜色识别的程序编在一起,现在想通过openmv引脚收到高低电平来执行指定指令, 比如p7引脚收到高电平就执行二维码程序,p8和p9都收到了高电平,就执行...
  • 我和小伙伴们在推出OpenMV3一年之后,再次推出了OpenMV4!...全开源的STM32H7版OpenMV4,性能更强,热成像,各种条形码,二维码,颜色跟踪,ARM神经网络等都已经支持 首先来个视频大家感受一下OpenMV4强悍的性...

    我和小伙伴们在推出OpenMV3一年之后,再次推出了OpenMV4!

    首先来一张测试版的丑照~哈哈~后面实际做的话会用黑色沉金工艺!比这个就漂亮多了!.

    有需求或者技术问题交流的,请加群646461928进行技术交流!

     

    全开源的STM32H7版OpenMV4,性能更强,热成像,各种条形码,二维码,颜色跟踪,ARM神经网络等都已经支持

    首先来个视频大家感受一下OpenMV4强悍的性能!

    https://www.bilibili.com/video/av25447120/

     

    首先感谢官方的开源!这里附上官方的众筹地址!有兴趣的小伙伴们可以支持一波!

    https://www.kickstarter.com/projects/1798207217/openmv-cam-h7-machine-vision-w-micropython

     

    当然,紧随其后的是我们的预售地址!希望小伙伴们也可以支持一波~

    https://item.taobao.com/item.htm?spm=a230r.1.14.61.6b34602baxLEdc&id=580520821708&ns=1&abbucket=11#detail

     

    此次物致DIY推出的镜头比官方多了ov9650和ov2640,发货时间为12月初。官方的发货时间为明年3月份!

    着急尝鲜的小伙伴们可以选择我们的套餐!

     

    OpenMV4采用了STM32H7高性能微控制器。处理器运行在400MHz主频,内核跑分是2020,作为对比,主频是1G的树莓派zero跑分是2060。功能强大的MCU让OpenMV4性能强悍!

    1、OpenMV的目标是机器视觉版的Arduino,且有自己的IDE,采用Python编程简单易用,更重要的是保证固件100%全开源。

    2、相比于之前的F7版本,性能提升2倍以上,带了热成像和全局快门的摄像头支持。

    3、颜色跟踪方面,H7版可以轻松达到80帧。更厉害的是,可以通过OpenMV IDE编辑16种颜色的阀值,从而快捷的对显示区里面16种颜色物体进行识别,并给出边界大小,质心和方向。

    4、OpenMV Cam H7可以跟踪April标签,解码二维码,读取各种类型的条形码,也可以解析数据矩阵。

    5、H7版带有FLIR Lepton 1/2/3热成像摄像头支持,允许用户在热图像上运行所有算法。想要检测进入房间的人? Thermal Vision + Multi-Blob Color Tracking使这一点变得极其简单。而且用户可以完全控制OpenMV Cam H7上所有较低级别的FLIR Lepton功能,这些功能内置于python模块的固件中,比如获得图像中任何像素的温度。

    6、对于需要精确机器视觉支持的用户,提供了MT9V034相机传感器模块,支持全局快门。MT9V034是一款仅支持灰阶的全局快门传感器,具有按需触发功能。 它能够在VGA / QVGA下运行80 FPS,在QQVGA下运行200 FPS,在QQQVGA下运行400 FPS。

    7、OpenMV Cam H7支持ARM的CMSIS-NN神经网络库,能够运行简单的CNN,如LENET-6,用于数字检测等。

     

    最后附上我们此次未推出(考虑成本问题)的红外成像的效果图,如果大家对红外成像有兴趣,我们也可以推出!

    具体请加群646461928咨询,谢谢~

     

    以上文章为物致DIY——皈依原创,需要使用或者转载的小伙伴们请注明出处,谢谢!

    展开全文

空空如也

空空如也

1 2 3
收藏数 44
精华内容 17
关键字:

openmv二维码识别