视觉巡线小车——STM32+OpenMV(三)

目录

前言

一、OpenMV代码

二、STM32端接收数据

1.配置串口

2.接收数据并解析

总结



前言

         通过视觉巡线小车——STM32+OpenMV(二),已基本实现了减速电机的速度闭环控制。要使小车能够自主巡线,除了能够精准的控制速度之外,还需要得到小车偏离黑线的差值——即位置偏差。本文将通过OpenMV得到该偏差。

        建议参考内容:

        OpenMV巡线小车 | 星瞳科技

        项目实例 · OpenMV中文入门教程

 系列文章请查看:视觉巡线小车——STM32+OpenMV系列文章 


一、OpenMV代码

        1、初始化外设,如串口等;

        2、运行主要代码,拍照,图像二值化处理,线性回归处理,得到黑线与OpenMV中心线之间的像素点偏差以及偏离角度。

        线性回归算法的原理是寻找一条最佳的直线来拟合数据点集。在视 觉巡线中,这些数据点就是二值化图像中代表线条的像素点。算法会计算这些像素点 的平均值、方差等统计量,并通过最小二乘法等来找到一条最佳的直线。

        3、将得到数据打包,并发送给STM32。

THRESHOLD = (0, 23, -128, 127, -128, 127) # Grayscale threshold for dark things...
import sensor, image, time
from pyb import LED
from machine import UART
import structsensor.reset()
sensor.set_vflip(False)   # 设置OpenMV图像“水平方向进行翻转”
sensor.set_hmirror(False) # 设置OpenMV图像“竖直方向进行翻转”sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQQVGA) # 80x60 (4,800 pixels) - O(N^2) max = 2,3040,000.# 线性回归算法的运算量大,越小的分辨率识别的效果越好,运算速度越快#sensor.set_windowing([0,20,80,40])
sensor.skip_frames(time = 2000)     # WARNING: If you use QQVGA it may take seconds
clock = time.clock()                # to process a frame sometimes.myuart = UART(1, 115200)
# OpenMV RT 只有串口UART(1),对应P4-TX P5-RX; OpenMV4 H7 Plus, OpenMV4 H7, OpenMV3 M7 的UART(1)是P0-RX P1-TX
myuart.init(115200, bits=8, parity=None, stop=1)  #8位数据位,无校验位,1位停止位def send_data_packet(x, y):temp = struct.pack(">bbii",                #格式为小端模式俩个字符俩个整型0xAA,                       #帧头10xBB,                       #帧头2int(x), # up sample by 4    #数据1int(y)) # up sample by 4    #数据2myuart.write(temp)#串口发送
while(True):clock.tick()img = sensor.snapshot().binary([THRESHOLD])''' 截取一张图片,进行 “阈值分割”阈值分割函数image.binary()对图像进行二值化(binary:二元的;由两部分组成的)得到的效果是:将阈值颜色变成白色,非阈值颜色变成黑色'''line = img.get_regression([(100,100)], robust = True)#调用线性回归函数# 对所有的阈值像素进行线性回归# 线性回归的效果就是将我们视野中“二值化”分割后的图像回归成一条直线if (line):rho_err = abs(line.rho())-img.width()/2# 计算我们的直线相对于中央位置偏移的距离(偏移的像素)# abs()函数:返回数字的绝对值  line.rho():返回霍夫变换后的直线p值。if line.theta()>90:theta_err = line.theta()-180else:theta_err = line.theta()# 进行坐标的变换:y轴方向为0°,x轴正方向为90°,x轴负方向为-90°img.draw_line(line.line(), color = 127)print(rho_err,line.magnitude(),theta_err)#line.magnitude()返回一个表示“线性回归效果”的值,这个值越大,线性回归效果越好;# 如果越接近于0,说明我们的线性回归效果越接近于一个圆,效果越差if line.magnitude()>8:send_data_packet(rho_err,theta_err)LED(1).off()else:LED(1).on()LED(2).off()else:LED(2).on()pass#print(clock.fps())

处理前后结果对比:

二、STM32端接收数据

1.配置串口

         由于OpenMV与STM32之间采用串口通讯,所以同样需要在CubeMX进行配置:

 同理也需要开启中断,这里不再赘述,参考上一篇文章。

2.接收数据并解析

        需要加入以下代码,进行初始化:

//全局变量
unsigned char OpenMV_Buf;
int theta_org,rho_org;//初始化处加入
HAL_UART_Receive_IT(&huart2,&OpenMV_Buf,1);

        在串口2中断回调函数中处理如下:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART2 ){
//       printf("OK\n");Rec_proce(OpenMV_Buf);                 HAL_UART_Receive_IT(&huart2,&OpenMV_Buf,1); }
}
void Rec_proce(u8 data)
{/* 局部静态变量:接收缓存 */static u8 RxBuffer[10];/* 数据长度 *//* 数据数组下标 */static u8  data_cnt = 0;/* 接收状态 */static u8 state = 0;/* 帧头1 */if(state==0&&data==0xAA){state=1;}/* 帧头2 */else if(state==1&&data==0xBB){state=2;data_cnt = 0;}/* 接收数据租 */else if(state==2){RxBuffer[data_cnt++]=data;if(data_cnt>=8){state = 0; rho_org   = (int)((RxBuffer[0]<<24) | (RxBuffer[1]<<16) | (RxBuffer[2]<<8) | (RxBuffer[3]));  theta_org = (int)((RxBuffer[4]<<24) | (RxBuffer[5]<<16) | (RxBuffer[6]<<8) | (RxBuffer[7]));            printf("%d,%d\n",rho_org,theta_org);
//            for(int i=0;i<8;i++) printf("%d",RxBuffer[i]);
//            printf("\n\n\n\n");}}/* 若有错误重新等待接收帧头 */elsestate = 0;
}

         如果要使用printf进行打印输出,则需要加入以下代码,这里以串口3为例,如下:

#include <stdio.h>
int fputc(int ch,FILE *f)
{while((USART3->SR & 0x40) == 0);USART3->DR = (uint8_t)ch;return ch;
}

总结

通过本文,使用OpenMV得到中心线偏离黑线的像素点偏差和角度偏差,再将数据打包通过串口发送给STM32,最后在STM32上将数据解析出来,以便后续控制运用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/381308.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信被好友屏蔽朋友圈/拉黑/删除?教你几招悄悄验证

微信这一国民级的社交软件&#xff0c;基本上渗入了大家日常生活的方方面面&#xff0c;沟通、支付、购物、娱乐都可以在上面一站式解决。微信功能虽然很全面&#xff0c;但某些功能细节设计也会让人感到困惑&#xff0c;比如我们被朋友拉黑或者删除&#xff0c;微信是不会通知…

数学建模--优劣解距离法TOPSIS

目录 简介 TOPSIS法的基本步骤 延伸 优劣解距离法&#xff08;TOPSIS&#xff09;的历史发展和应用领域有哪些&#xff1f; 历史发展 应用领域 如何准确计算TOPSIS中的理想解&#xff08;PIS&#xff09;和负理想解&#xff08;NIS&#xff09;&#xff1f; TOPSIS方法在…

【NLP自然语言处理】基于BERT实现文本情感分类

Bert概述 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一种深度学习模型&#xff0c;用于自然语言处理&#xff08;NLP&#xff09;任务。BERT的核心是由一种强大的神经网络架构——Transformer驱动的。这种架构包含了一种称为自注…

宝塔SSL续签失败

我有2个网站a和b&#xff08;文字中用baidu.com替换我的域名&#xff09; b是要续签那个&#xff0c;但续签报错&#xff1a; nginx version: nginx/1.22.1 nginx: [emerg] host not found in upstream "github.com" in /www/server/panel/vhost/nginx/proxy/a.bai…

分享 2 个 .NET EF 6 只更新某些字段的方法

前言 EF 更新数据时&#xff0c;通常情况下&#xff0c;是更新全部字段的&#xff0c;但实际业务中&#xff0c;更新全部字段的情况其实很少&#xff0c;一般都是修改其中某些字段&#xff0c;所以为了实现这个目标&#xff0c;很多程序员通常会这样作&#xff1a; 先从数据库…

Nginx 怎样处理请求的熔断机制?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 Nginx 怎样处理请求的熔断机制&#xff1f;一、什么是熔断机制二、Nginx 中的熔断机制原理&#xff08;一&#xff09;基于错误率&#xff08;二&#xff09;基于…

超级写手:AI笔耕者的未来图谱

在数字化时代,人工智能(AI)正悄然改变着各行各业的传统作业方式。其中,“超级写手”——AI scribes,作为一种新兴的垂直应用场景,正以其独特的魅力吸引着投资者的目光。本文将深入探讨AI写手的市场背景、技术栈、投资策略及其潜在应用领域,带您一窥这个未来写作助手的广…

动手学深度学习——5.卷积神经网络

1.卷积神经网络特征 现在&#xff0c;我们将上述想法总结一下&#xff0c;从而帮助我们设计适合于计算机视觉的神经网络架构。 平移不变性&#xff08;translation invariance&#xff09;&#xff1a;不管检测对象出现在图像中的哪个位置&#xff0c;神经网络的前面几层应该对…

Docker构建LNMP环境并运行Wordpress平台

1.准备Nginx 上传文件 Dockerfile FROM centos:7 as firstADD nginx-1.24.0.tar.gz /opt/ COPY CentOS-Base.repo /etc/yum.repos.d/RUN yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c make && \useradd -M -s /sbin/nologin nginx && \cd /o…

解决 go 引用私有包,安装失败

问题描述 go mod tidy 或者 go run main.go 时&#xff0c;提示失败&#xff0c;例如 no such host&#xff08;设置GOPRIVATE&#xff09;或者 x509: certificate signed by unknown authority 之类的报错&#xff08;设置GOINSECURE&#xff09; 解决 在各种 insteadof 方…

Android音视频—OpenGL 与OpenGL ES简述,渲染视频到界面基本流程

文章目录 OpenGL 简述特点和功能主要组件OpenGL ES当前状态 OpenGL ES 在 Android 上进行视频帧渲染总体流程 OpenGL 简述 OpenGL&#xff08;Open Graphics Library&#xff09;是一个跨平台的、语言无关的应用程序编程接口&#xff08;API&#xff09;&#xff0c;用于开发生…

通过albumentation对目标检测进行数据增强(简单直接)

albumentation官方文档看不懂&#xff1f;xml文件不知道如何操作&#xff1f;下面只需要修改部分代码即可上手使用 要使用这个方法之前需要按照albumentation这个库还有一些辅助库,自己看着来安装就行 pip install albumentation pip install opencv-python pip install json…

昇思25天学习打卡营第25天 | RNN实现情感分类

学习心得&#xff1a;RNN实现情感分类 在自然语言处理&#xff08;NLP&#xff09;的领域中&#xff0c;情感分类是一个极具挑战性的任务&#xff0c;它要求模型能够准确地从文本中识别出情感倾向。通过使用MindSpore框架和RNN模型进行情感分类&#xff0c;我获得了许多有关构…

Springboot项目远程部署gitee仓库(docker+Jenkins+maven+git)

创建仓库 创建一个Springboot项目&#xff0c;勾选web将该项目创建git本地仓库&#xff0c;再创建远程仓库推送上去 创建TestController RestControllerRequestMapping("/test")public class TestController {GetMapping("/hello")public String sayHell…

linux进程优先级——优先值、调度算法、进程性质

前言&#xff1a;本篇内容主要讲解linux下进程的优先级。 优先级的内容相对较少&#xff0c; 最重要的内容就是cpu的调度方法。 内容相对容易理解。 ps&#xff1a;本节内容适合了解冯诺依曼和操作系统的管理方式以及进程PCB的友友们进程观看 进程的优先级是什么 进程的优先级…

智汇云舟:双引擎模式,为合作伙伴带来实在的利润和回报

2024年是智汇云舟新渠道政策的元年&#xff0c;今年上半年&#xff0c;智汇云舟基于视频孪生产品的升级&#xff0c;对合作伙伴的共创模式进行了升级&#xff0c;从以往的“渠道模式”升级为“合伙模式”&#xff0c;从而实现能力升级&#xff0c;为智汇云舟渠道业务的发展带来…

08 模型演化根本 深度学习推荐算法的五大范式

易经》“九三&#xff1a;君于终日乾乾&#xff1b;夕惕若&#xff0c;厉无咎”。九三是指阳爻在卦中处于第三位&#xff0c;已经到达中位&#xff0c;惕龙指这个阶段逐渐理性&#xff0c;德才已经显现&#xff0c;会引人注目&#xff1b;但要反思自己的不足&#xff0c;努力不…

ABAP打印WORD的解决方案

客户要求按照固定格式输出到WORD模板中&#xff0c;目前OLE和DOI研究了均不太适合用于这种需求。 cl_docx_document类可以将WORD转化为XML文件&#xff0c;利用替换字符串方法将文档内容进行填充同 时不破坏WORD现有格式。 首先需要将WORD的单元格用各种预定义的字符进行填充…

《昇思25天学习打卡营第23天|RNN实现情感分类》

使用RNN进行情感分类&#xff1a;基于IMDB数据集的LSTM应用 引言 情感分析是自然语言处理&#xff08;NLP&#xff09;中的一个重要应用&#xff0c;广泛用于电影评论、社交媒体等文本数据的情感分类任务。本文将介绍如何使用递归神经网络&#xff08;RNN&#xff09;实现情感…

使用IDEA编写lua脚本并运行

下载lua https://github.com/rjpcomputing/luaforwindows/releases 是否创建桌面快捷方式&#xff1a;我们的目标是使用IDEA编写lua脚本&#xff0c;所以不需要勾选。后面需要的话&#xff0c;可以到安装目录下手动创建快捷方式 环境变量自动配置 安装后会自动配置好环境变量…