openmv识别物体并与单片机通信(STM32)

  • OPENMV端
    • 物体识别
      • 感光元件
      • 寻找色块
      • 画图
    • 距离判断
      • 距离
      • 实际距离
    • 串口发送
  • STM32段
    • 串口接收
      • 串口2配置
    • 数据处理
    • 数据显示
  • Openmv与STM32连线
  • 实验现象
    • `在进行串口配置时,OpenMV和STM32的串口的波特率、奇偶位、停止位等都需要相同,否则传送数据不会成功。`
  • 源码获取

OPENMV端

物体识别

感光元件

 img = sensor.snapshot() #存储摄像头所拍摄的图像并保存在img变量中

寻找色块

 blobs = img.find_blobs([red_thresholds]) #find_blobs函数可以找到色块。

find_blobs函数:此函数参数较多,一般只用第一个参数就可以找到需要的色块。thresholds是颜色的阈值,是一个列表,这个列表可以有多个颜色阈值。
一个颜色阈值的结构是这样的:

thresholds= (minL, maxL, minA, maxA, minB, maxB) #元组里面的数值分别是L A B 的最大值和最小值。

画图

image.draw_cross(x, y, size=5, color=White) #在图像中画一个十字

x,y:是坐标
size:是两侧的尺寸
color:画十字的颜色

image.draw_rectangle(rect_tuple, color=White) #在图像中画一个矩形框

rect_tuple 的格式是 (x, y, w, h)
color:画矩形框的颜色
sensor-感光元件具体介绍
find_blobs函数具体介绍
画图具体介绍

距离判断

实际长度和摄像头里的像素成反比

距离

距离 = k / 直径的像素

K1 = 500   #每次改变物体,K值都要重新计算 K1 = 距离(25cm已知)*直径像素Lm(20)
Lm = (max_blob.w() + max_blob.h())/2 #色块的长与宽 直径像素点个数
length = K1 / Lm

实际距离

实际距离 = k * 直径的像素
相同距离测不同物体的宽和长的长度

K2 = 0.16  #实际距离 = k * 直径的像素,K2 = 实际大小(宽4cm已知)/宽像素b[2](25)
K3 = 0.16  #实际距离 = k * 直径的像素,K3 = 实际大小(长4cm已知)/长像素b[3](25)
width = K2 * max_blob.w()
height = K3 * max_blob.h()

k1值计算:先已知一个长度length,在计算出直径像素点个数Lm。根据公式得到k = lenght * Lm计算出k1。通过改变物体(与计算k1值的物体为同一个)的距离就可以得到物体到openmv的距离。
k2,k3值计算:先得到一个已知物体的实际长和宽,在得到这个物体长和宽的像素。根据公式实际距离 = k * 直径的像素来得到k2,k3。改变不同的物体就可以知道该物体的实际长和宽。
OpenMV测距具体介绍
视频介绍

串口发送

from pyb import UART #模块导入
uart = UART(3,115200) #串口配置
uart.init(9600, bits=8, parity=None, stop=1)
data = bytearray([0xb3,0xb3,max_blob[5],max_blob[6],max_blob[3],0x0d,0x0a]) #要发送的数据
uart.write(data) #数据发送

openmv发送16进制数据需要转换为字节的形式,假设要发送 0x50,0x600,0x70,0x80这几个16进制数据代码如下:

uart = UART(3, 115200)
uart.init(9600, bits=8, parity=None, stop=1)
data=bytearray([0x50,0x60,0x70,0x80])
uart.write(data)

STM32段

串口接收

串口2配置

  GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //使能GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); //使能USART2USART_DeInit(USART2);//USART2_TX   GPIOA.2GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA.2//USART2_RX    GPIOA.3GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA.3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA.3  //Usart2 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_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(USART2,&USART_InitStructure); //初始化串口2USART_ITConfig(USART2,USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART2,ENABLE);                    //使能串口2

数据处理

 static u8 state = 0;if(state == 0 && data == 0xb3){state = 1;openmv[0] = data;}else if(state == 1 && data == 0xb3){state = 2;openmv[1] = data;}else if(state == 2){state = 3;openmv[2] = data;}else if(state == 3){state = 4;openmv[3] = data;}else if(state == 4){state = 5;openmv[4] = data;}else if(state == 5){state = 6;openmv[5] = data;}else if(state == 6) // 检测是否接收到结束标志{if(data == 0x0a){state = 0;LED0 =~ LED0;openmv[6] = data;Openmv_Data();data = 0;}else if(data != 0x0a){state = 0;for(i = 0;i < 7;i++){openmv[i] = 0x00;}}}else{state = 0;data = 0;LED0 = 1;for(i = 0;i < 7;i++){openmv[i] = 0x00;}}

数据显示

在oled上显示需要的数据

 OLED_ShowString(0,0,"OpenMV-X:"); OLED_ShowNum(70,00,OpenMV_X,3,12);OLED_ShowString(0,2,"OpenMV-Y:");   OLED_ShowNum(70,2,OpenMV_Y,3,12);        OLED_ShowString(0,4,"Distance:");  OLED_ShowNum(68,4,Distance,3,12);OLED_ShowString(90,4,"cm");

Openmv与STM32连线

Openmv端:TXD(P4),RXD(P5),GND。TXD是发送端,RXD是接收端,GND是地线。
STM32端:TXD(PA2),RXD(PA3),GND。
如何连线:OpenMV的RXD连到STM32的TXD;OpenMV的TXD连到STM32的RXD;把OpenMV的GND与STM32的GND相连接。

实验现象

识别到红色物体

openmv打印输出数据

STM32还未接收到数据

STM32接收到数据并在oled上显示

注:当stm32上电后,oled上显示数据为0且红灯亮蓝灯灭,当openmv识别到物体并发送数据到stm32时,红灯亮蓝灯闪烁且oled实时显示数据;当openmv未识别到物体时,oled显示上次识别到的数据且红蓝灯亮。


在进行串口配置时,OpenMV和STM32的串口的波特率、奇偶位、停止位等都需要相同,否则传送数据不会成功。


源码获取

链接:https://pan.baidu.com/s/125H07c1wLDt9P-YLQeN8ZA
提取码:ddt0

openmv识别物体并与单片机通信(STM32)相关推荐

  1. 超详细OpenMV与STM32单片机通信 (有完整版源码)

    目录标题 1.前言(闲话) 2.硬件连接 3.软件代码---OpenMV端 4.软件代码---STM32端 5.利用PC端测试数据数据是否发送接收正常 6.学习补充 (代码看不懂的时候可以来看一下) ...

  2. python实现STM32单片机通信

    python实现STM32单片机通信 注意事项 注意事项 Python3中的encode('unicode-escape')和encode('raw_unicode_escape')区别与联系 htt ...

  3. K210识别数字(0~9)并与单片机通信通过数字来控制小车移动

    前一段时间学习了K210的模型训练,又学会了K210的串口通信,于是冒出一个新奇的想法,用手势控制小车,手势识别可能比较难,于是想着先用数字控制小车.(懂得都懂)我相信有很多人再找这篇博客,希望大家可 ...

  4. OpenCV开发笔记(七十二):红胖子8分钟带你使用opencv+dnn+tensorFlow识别物体

    本博客是转载的 本文章源博客地址:https://blog.csdn.net/qq21497936/article/details/109194717 各位读者,知识无穷而人力有穷,要么改需求,要么找 ...

  5. nRF24L01--2.4G无线通信模块(1)(51单片机和51单片机通信)

    作者:李剀 出处:https://www.cnblogs.com/kevin-nancy/ 或者 https://blog.csdn.net/Kevin_8_Lee/article/details/9 ...

  6. STM32F103+NRF2401+游戏摇杆ADC双单片机通信遥控小车

    STM32F103+NRF2401+游戏摇杆ADC双单片机通信遥控小车 文章目录 STM32F103+NRF2401+游戏摇杆ADC双单片机通信遥控小车 前言 一.实现的功能? 二.主要代码及模块讲解 ...

  7. 十年老鸟告诉你,51单片机和STM32怎么选择?

    十年老鸟告诉你,51单片机和STM32怎么选择? 初中辍学进厂,边工作边自学单片机,各种单片机实战项目,也是零基础学的stm32,应该还是能给你一些建议.首先理解为什么叫嵌入式?单从电路板硬件上看,是 ...

  8. c51单片机的语言,51单片机,stm32,arduino都是用什么语言进行编程的?

    51单片机,STM32单片机用汇编或者C语言,现在基本都用C语言编程,Arduino有自己的编程环境,用户也是用C语言编程. 51单片机的编程 51单片机进入中国比较早,在早前用汇编编程比较多,我在上 ...

  9. 训练自己haar-like特征分类器并识别物体(1)

    本系列文章旨在学习如何在opencv中基于haar-like特征训练自己的分类器,并且用该分类器用于模式识别.该过程大致可以分为一下几个大步骤: 1.准备训练样本图片,包括正例及反例样本 2.生成样本 ...

最新文章

  1. Cornell University Designing with Microcontrollers
  2. SalttSack自动化运维(四)——JINJA模块
  3. 解决Loadrunner报not writing pre_cci.ci问题
  4. PAT-BASIC-1016-部分A+B
  5. [Godot][Blender] 通过 Blender 将 fbx 批量转为 gltf 用于 godot
  6. leetcode 130 python
  7. 洛谷P1087 FBI树
  8. jquery 使用下拉效果的实现
  9. java第二章_Java第二章基本语法
  10. 怎么缩小界面_PDF怎么压缩变小?介绍实用的PDF压缩软件
  11. TinyPXE网络启动,打造无盘工作站
  12. laravel-admin使用教程
  13. 大数据与数据挖掘的相对绝对关系
  14. 思岚雷达rplidar S1配置调试全纪录
  15. JUC强大的辅助工具类
  16. 推荐一款团队协作软件---confluence
  17. php 删除其他盘符,Linux_自动清除电脑垃圾及删除windows默认共享盘符的批处理bat,by:zuifeng258Windows在默认情况下 - phpStudy...
  18. Android Camera:从零开发一款相机APP
  19. 2021-01-03 请教一下水卡校验算法
  20. 用nero将rmvb格式影片刻录成vcd光盘

热门文章

  1. 9-Mybatis 多表查询之一对多
  2. idea中配置Springboot热部署
  3. java 图像膨胀_OpenCV3 Java图形图像上的膨胀(Imgproc.dilate)
  4. java swing 列表框_Java开发笔记(一百三十一)Swing的列表框
  5. eclipse支持html,让eclipse完全支持HTML/JS/CSS智能提示
  6. switchpreference 事件_Vue 3 自定义事件
  7. 冬天来了,温暖甜品热饮海报设计psd模板,勾住你的胃!
  8. 值得所有设计师拥有的国内外“设计导航网站”
  9. c语言程序优化设计,C程序设计语言的教学策略优化设计
  10. linux mysql 主从数据库_【Linux】【MySQL】MySQL主从数据库