毕业设计 基于stm32与openmv的目标跟踪系统

news2024/9/23 15:24:10

文章目录

  • 0 前言
  • 课题简介
  • 设计框架
  • 3 硬件设计
  • 4 软件设计
    • 对被测物体的识别
    • 判断被测物体所在区域
  • 5 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 基于stm32与openmv的目标跟踪系统

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:5分

在这里插入图片描述

🧿 项目分享:

https://gitee.com/sinonfin/sharing


课题简介

随着智能化技术的迅猛发展,网络智能视频监控系统也得到了广泛的应用。视频监控系统经历了从模拟化向数字化、网络化、智能化的发展过程,目标检测和跟踪技术是计算机视觉的重要组成部分,也是实现监控系统智能化的基础,因其广泛的应用前景而成为近年来的研究热点。本文通过OpenMV作为是识别模块去识别被测物体(以红色小球为例),当其识别到红色小球后,判断小球中心点所在的区域信息,并将其区域标志位通过串口发送给STM32,当STM32接收到位置信息后对x轴、y轴的两个舵机参数进行操作,最后通过定时器输出合适的PWM波,控制舵机旋转相应的角度,使OpenMV摄像头对准被测物体,以实现物体追踪功能。

设计框架

主要分为两个方面:一个是OpenMV识别部分,另一个是STM32控制部分。通过OpenMV对被测物体进行捕捉,所用的被测物体为红色小球,OpenMV编程时,先对红色的色域进行调整,在识别到红色后,对红色进行判断,判断出识别区域中红色区域最大的部分,此举在过滤掉背景中存在小部分红色区域,造成对识别的干扰,识别到红色小球后,用矩形框将其框住,并显示矩形框的中心位置,判断中心位置所在区域,并将区域的标志信息会通过串口传递给STM32,STM32接收到数据后进行相应动作,使定时器输出PWM波,控制舵机旋转相应的角度,使OpenMV摄像头对准被测物体,以实现物体追踪功能。主要研究内容如下:

  • 1.通过OpenMV识别出被测物体(以红色小球为例)。
  • 2.在OpenMV识别出目标物体后,判断物体所在区域,将区域信息通过串口传输给STM32。
  • 3.利用STM32的串口部分的应用及原理知识,对接收到的数据进行处理。
  • 4.利用STM32的应用及原理知识,对处理好的数据进行判断后,对舵机进行控制。
  • 5.利用STM32的定时器部分和PWM控制的应用及原理知识,控制舵机,使其转动适当角度,使OpenMV对准目标物体。主控制图如图所示。

在这里插入图片描述
舵机控制逻辑

在这里插入图片描述

3 硬件设计

硬件连接部分使用杜邦线连接,连接如下:3S锂电池接稳压板输入端以及直接给LED补光板供电,稳压板输出端接OpenMV的VIN和GND引脚、STM32的5V和GND引脚以及两个舵机的正(红色)负(棕色)极。OpenMV的P4引脚(串口3的TX)接STM32的PA10引脚(串口1的RX),OpenMV的P5引脚(串口3的RX)接STM32的PA9引脚(串口1的TX),STM32的PC7引脚(定时器3通道2)接x轴的舵机的信号线(橙黄色),STM32的PC7引脚(定时器3通道1)接y轴的舵机的信号线(橙黄色)。

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

4 软件设计

软件部分的功能主要分为两部分,一个是OpenMV部分,另一是STM32部分,OpenMV主要实现功能:完成被测物体的识别、寻找最大色块区域、判断被测物体所在区域、通过串口发送被测物体的位置信息。STM32部分主要实现功能:使用串口接收OpenMV发来的数据、通过定时器输出PWM波、以及实现控制舵机旋转追踪的目的。

整体逻辑

在这里插入图片描述

对被测物体的识别

本设计中被测物体为一个红色小球,因此对于物体的识别主要为颜色识别,在编程中首先需要对OpenMV的红色的阈值进行调整,意在告诉OpenMV“什么是红色”,打开阈值编辑器,对LAB的阈值进行调整,使二进制图像中只有红色区域的映像
在这里插入图片描述

import sensor, image, time, pyb
ensor.reset() # 初始化摄像头传感器.
sensor.set_pixformat(sensor.RGB565) # 使用RGB565.
sensor.set_framesize(sensor.QVGA) # 分辨率:320*240
sensor.skip_frames(10) # 让新设置生效.
sensor.set_auto_whitebal(False) # 关闭自动白平衡.
clock = time.clock() # Tracks FPS.
red_threshold = (14, 68, 11, 70, 9, 56)  #红色阈值设定
while(True):
img = sensor.snapshot()  # 拍照并返回图像.
blobs = img.find_blobs([red_threshold])
img.draw_rectangle(blobs)
img.draw_cross(blobs.cx(), blobs.cy())

判断被测物体所在区域

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

import sensor, image, time, pyb
from pyb import UART

red_threshold = (14, 68, 11, 70, 9, 56) #红色阈值设定

sensor.reset() # 初始化摄像头传感器.
sensor.set_pixformat(sensor.RGB565) # 使用RGB565.
sensor.set_framesize(sensor.QVGA) # 使用QVGA.
sensor.skip_frames(10) # 让新设置生效.
sensor.set_auto_whitebal(False) # 关闭自动白平衡.
clock = time.clock() # Tracks FPS.

uart = UART(3, 115200)
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

led = pyb.LED(1)
while(True):
    img = sensor.snapshot() # 拍照并返回图像.
    blobs = img.find_blobs([red_threshold])
    x_max = 320
    x_min = 0
    x_1 = 115
    x_2 = 185

    y_max = 240
    y_min = 0
    y_1 = 95
    y_2 = 145

    if blobs:
        max_blob=find_max(blobs)
        print('sum :', len(blobs))
        img.draw_rectangle(max_blob.rect())
        img.draw_cross(max_blob.cx(), max_blob.cy())
        if max_blob.cx()>= x_min  and max_blob.cx() <= x_1 and\
max_blob.cy() >= y_2 and max_blob.cy() <= y_max :
            flag = 1
        if max_blob.cx()>= x_2 and max_blob.cx() <= x_max and\
 max_blob.cy() >= y_2 and max_blob.cy() <= y_max :
            flag = 2
        if max_blob.cx()>= x_min and max_blob.cx() <= x_1 and\
 max_blob.cy() >= y_min and max_blob.cy() <= y_1 :
            flag = 3
        if max_blob.cx()>= x_2 and max_blob.cx() <= x_max and \
max_blob.cy() >= y_min and max_blob.cy() <= y_1 :
            flag = 4
        if max_blob.cx()> x_1 and max_blob.cx() < x_2 and\
 max_blob.cy() > y_1 and max_blob.cy() < y_2 :
            flag = 5
        output_str="%d" %flag 
        led.on()
        print('you send:',output_str)
        uart.write(output_str+'\r\n')
    else:
        print('not found!')
        led.off()
STM32程序:

main.c:
#include "STM32f10x.h"
#include "control.h"
#include "Systick.h"
#include "usart.h"		
#include "pwm.h"

int main()
{
	Systick_init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 
	USART1_Init(115200);	
	TIM3_CH2_PWM_Init(20000-1,72-1); //20ms
	TIM3_CH1_PWM_Init(20000-1,72-1);
	//舵机角度参数:19500-17500(前者为0°,后者为180°)
	TIM_SetCompare2(TIM3,19500);//x轴角度初始化,下面的舵机。
	TIM_SetCompare1(TIM3,18700);//y轴角度初始化,上面的舵机。
	Delay(2500);
	while(1);
}

pwm.c:
#include "pwm.h"

void TIM3_CH2_PWM_Init(u16 per,u16 psc)//控制x轴舵机(引脚:PC7)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	/* 开启时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
/* GPIO配置 */
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOC,&GPIO_InitStructure);	
/* GPIO重映射 */
	GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//改变指定管脚的映射	
	TIM_TimeBaseInitStructure.TIM_Period=per;   //自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;  
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);	
/* PWM参数配置 */
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC2Init(TIM3,&TIM_OCInitStructure); //输出比较通道2初始化
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable); 
	TIM_ARRPreloadConfig(TIM3,ENABLE);//使能预装载寄存器	
	TIM_Cmd(TIM3,ENABLE); //使能定时器
}

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

5 最后

🧿 项目分享:

https://gitee.com/sinonfin/sharing

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 负载均衡介绍之LVS工作模式-NAT转发模式

Linux 负载均衡介绍之LVS工作模式-NAT转发模式 图示&#xff1a; 工作原理&#xff1a; ①.客户端将请求发往前端的负载均衡器&#xff0c;请求报文源地址是CIP(客户端IP),后面统称为CIP)&#xff0c;目标地址为VIP(负载均衡器前端地址&#xff0c;后面统称为VIP)。 ②.负载…

RK3568平台开发系列讲解(视频篇)视频渲染OpenGL ES是什么

🚀返回专栏总目录 文章目录 一、什么是OpenGL ES二、上下文环境三、OpenGL(ES)的用途四、OpenGL 渲染管线五、创建显卡执行程序5.1、创建 Shader5.2、创建 Program沉淀、分享、成长,让自己和他人都能有所收获!😄 📢渲染并不单单是要把画面绘制到屏幕上,更多的是需要…

VirtualBox启动问题记录

很久之前安装过的虚拟机&#xff0c;虚拟机文件是安装在移动硬盘上的&#xff0c;最近在做redis集群试验的时候&#xff0c;打算重新使用一下这个虚拟机&#xff0c;在启动的时候出现了一些问题&#xff0c;特此记录一下&#xff0c;便于后面再出现此问题时不知所措。 实体机操…

ChatGPT 这玩意也太猛了!程序员朋友们,我在此严正呼吁大家:端好饭碗,谨防 AI!

大家周二好呀。 最近几天大火的 ChatGPT 你玩了吗&#xff1f; 如果你不知道它是个什么东西&#xff0c;那么我让它给你来个自我介绍&#xff1a; ​说白了&#xff0c;就是一个可以对话的人工智能。 我开始以为就是一个升级版的“小爱同学”&#xff0c;“小度小度”&#x…

第一个MyBatis程序

目录 一、新建项目 二、设置数据库和MyBatis的配置 &#x1f351;配置数据库的连接信息 &#x1f351;配置MyBatis XML存放位置和命名规则 三、MyBatis实现查询操作 &#x1f34e;MyBatis的组成 &#x1f34e;使用MyBatis实现查询功能 &#x1f34e;SpringBoot单元测…

TF卡格式化了怎么办?tf卡数据恢复,看这3个方法

现在手机存储卡都很普及&#xff0c;TF卡是最常见的存储卡之一。但是你知道吗&#xff1f;TF卡也会有问题&#xff0c;比如出现误删数据&#xff0c;或者把数据格式化。因为手机内存有限&#xff0c;我们经常会把 TF卡设置为默认的最大空间&#xff0c;这样就可能会出现存储空间…

Java: 字符串indexOf() /substring()/replace() 的使用

需要做的: 获取如下图响应信息html页面中的 fec7f1e4-30e0-41d1-9417-bb4829be51dc 值 一.具体思路&#xff1a; &#xff08;1&#xff09;字符串查找 indexOf()其实就是在字符串中查找其子串第一次出现的位置&#xff0c;如果没有找到该子串&#xff0c;则返回-1 四种用…

三面“有赞”Java岗斩获offer:Spring+JVM+并发锁+分布式+算法

年末离职&#xff0c;年初为面试也筹备挺长一段时间&#xff0c;找了不少复习资料&#xff0c;刷了很多题在网上投了很多简历最终面试了有赞&#xff0c;还有幸拿到offer&#xff01; 本人两年Java开发&#xff0c;本科毕业&#xff0c;计算机专业&#xff0c;勤学好问、积极上…

BM(Boyer-Moore) 算法详解

BM算法(Boyer-Moore) BM算法也叫做精确字符集算法&#xff0c;它是一种从右往左比较&#xff08;后往前&#xff09;&#xff0c;同时也应用到了两种规则坏字符、好后缀规则去计算我们移动的偏移量的算法。 坏字符规则 BM 算法是从后往前进行比较&#xff0c;此时我们发现比…

ArcGIS基础:不同方法修改栅格数据像元值

【1】&#xff1a;根据值修改栅格值 原始数据如下所示&#xff1a; 是一个栅格数据&#xff0c;分为三种不同的颜色&#xff0c;三种颜色代表三个不同的数值&#xff0c;如下所示&#xff1a; 如下所示&#xff0c;为1、2、3三个不同值。 下面将栅格值为1 的数据的数值替换…

5年测试,面试结束后被HR怼了..(心塞)

前一阵子向朋友诉苦&#xff0c;我在参加字节跳动面试的时候被面试官怼得哑口无言&#xff0c;场面让我一度十分尴尬。印象最深的就是下面几个问题&#xff1a; 根据你以前的工作经验和学习到的测试技术&#xff0c;说说你对质量保证的理解&#xff1f;非关系型数据库和关系型数…

【免杀前置课——Windows编程】十五、网络编程——C/S,B/S模式分别是什么?WinSocket、Socket传输的定义和其特点、实现简易通信(附代码)

网络编程网络编程C/S:客户端/服务器模式:B/S:浏览器/服务器架构模式。WinSocket:Socket传输的定义和其特点实现简易通信服务器端客户端网络编程 网络分为C/S,B/S两种模式。 C/S:客户端/服务器模式: 服务器端&#xff1a; 首先服务器先启动&#xff0c;并根据客户端请求做出相…

Pytest 的高级用法之插件开发

用过pytest的小伙伴应该都知道&#xff0c;pytest之所以功能强大&#xff0c;是因为pytest的插件非常的多。这是插件大多是pytest的使用者所开发的&#xff0c;今天咱们专门来聊聊如何去自己开发Pytest的插件。 一 pytest插件的介绍 pytest框架采用的是插件系统的模式来设计的…

安装VMware

大纲&#xff1a; 一、VMware简介 VMWare虚拟机软件是一个“虚拟PC”软件&#xff0c;它使你可以在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。 二、VMware摘要笔记 三、VMware安装步骤 1、将VMware Workstation 16 Pro解压后 双击运行第二个应用程序(player)进行…

精品基于springboot的线上跳蚤市场平台

《线上跳蚤市场平台》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 使用技术&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;springboot(ssm) 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&a…

Android 中的权限

1、权限类型 Android 将权限分为不同的类型&#xff0c;包括安装时权限、运行时权限和特殊权限。每种权限类型都指明了当系统授予应用该权限后&#xff0c;应用可以访问的受限数据范围以及应用可以执行的受限操作范围。每项权限的保护级别取决于其类型。 1.1、安装时权限 安…

智慧农业发展,商业计划书撰写,商业模式,ppt亮点

目录 什么是商业模式 中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要_滚动新闻_中国政府网 第五篇 加快数字化发展 建设数字中国 第十五章 打造数字经济新优势 第十六章 加快数字社会建设步伐 第十七章 提高数字政府建设水平 第十八章 营造…

Linux下载安装 RabbitMQ​

压缩包&#xff1a;RabbitMQ-Linux版-Java文档类资源-CSDN下载 一、官网下载&#xff1a; 1、需要先下载RabbitMQ所需要的erl语言环境 官网地址&#xff1a;Downloads - Erlang/OTP 2、下载MQ 官网&#xff1a;Messaging that just works — RabbitMQgithub地址&#xff1a;…

一篇文章,教你彻底掌握接口测试!

Part 01、什么是接口测试 所谓接口&#xff0c;是指同一个系统中模块与模块间的数据传递接口、前后端交互、跨系统跨平台跨数据库的对接。而接口测试&#xff0c;则是通过接口的不同情况下的输入&#xff0c;去对比输出&#xff0c;看看是否满足接口规范所规定的功能、安全以及…

【设计模式】外观模式(Facade Pattern)

外观模式属于结构型模式&#xff0c;主要解决客户程序访问复杂程序中的多个子程序而产生的高耦合度及高复杂度问题&#xff0c;根本目的在于简化接口的调用。例如我们去医院看病&#xff0c;可能要去挂号、门诊、划价、取药&#xff08;子系统角色&#xff09;&#xff0c;这让…