基于Opencv和STM32物理鼠标的目标跟踪器

该文介绍了一个利用STM32最小系统板构建的HID USB鼠标,通过串口接收上位机截图坐标,并利用OpenCV进行图像识别。系统能自动控制鼠标移动,实现自动瞄准功能。主要涉及串口通讯、Win32API截图、OpenCV图像处理和STM32的USB HID设备控制。
摘要由CSDN通过智能技术生成

本文需要使用STM32最小系统板[3]实现一个带有串口的HID USB鼠标,实现STM32可以控制电脑鼠标的移动的功能函数,然后在上位机电脑中调用WIN32 API对整个电脑的桌面进行截图,再把获得的截图存进电脑的指定文件夹中,然后通过OPENCV4对指定文件夹中的指定文件名字的图片进行读取,读取后对图片内容进行识别,获取目标在屏幕中的坐标,然后通过串口通讯的方式发送给STM32实现的物理鼠标,物理鼠标获取到坐标后,先将不停的传送过来的坐标存入设定好的数组中,为了避免重复存入相同的坐标,设置扫描程序[4],当坐标传送过来后,先将坐标与数组中已经存在的坐标进行对比,如果发现坐标已经存在,则该传送过来的坐标作废,不进行操作,如果不存在,则按照从低到高的顺序依次存进数组中,当存满以后,又继续从低到高覆盖数据,反复执行.在通过串口实时获取目标的坐标后,需要在STM32中对获取的坐标进行处理,首先需要设置设置一个屏幕中心值,这个可以在WIN32获取的截图中看到(右键获取的图片,属性->详细情形->图像,然后可以看到图像高度XX像素点,宽度XX像素点,据此得出中心值即可),然后需要自己写一个函数,对目标数组进行扫描,确认数组中是否存在坐标与屏幕中心坐标不一致,如果存在不一致坐标,则控制鼠标向该坐标[5]移动,如果存在多个与屏幕中心坐标不一致的坐标时,则需要再写一个函数,计算每个坐标与屏幕中心坐标之间的直线距离,找出距离屏幕中心最近的坐标,然后控制鼠标移向该目标,以此实现自动瞄准的目的。

样列图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
部分代码

#include “main.h”
#include “usart.h”
#include “usb_device.h”
#include “gpio.h”
#include <stdlib.h>
#include<math.h>

/* Private includes ----------------------------------------------------------/
/
USER CODE BEGIN Includes /
#include “usbd_hid.h”
/
USER CODE END Includes */

/* Private typedef -----------------------------------------------------------/
/
USER CODE BEGIN PTD */
uint8_t zuo[4] = {0,-2,0,0};
uint8_t you[4] = {0,2,0,0};
uint8_t shang[4] = {0,0,-2,0};
uint8_t xia[4] = {0,0,2,0};

extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------/
/
USER CODE BEGIN PD /
/
USER CODE END PD */

/* Private macro -------------------------------------------------------------/
/
USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

uint8_t Rxbuf[8];
uint8_t ACKbuf[]=“ACK world”;
uint8_t ch[8];
int ch1=500;
int ab=0;
uint8_t ge;
uint8_t shi;
uint8_t bai;
uint8_t qian;
uint8_t ge1;
uint8_t shi1;
uint8_t bai1;
uint8_t qian1;
uint16_t zuobiao[20]={960,540};
//int chushi[2]={768,432};
uint16_t chushi[2]={960,540};
int tx1[4];
int tx2[4];
float beilv=1;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------/
void SystemClock_Config(void);
/
USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------/
/
USER CODE BEGIN 0 */

int k;
int dist(int x1,int y1,int x2,int y2)
{
int a,b;
int c;

a=x2-x1;
b=y2-y1;
c=sqrt(aa+bb);
return c;
}
void duibi(uint16_t zuobiao1[],int n,int *k)
{
int s[10];

s[0]=dist(chushi[0],chushi[1],zuobiao1[0],zuobiao1[1]);
s[1]=dist(chushi[0],chushi[1],zuobiao1[2],zuobiao1[3]);
s[2]=dist(chushi[0],chushi[1],zuobiao1[4],zuobiao1[5]);
s[3]=dist(chushi[0],chushi[1],zuobiao1[6],zuobiao1[7]);
s[4]=dist(chushi[0],chushi[1],zuobiao1[8],zuobiao1[9]);
s[5]=dist(chushi[0],chushi[1],zuobiao1[10],zuobiao1[11]);
s[6]=dist(chushi[0],chushi[1],zuobiao1[12],zuobiao1[13]);
s[7]=dist(chushi[0],chushi[1],zuobiao1[14],zuobiao1[15]);
s[8]=dist(chushi[0],chushi[1],zuobiao1[16],zuobiao1[17]);
s[9]=dist(chushi[0],chushi[1],zuobiao1[18],zuobiao1[19]);

    int num=s[0];
    int i;

    for(i=1;i<10;i++)
    {
        if(num>s[i])
        {

            num=s[i];
            *k=i;
        }
    }

}

/* USER CODE END 0 */

/**

  • @brief The application entry point.
  • @retval int
    /
    uint16_t sd[2]={960,540};
    int main(void)
    {
    /
    USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef UartHandle);
/
USER CODE END SysInit */

/* Initialize all configured peripherals /
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MX_USART1_UART_Init();
/
USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1,Rxbuf,sizeof(Rxbuf));

/* USER CODE END 2 */

/* Infinite loop /
/
USER CODE BEGIN WHILE */
int a;
int b;
uint8_t c;

while (1)
{

//  if(ab>=10)
//  {
	//  duibi(zuobiao,20,&k);

//  if(zuobiao[2*k]!=chushi[0]||zuobiao[2*k+1]!=chushi[1])
  if(sd[0]!=chushi[0]||sd[1]!=chushi[1])
  {

// a=zuobiao[2k]-chushi[0];
// b=zuobiao[2
k+1]-chushi[1];
// zuobiao[2k]=960;
// zuobiao[2
k+1]=540;
a=sd[0]-chushi[0];
b=sd[1]-chushi[1];
if(a>0&&b>0)
{
for(int i=0;i<a;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,you,4);
}
for(int i=0;i<b;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,xia,4);
}
}
if(a<0&&b>0)
{
a=-a;
for(int i=0;i<a;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,zuo,4);
}
for(int i=0;i<b;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,xia,4);
}
}
if(a>0&&b<0)
{
b=-b;
for(int i=0;i<a;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,you,4);
}
for(int i=0;i<b;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,shang,4);
}
}
if(a<0&&b<0)
{ a=-a;
b=-b;
// a=abeilv;
// b=b
beilv;
for(int i=0;i<a5;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,zuo,4);
}
for(int i=0;i<b
5;i++)
{
HAL_Delay(1);
USBD_HID_SendReport(&hUsbDeviceFS,shang,4);
}
}

	       sd[0]=zuobiao[0];
	       sd[1]=zuobiao[1];
  }
  //}

// HAL_Delay(999);
// HAL_UART_Transmit(&huart1, Txbuf, sizeof(Txbuf), 100);

// if (HAL_UART_Receive(&huart1,Rxbuf,sizeof(Rxbuf),1000) == HAL_OK)
// {
// HAL_UART_Transmit(&huart1,Rxbuf,sizeof(Rxbuf),100);
// }
//

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

// for(int i=0;i<500;i++)
// {
// HAL_Delay(1);
// USBD_HID_SendReport(&hUsbDeviceFS,zuo,4);
//
// }
// for(int i=0;i<500;i++)
// {
// HAL_Delay(1);
// USBD_HID_SendReport(&hUsbDeviceFS,shang,4);
//
// }
// for(int i=0;i<500;i++)
// {
// HAL_Delay(1);
// USBD_HID_SendReport(&hUsbDeviceFS,you,4);
//
// }

}
/* USER CODE END 3 */
}

/**

  • @brief System Clock Configuration
  • @retval None
    */
    void SystemClock_Config(void)
    {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

/** Initializes the RCC Oscillators according to the specified parameters

  • in the RCC_OscInitTypeDef structure.
    /
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }
    /
    * Initializes the CPU, AHB and APB buses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}

/* USER CODE BEGIN 4 */
int i=0;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
if (UartHandle->Instance == USART1)
{
// ch=Rxbuf[0]*1+Rxbuf[1]*10+Rxbuf[2]*100+Rxbuf[3]*1000;
// ch=ch-1;
// Rxbuf[3]=ch/1000;
// Rxbuf[2]=(ch%1000)/1000;
// Rxbuf[1]=(ch%100)/10;
// Rxbuf[0]=ch%10;
// ch[0]=Rxbuf[0];
// ch[1]=Rxbuf[1];
// ch[2]=Rxbuf[2];
// ch[3]=Rxbuf[3];

// ch=Rxbuf[0]1+Rxbuf[1]10+Rxbuf[2]100+Rxbuf[3]1000;
HAL_UART_Transmit_IT(&huart1,Rxbuf,sizeof(Rxbuf));
ge=Rxbuf[3];
shi=Rxbuf[2];
bai=Rxbuf[1];
qian=Rxbuf[0];
// zuobiao[i]=ge
1+shi
10+bai
100+qian
1000;
sd[0]=ge1+shi10+bai100+qian1000;
ge1=Rxbuf[7];
shi1=Rxbuf[6];
bai1=Rxbuf[5];
qian1=Rxbuf[4];
// zuobiao[i+1]=ge11+shi110+bai1100+qian11000;
sd[1]=ge11+shi110+bai1100+qian11000;
/* if(sd[0]!=zuobiao[0]||sd[1]!=zuobiao[1])
{
if(sd[0]!=zuobiao[2]||sd[1]!=zuobiao[3])
{

            		 if(sd[0]!=zuobiao[4]||sd[1]!=zuobiao[5])
            		                {

            			 if(sd[0]!=zuobiao[6]||sd[1]!=zuobiao[7])
            			                {

            				 if(sd[0]!=zuobiao[8]||sd[1]!=zuobiao[9])
            				                {

            					 if(sd[0]!=zuobiao[10]||sd[1]!=zuobiao[11])
            					                {

            						 if(sd[0]!=zuobiao[12]||sd[1]!=zuobiao[13])
            						                {

            							 if(sd[0]!=zuobiao[14]||sd[1]!=zuobiao[15])
            							                {

            								 if(sd[0]!=zuobiao[16]||sd[1]!=zuobiao[17])
            								                {

            									 if(sd[0]!=zuobiao[18]||sd[1]!=zuobiao[19])
            									                {
            										      zuobiao[i]=sd[0];
            										      zuobiao[i+1]=sd[1];
            								        	    i=i+2;
            								        	    ab=ab+1;
            									                }
            								                }
            							                }
            						                }
            					                }
            				                }
            			                }
            		                }
            	                }
                            }

*/

            HAL_UART_Receive_IT(&huart1,Rxbuf ,sizeof(Rxbuf));//重
    	  /*  if(i==20)
    	    {
    	    i=0;
    	    }

*/
}
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值