openmv与stm32之间的通信学习(数字识别)
前提:软件安装与学习视频讲解
在我们使用openmv中的神经网络时,在新的版本里是没有nn的库给你调用的,需要在老版本里才有,百度云链接:https://pan.baidu.com/s/1bgLiLMxyqqL9X3h5dN8cZA 提取码:behn (光这个能不能点个赞咧)
本文的数字识别的及基础使用可看这个视频OpenMV Lenet识别数字 | 星瞳科技
一.理论知识-视觉识别与神经网络
nn
模块用于神经网络。nn_class对象由 net.search() 返回。classnn.nn_class请调用 net.search() 来创建这个对象与神经网络算法.
神经网络是受神经元启发的,对于神经元的研究由来已久,1904年生物学家就已经知晓了神经元的组成结构。一个神经元通常具有多个树突,主要用来接受传入信息;而轴突只有一条,轴突尾端有许多轴突末梢可以给其他多个神经元传递信息。轴突末梢跟其他神经元的树突产生连接,从而传递信号。这个连接的位置在生物学上叫做“突触”。在这里可以参考高中生物关于神经元信息传输与脉冲刺激兴奋的关系。
1949年心理学家Hebb提出了Hebb学习率,认为人脑神经细胞的突触(也就是连接)上的强度上可以变化的。于是计算科学家们开始考虑用调整权值的方法来让机器学习。这为后面的学习算法奠定了基础。
1958年,计算科学家Rosenblatt提出了由两层神经元组成的神经网络。他给它起了一个名字–感知器( Perceptron )。
1986年,Rumelhar和Hinton等人提出了反向传播( Backpropagation ,BP)算法,这是最著名的一个神经网络算法。
组成
多层神经网咯主要由三部分组成:输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)。
每层由单元(units)组成, 输入层(input layer)是由训练集的实例特征向量传入,经过连接结点的权重(weight)传入下一层,一层的输出是下一层的输入。 隐藏层(hidden layers)的个数可以是任意的,输入层有一层,输出层(output layers)有一层。每个单元(unit)也可以被称作神经结点。上图为2层的神经网络(一般输入层不算)。
一层中加权的求和,然后根据非线性方程转化输出。作为多层向前神经网络,理论上,如果有足够多的隐藏层(hidden layers) 和足够大的训练集, 可以模拟出任何方程。
神经网络可以用来解决分类(classification)问题,也可以解决回归( regression )问题。
单层到多层的神经网络
由两层神经网络构成了单层神经网络,它还有个别名——— 感知机(Perceptron)。在3个输入,连接线的权值分别是 w1, w2, w3。将输入与权值进行乘积然后求和,作为 z单元的输入,如果 z 单元是函数 g ,那么就有 z = g(a1 * w1 + a2 * w2 + a3 * w3) 。
在多层神经网络中,只不过是将输出作为下一层的输入,一样是乘以权重然后求和。
方法1
nn_class.rect()
返回一个nn_class的边界框的矩形元组(x,y,w,h),用于像 image.draw_rectangle()
等 image
方法。
nn_class.x()
返回nn_class的边界框的x坐标(int)。
您也可以通过索引 [0]
取得这个值。
nn_class.y()
返回nn_class的边界框的y坐标(int)。
您也可以通过索引 [1]
取得这个值。
nn_class.w()
返回nn_class的边界框的w坐标(int)。
您也可以通过索引 [2]
取得这个值。
nn_class.h()
返回nn_class的边界框的h坐标(int)。
您也可以通过索引 [3]
取得这个值。
nn_class.index()
返回nn类检测的索引(int)。
您也可以通过索引 [4]
取得这个值。
nn_class.value()
返回nn类检测的值(float)。
您也可以通过索引 [5]
取得这个值。
进行NET-构造函数
classnn.load(path)
将神经网络从 .network
二进制文件加载到内存中。 神经网络的层/权值/偏置/等。存储在MicroPython堆上。 返回一个可以在图像上进行操作的Net对象。
方法2
net.forward(image[, roi[, softmax=False[, dry_run=False]]])
在图像roi上运行网络(必要时自动缩放)并返回神经网络分类结果的浮点值列表。
roi
是感兴趣区域的矩形元组(x,y,w,h)。如果未指定,则它等于图像矩形。仅运算 roi
中的像素。
如果 softmax
为True,则列表中所有的输出总和为1。否则,列表中的任何输出都可以在0和1之间。
将 dry_run
设置为True以打印出正在执行的网络层而不是实际执行它们。这是为了调试debug。
net.search(image[, roi[, threshold=0.6[, min_scale=1.0[, scale_mul=0.5[, x_overlap=0[, y_overlap=0[, contrast_threshold=1[, softmax=False]]]]]]]])
以滑动窗口方式在图像roi上运行网络。 网络检测器窗口以多种比例滑过图像。
返回神经网络检测结果的 nn_class 对象列表。
roi
是感兴趣区域的矩形元组(x,y,w,h)。如果未指定,则它等于图像矩形。仅运算 roi
中的像素。
在图像中的区域上运行之后,将最大检测值超过 threshold
的对象添加到输出列表中。
min_scale
控制网络模型的缩放比例。在默认值下,网络不会缩放。但是,值为0.5将允许用于检测图像大小为50%的对象…
scale_mul
控制测试多少个不同的比例。滑动窗口方法的工作原理是将默认比例1乘以 scale_mul
,
并且结果需要大于 min_scale
。 scale_mul
的默认值0.5,测试每个比例变化减少50%。 但是,0.95的值仅为5%的缩小量。
x_overlap
控制与滑动窗口的下一个检测区域重叠的百分比。值为零表示没有重叠。值为0.95意味着95%重叠。
y_overlap
控制与滑动窗口的下一个检测区域重叠的百分比。值为零表示没有重叠。值为0.95意味着95%重叠。
contrast_threshold
控制跳过图像低对比度区域的阈值。在图像中的某个区域上运行nn之前,将在该区域上计算标准偏差,如果标准偏差低于 contrast_threshold
,则跳过该区域。
如果 softmax
为True,则列表中所有的输出总和为1。否则,列表中的任何输出都可以在0和1之间。
二.代码使用
1、openmv-视觉识别代码(使用python语言进行学习)
# LetNet Example 直接使用openmv与电脑连接就可以使用了import sensor, image, time, os, nnsensor.reset() # Reset and initialize the sensor.
sensor.set_contrast(3)
sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.set_windowing((128, 128)) # Set 128x128 window.
sensor.skip_frames(time=100)
sensor.set_auto_gain(False)
sensor.set_auto_exposure(False)# Load lenet network
net = nn.load('/lenet.network')
labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']clock = time.clock() # Create a clock object to track the FPS.
while(True):clock.tick() # Update the FPS clock.img = sensor.snapshot() # Take a picture and return the image.out = net.forward(img.copy().binary([(150, 255)], invert=True))max_idx = out.index(max(out))score = int(out[max_idx]*100)if (score < 70):score_str = "??:??%"else:score_str = "%s:%d%% "%(labels[max_idx], score)img.draw_string(0, 0, score_str)print(clock.fps()) # Note: OpenMV Cam runs about half as fast when connected# to the IDE. The FPS should increase once disconnected.
在进行通信时最好对于C语言有较好的基础,不然会难以进行对于通信模块的准备。
openmv-与stm32代码调整
# LetNet Example 直接使用openmv与电脑连接就可以使用了import sensor, image, time, os, nn
import pyb from uart
sensor.reset() # Reset and initialize the sensor.
sensor.set_contrast(3)
sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.set_windowing((128, 128)) # Set 128x128 window.
sensor.skip_frames(time=100)
sensor.set_auto_gain(False)
sensor.set_auto_exposure(False)
uart(1,115200)#这里要进行注意,你的stm32的串口通信使用的时是什么如:调用UART1就是用1的# Load lenet network
net = nn.load('/lenet.network')
labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',0x5B]clock = time.clock() # Create a clock object to track the FPS.
while(True):clock.tick() # Update the FPS clock.img = sensor.snapshot() # Take a picture and return the image.out = net.forward(img.copy().binary([(150, 255)], invert=True))max_idx = out.index(max(out))score = int(out[max_idx]*100)if (score < 70):score_str = "??:??%"else:score_str = "%s:%d%% "%(labels[max_idx], score)img.draw_string(0, 0, score_str)print(clock.fps()) uart.write(labels[max_idx]) # Note: OpenMV Cam runs about half as fast when connected# to the IDE. The FPS should increase once disconnected.
2、stm32代码-采用串口通信
(使用IIC,或SPI,无线电wifi通信也是可以的)
如果需要进行WiFi与openmv通信最好先去看这个教程视频。WIFI编程对OpenMV远程调试 | 星瞳科技 (singtown.com)
在这里需要外加模块或板子,如:esp8266(adriuno)
在stm32中使用串口通信用于接收opennmv传过来的数据,在这里要特别强调,它传过来的字符串,要自己进行对应的字符转换才能进行解码。
//USART1 全局中断服务函数
void USART1_IRQHandler(void)
{char com_data; static u8 RxBuffer1[10]={0}; static u8 RxFlag1 = 0;u8 temp;if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) //接收中断 {USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志com_data = USART_ReceiveData(USART1);if(flag0==0){if(com_data!=' '){RxBuffer1[RxFlag1]=com_data;RxFlag1++;}else if(com_data==' '){sum=RxBuffer1[1];printf("sum is %c\n", sum);flag0=1;RxFlag1=0;}}else{if((com_data>47)&&(com_data<58)){RxBuffer1[RxFlag1]=com_data;RxFlag1++;}else if(com_data==' '){if(RxFlag1==1){temp=(RxBuffer1[0]-48);}else if(RxFlag1==2){temp=(RxBuffer1[0]-48)*10+(RxBuffer1[1]-48);}else if(RxFlag1==3){temp=(RxBuffer1[0]-48)*100+(RxBuffer1[1]-48)*10+(RxBuffer1[2]-48);} Cx=temp;printf("Cx is %d\n", Cx);RxFlag1=0;}}
// else if(RxState==1)
// {
// if((com_data>47)&&(com_data<58))
// {
// RxBuffer1[RxFlag1]=com_data;
// RxFlag1++;
// }
// else if(com_data==' ')
// {
// if(RxFlag1==1)
// {
// Cw=(RxBuffer1[0]-48);
// }
// else if(RxFlag1==2)
// {
// Cw=(RxBuffer1[0]-48)*10+(RxBuffer1[1]-48);
// }
// else if(RxFlag1==3)
// {
// Cw=(RxBuffer1[0]-48)*100+(RxBuffer1[1]-48)*10+(RxBuffer1[2]-48);
// }
// RxFlag1=0;
// printf("Cw is %d\n", Cw);
// RxState=0;
// }
// }}
}
在这里我直接先给出中断函数的代码,其他的配置就和一般的stm32 串口通信的相同。在这里可以解释下为什么openmv那边传过来的字符串,因为openmv虽然是有自带stm32芯片处理,但为了后续更好的进行简单化使用就用python尽心那个了封装,而在python中在未规定指定的传出数据时都是默认传输字符串。剩下的就是在串口助手那里看是否有数据过来
openmv与stm32之间的通信学习(数字识别)相关推荐
- STM32 CAN总线通信学习笔记(一)
STM32 CAN总线通信学习笔记(一) 一.CAN总线简介 CAN 是控制器局域网络(Controller Area Network, CAN)的简称.CAN采用数据块编码的方式,数据块根据帧的类型 ...
- 【星曈科技】OpenMv笔记——利用OpenMV与STM32进行串口通信
利用OpenMV与STM32进行串口通信 OpenMV端的程序 # Untitled - By: dell - 周一 7月 19 2021# Blob Detection and uart trans ...
- 【嵌入式】openmv与stm32的串口通信
参考:(文中部分图/文字/代码来自以下文章,部分内容由于时间久远已经找不到原作者,可联系注明或删除) PYTHON串口数据打包发送STM32接收数据解析 openmv中文文档 这里以openmv循迹代 ...
- 基于SVM+HOG的手写体数字识别
本文是对下面这篇文章的一些略微详细的解释... OpenCV Hog+SVM 学习 最近在学习数字识别,搜索资料的时候,发现了这篇文章.文章很久了,是2013年发的,那时候我才刚上大学.....用的是 ...
- 超详细OpenMV与STM32单片机通信 (有完整版源码)
目录标题 1.前言(闲话) 2.硬件连接 3.软件代码---OpenMV端 4.软件代码---STM32端 5.利用PC端测试数据数据是否发送接收正常 6.学习补充 (代码看不懂的时候可以来看一下) ...
- openmv和stm32串口通信完成二维码识别
openmv和stm32串口通信完成二维码识别 文章目录 前言 一.所用的硬件: 二.openmv端 2.stm32端 总结 前言 注:我只是个大一的小白,本文只完成基本功能,希望能帮助有困惑的人(我 ...
- 2021电赛F题智能送药小车方案分析(openMV数字识别,红线循迹,STM32HAL库freeRTOS,串级PID快速学习,小车自动返回)
2021全国大学生电子设计竞赛F题智能送药小车 前提:本篇文章重在分享自己的心得与感悟,我们把最重要的部分,摄像头循迹,摄像头数字识别问题都解决了,有两种方案一种是openARTmini摄像头进行数字 ...
- 嵌入式学习笔记——STM32的USART通信概述
文章目录 前言 常用通信协议分类及其特征介绍 通信协议 通信协议分类 1.同步异步通信 2.全双工/半双工/单工 3.现场总线/板级总线 4. 串行/并行通信 5. 有线通信.无线通信 STM32通信 ...
- OpenMv和STM32通信
OpenMv和STM32通信 OpenMv和STM32通信问题 OpenMv和STM32通信 前言 一.OpenMv配置 1.第一种发送方法 2.第二种发送方法 二.Stm32配置 总结 前言 最近一 ...
最新文章
- vue设置一个简单的计算器
- 未来计算在“云-端”
- HTML 转 PDF 之 wkhtmltopdf
- Python多线程原理与实现
- 谈谈无头电商 - headless commerce
- 两台电脑通过usb共享网络_怎样让电脑通过手机共享上网?
- java代码中的缓存类怎么找,JAVA缓存的实现 - dreamcloudz的个人空间 - OSCHINA - 中文开源技术交流社区...
- python笔记(一)获取当前目录路径和文件(抄录)
- Skyfree退休公告
- SketchUp最适用新手的二十多款SU插件
- 虚拟化部署----USB Server
- 图的遍历 —— 广度优先遍历
- 给windows7系统盘瘦身
- wincc随机数的生成
- Android初学之十二:Broadcast
- Spring|Spring知识点总结思维导图
- css+js+jq实训笔记
- 【python】根据pixiv网站的图片url下载图片到本地
- cmd 下登陆ftp及相关操作
- GitChat文章推荐
热门文章
- System.IO.Directory.GetCurrentDirectory与System.Windows.Forms.Application.StartupPath的用法
- 8月!校招提前批的黄金期和末尾期!
- html 静止横屏,CSS实现Html页面强制横屏
- IO流(常用流都有)
- 网络基础(二)之TCP/UDP协议
- 【Python】Python端口占用测试(检测Socket)
- 高级程序员如何面对职场压力?(3)--明确目标赢在职场
- 内存泄漏的检测、定位和解决经验总结
- Exp4 恶意代码分析 20164314
- 180303 逆向-抵御静态分析(2)