论如何用逐飞官方提供的MT9V304类型的摄像头进行赛道巡线以及摄像头数据处理

1.官方所提供的摄像头例子,已经教会的最基本的摄像头初始化,首先应该打开摄像头相关的例程查看与此类摄像头相关的代码以及函数,最重要的是学会寻找摄像头返回图像的数组,因为对摄像头数据的处理之后都是在这个二维数组上的,首先讲一下这个二维数组的格式,官方所提供的是一个长188宽120个单位的数组。这是可以更改的,根据你所选择的摄像头的长和宽,于此同时会生成对应的二维数组。但是你所选择的二位数组不得超过摄像头的上限。根据摄像头的类型分为130度摄像头和140度摄像头等各种各样的摄像头。这两种摄像头分别对应着不同大小上限的二维数组。但是我们之所以要修改这个数组的大小,其实是为了更之后我们之后图像的处理,因为图像处理是处理非常大的数据量,对芯片的性能消耗的极其的剧烈。一旦处理不好就回导致芯片的卡死。

当你在进行某些计算量比较大的运算或算法是,例如逆透视,还有无线图像传输以及把八邻域算法和赛道边界生长算法等还有诸多的常见的赛道检测算法。所以你要合理分配的芯片的资源。芯片的算力是有限的,但是你需要去优化代码,去实现在有限的芯片算力范围内实现你想要的图像处理的效果在本次我们所采用的摄像头曲线算法里,我先讲八邻域赛道边缘生长算法。、

本次比赛所使用的摄像头为总转风摄像头,他是一个灰度摄像头能到返回一个二维数组,及每个像素点的灰度值,至于灰度值是什么我相信我不用讲,他的取值范围是0-256之间,从白色一点点过渡到黑,这都不懂你们就自己查吧!至于具体算法是怎么运行的,我就先不讲了。先告诉你们,运用这个算法,你们会得到什么?你们会得到赛道边缘的生长方向以及赛道两侧边线的值,那你们就能得到赛道中线的值,那怎么将其以用在pid的上面呢?pid总共有以下几个变量,kp\ki\kd,以及采样周期和实际值和目标值,那么在当时的这个情况下,我们该如何结合实际去是实现这个巡线呢?

下面我来实际分析一下这几个变量应该如何使用呢?

首先明确一个定义:那就是何为赛道的中线值,定义赛道的中线值是由赛道所决定的,但是摄像头的中间值不是赛道的中间值,一定要区分开什么叫摄像头的中间值,什么叫赛道的中间值。那么怎么判断车体所在的位置,那就是用摄像头的中间值,因为在安装摄像头时,摄像头一般都安装在车体的正中心,所以摄像头的中间值就是车体的中间值,那设想,车辆在行使时,什么情况下会使得车辆沿着赛道中心行驶呢?那就是让赛道中心和摄像头中心重合。即通过调整车辆的行驶角度去使他们二者重合,那么此时就应该让摄像头的中间值做为目标值,而赛道的中心线是实际值 ,这个时候,很多人可能会好奇并且感到疑惑,为什么是让摄像头的中间值作为目标值,而不是让赛道的中线,作为目标值,这是一个很重要的问题,也是必须要明确的一点。因为这个问题及其的重要。

我来区分一下,pid的目标值是为了让被控变量达到的目标值,如果让赛道中间值作为目标值,而摄像头的中线值,作为实际值,我们首先会发现,这个被控量——摄像头的中线值无法移动,其实固定值,所以完全没有意义。而相反的话用赛道的中线值作为被控量的话,这样就会通过对车体位置的调整去实现赛道中线值与摄像头中线值重合,去实现这么目标。这就是巡线pid的大体结构。至于八邻域算法可以晚上见面讲,因为这个八邻域算法,比较复杂。我靠纯手打字不太方便。

总之你们首先要写一个类似这样的结构,然后我会教你们八邻域算法,以及如何移植八邻域算法。你们加油!争取这个月末能实现巡线

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是一个基本的使用MT9V03X灰度摄像头进行室外巡线的C语言代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #include "MT9V03X.h" // 包含MT9V03X灰度摄像头的头文件 #define PI 3.1415926 // 宏定义 #define WIDTH 320 #define HEIGHT 240 #define THRESHOLD 100 // 二值化阈值 #define LINE_THRESHOLD 200 // 线段检测阈值 #define MIN_LENGTH 20 // 最小线段长度 // 全局变量 unsigned char image[WIDTH][HEIGHT]; // 存储灰度图像 unsigned char binImage[WIDTH][HEIGHT]; // 存储二值化图像 unsigned char lineImage[WIDTH][HEIGHT]; // 存储线段检测图像 int lineCount; // 检测到的线段数量 int lineX1[100], lineY1[100], lineX2[100], lineY2[100]; // 线段的端点坐标 // 函数声明 void binarizeImage(); // 二值化图像 void detectLines(); // 检测线段 void drawLines(); // 绘制线段 void setMotorSpeed(int leftSpeed, int rightSpeed); // 设置电机速度 int main() { MT9V03X_Init(); // 初始化MT9V03X灰度摄像头 while(1) { MT9V03X_StartCapture(); // 开始采集图像 while(!MT9V03X_CaptureDone()); // 等待采集完成 MT9V03X_GetImage(image); // 获取采集到的图像 binarizeImage(); // 二值化图像 detectLines(); // 检测线段 drawLines(); // 绘制线段 setMotorSpeed(100, 100); // 设置电机速度 } return 0; } // 二值化图像 void binarizeImage() { int i, j; for(i = 0; i < WIDTH; i++) { for(j = 0; j < HEIGHT; j++) { if(image[i][j] > THRESHOLD) { binImage[i][j] = 255; } else { binImage[i][j] = 0; } } } } // 检测线段 void detectLines() { int i, j, k; // 初始化线段计数器 lineCount = 0; // 清空线段端点坐标数组 for(i = 0; i < 100; i++) { lineX1[i] = 0; lineY1[i] = 0; lineX2[i] = 0; lineY2[i] = 0; } // 对二值化图像进行线段检测 for(i = 1; i < WIDTH - 1; i++) { for(j = 1; j < HEIGHT - 1; j++) { if(binImage[i][j] == 255) { // 搜索8邻域 for(k = 0; k < 8; k++) { int x = i + cos(k * PI / 4); int y = j + sin(k * PI / 4); if(binImage[x][y] == 0) { lineCount++; lineX1[lineCount] = i; lineY1[lineCount] = j; lineX2[lineCount] = x; lineY2[lineCount] = y; break; } } } } } } // 绘制线段 void drawLines() { int i, j, k; for(i = 1; i < WIDTH - 1; i++) { for(j = 1; j < HEIGHT - 1; j++) { lineImage[i][j] = 0; } } for(k = 1; k <= lineCount; k++) { int dx = lineX2[k] - lineX1[k]; int dy = lineY2[k] - lineY1[k]; int length = sqrt(dx * dx + dy * dy); if(length >= MIN_LENGTH) { for(i = 0; i < length; i++) { int x = lineX1[k] + i * dx / length; int y = lineY1[k] + i * dy / length; lineImage[x][y] = 255; } } } } // 设置电机速度 void setMotorSpeed(int leftSpeed, int rightSpeed) { // TODO: 实现设置电机速度的代码 } ``` 注意,上述代码只是一个基本的示例,需要根据实际情况进行修改和完善。在实际应用中,还需要加入很多其他的功能,例如图像预处理、车辆控制、PID控制等等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

长了牙的无牙仔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值