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, nn

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)

# 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中在未规定指定的传出数据时都是默认传输字符串。剩下的就是在串口助手那里看是否有数据过来

  • 24
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: OpenMV是一种小型嵌入式计算机视觉系统,它可以帮助我们实现边框数字识别。首先,我们需要通过OpenMV的摄像头模块拍摄到包含数字边框的图像。然后,利用OpenMV的图像处理库和算法,我们可以对该图像进行预处理,例如调整亮度、对比度、裁剪等,以便更好地识别数字。接下来,我们可以利用OpenMV的机器学习库,如KNN分类器或卷积神经网络(CNN),对预处理后的图像进行特征提取和数字分类。训练一个模型来识别数字边框样式的数据集。当处理一个新的图像时,我们可以使用训练好的模型来预测数字的位置和值。最后,OpenMV可以通过串口或无线连接与其他设备进行通信,将识别到的数字结果传输给外部主机或显示设备。通过OpenMV识别边框数字应用,我们可以实现自动化的数字边框识别系统,可以应用于各种领域,如自动计数、物体识别等。 ### 回答2: OpenMV是一款基于MicroPython的开源机器视觉项目,具有丰富的图像处理功能。要使用OpenMV识别边框数字,可以按照以下步骤进行: 首先,通过OpenMV官方提供的示例或者自己编写代码,将摄像头模块连接到OpenMV主板上,并启动摄像头。然后,使用OpenMV提供的图像采集函数从摄像头获取图像。 接下来,对获取的图像进行预处理。可以使用OpenMV的图像处理函数对图像进行二值化、滤波、降噪等操作,以便更好地进行数字识别。 然后,使用OpenMV数字识别功能进行边框数字识别OpenMV提供了各种数字识别算法,比如基于模板匹配的算法、基于机器学习的算法等。可以选择合适的算法,并进行相应的配置和训练,以实现边框数字的准确识别。 最后,根据识别结果进行相应的处理。可以使用OpenMV的串口通信功能将识别到的数字发送给外部设备,或者通过OpenMV的屏幕显示功能直接显示识别结果。 总之,OpenMV提供了丰富的图像处理和数字识别功能,可以很方便地用于边框数字识别。用户只需按照上述步骤进行配置和操作,即可实现准确的边框数字识别

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值