openmv目标追踪小车
时间: 2025-01-03 10:43:00 浏览: 19
### 使用OpenMV进行目标追踪的小车项目
#### 1. 系统概述
为了构建一个能够自动跟踪特定颜色目标的小车,整个系统由两大部分组成:OpenMV用于实时图像处理和目标识别;STM32作为控制器接收来自OpenMV的位置数据并据此调整小车的方向与速度。
#### 2. 开发环境准备
确保拥有最新版本的OpenMV IDE以及支持串口通信开发板如STM32。对于OpenMV来说,推荐使用OpenMV4 Plus型号,因为其性能足以满足大多数应用场景的需求,在测试过程中可达到约8帧每秒的速度[^2]。
#### 3. 图像采集与预处理
通过摄像头模块获取当前视野内的画面,并利用内置函数完成色彩空间转换、二值化等操作来突出显示感兴趣区域(ROI),即待追踪的目标对象的颜色特征。这一步骤有助于提高后续算法效率及准确性。
```python
import sensor, image, time
sensor.reset() # Reset and initialize the sensor.
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.skip_frames(time = 2000) # Wait for settings take effect.
clock = time.clock()
```
#### 4. 目标检测逻辑编写
定义阈值范围以区分不同颜色的对象,当找到匹配项时记录下其中心坐标并通过UART接口发送给微控制器。这里可以采用HSV颜色模型来进行更精确的颜色分类。
```python
red_threshold = [(31, 79, 15, 127, 15, 127)] # Red color threshold.
while(True):
clock.tick() # Update the FPS clock.
img = sensor.snapshot() # Take a picture and return the image.
blobs = img.find_blobs(red_threshold)
if blobs:
largest_blob = max(blobs, key=lambda b:b.pixels())
center_x = int(largest_blob.cx()/2)
center_y = int(largest_blob.cy()/2)
uart.write(str(center_x)+','+str(center_y)+'\n') # Send coordinates over UART
img.draw_rectangle(largest_blob.rect()) # Draw rectangle around detected object
img.draw_cross(largest_blob.cx(), largest_blob.cy()) # And draw cross at its centroid
```
#### 5. 控制策略制定
接收到位置信息后,MCU需要解析这些数据并决定如何改变马达转速从而让车辆朝向指定方向前进。通常情况下会涉及到PID调节器的设计以便获得更加平稳自然的动作效果。
```c++
#include <Arduino.h>
#define LEFT_MOTOR_PIN D2
#define RIGHT_MOTOR_PIN D3
void setup(){
Serial.begin(115200);
pinMode(LEFT_MOTOR_PIN , OUTPUT);
pinMode(RIGHT_MOTOR_PIN, OUTPUT);
}
void loop(){
static float last_error=0;
static float integral=0;
if(Serial.available()){
String dataString = Serial.readStringUntil('\n');
char* token=strtok((char*)dataString.c_str(),",");
while(token!=NULL){
float error = atof(token)-image_center; // Calculate deviation from center
float derivative = error-last_error;
integral +=error;
float output = Kp * error + Ki *integral + Kd *derivative ;
analogWrite(LEFT_MOTOR_PIN ,base_speed-output );
analogWrite(RIGHT_MOTOR_PIN, base_speed+output);
last_error = error;
break;
}
}
delay(20);
}
```
阅读全文