智能车制作
标题:
【阐释者】单双处理 引导线黑白背景兼容 实车验证
[打印本页]
作者:
vireague
时间:
2015-4-2 10:04
标题:
【阐释者】单双处理 引导线黑白背景兼容 实车验证
CCD数据通过线数分析赛道类型,这是我自创的方案,具体方法见我之前的帖子(那个版本还不完善,有很多问题,但是思路一样),望多多交流,多多指导。
作者:
vireague
时间:
2015-4-2 10:14
手机发不了图片,中午补上。
作者:
zhou1994
时间:
2015-4-2 10:26
不明觉厉的样子
作者:
麦籽小立
时间:
2015-4-2 10:28
:D:D:D:D:D
作者:
lions
时间:
2015-4-2 10:30
open and share
:lol:lol浪险到不行
作者:
六步上篮
时间:
2015-4-2 10:33
坐等上图
作者:
vireague
时间:
2015-4-2 12:45
/***************************************************************
名称:CCD相关函数
输入:
输出:
描述:
:
****************************************************************/
#include "common.h"
#include "include.h"
/***************************************************************
名称:基本定义
输入:
输出:
描述:
:
****************************************************************/
#define SOBEL_MIN 10 //最小跳变沿距离
#define SOBEL_BIN_MIN 100 //CCD最小处理跳变沿阈值
#define CCD_recovery 0.8 //角度校正 CCD 数据
#define CCD_BIN_RATE 0.6 //CCD导数二值化阈值数据
#define LINE_width_MIN 40 //允许的最小路宽
#define CCD_CENTER_WIDTH_MAX 5
#define WAY_anxious 0 //切线比例 越大跑法内切越大
uint8 CCD_BUFF[TSL1401_SIZE]; //0 原图 1 2 二值化图
int16 tempArray[TSL1401_SIZE]; //SOBEL 导数图
uint8 tempArray_bin[TSL1401_SIZE]; //SOBEL 导数二值图
uint8 tempArray_creat[TSL1401_SIZE]; //边线图
int16 WAY_value = 0; //方向偏移 - 左偏 + 右偏
uint8 right_angle_state = 0;
char CCD_exposure_time = 2; //曝光时间
int16 WAY_value_sorce = 0; //CCD???????
uint8 LINE_width = 0;
int16 thresholding_max = 0; //导数阈值 (程序计算)
int16 thresholding_min = 0; //导数阈值 (程序计算)
int16 LINE_L[10];
int16 LINE_R[10];
char LINE_L_number = 0; //线数
char LINE_R_number = 0; //线数
char temp;
char CROSS_static = 0; // 1直线 2弯道 3人字路口 4障碍 6右直角 7左直角 8十字路口
/***************************************************************
名称:函数声明
输入:
输出:
描述:
:
****************************************************************/
void CCD_sobel(void); //求导声明
void CCD_line_count(void); //线数计算
void CCD_measure(void);
/***************************************************************
名称:CCD初始化
输入:
输出:
描述:
:
****************************************************************/
void CCD_init(void)
{
tsl1401_set_addrs(TSL1401_MAX,(uint8 *)&CCD_BUFF[0]);
tsl1401_init(); //初始化 线性CCD ,配置 中断时间为 time
}
/***************************************************************
名称:CCD采集与处理
输入:
输出:
描述:
:
****************************************************************/
void CCD_hand(void)
{
tsl1401_get_img(); //采集 线性CCD 图像
CCD_sobel(); //导数计算
CCD_line_count();//线数计算
CCD_measure();
}
/***************************************************************
名称:导数计算
输入:
输出:
描述:
:
****************************************************************/
void CCD_sobel()
{
int16 gradX;
int16 thresholding_deal_max = 0;
int16 thresholding_deal_min = 0;
//CCD_BUFF[0] = CCD_BUFF[1];
//CCD_BUFF[127] = CCD_BUFF[126];
for (int j = 2; j <= 125; j++)
{
gradX = CCD_BUFF[j + 1] + CCD_BUFF[j + 2] - CCD_BUFF[j - 1] - CCD_BUFF[j - 2];
tempArray[j] = gradX; //CCD 导数图 tempArray
if(tempArray[j] > thresholding_deal_max)
{
thresholding_deal_max = tempArray[j];
}
if(tempArray[j] < thresholding_deal_min)
{
thresholding_deal_min = tempArray[j];
}
}
thresholding_max = thresholding_deal_max; //保存导数最大值
thresholding_min = thresholding_deal_min; //保存导数最大值
if(thresholding_max < SOBEL_BIN_MIN)
{
thresholding_max = SOBEL_BIN_MIN;
}
if(thresholding_min > -SOBEL_BIN_MIN)
{
thresholding_min = -SOBEL_BIN_MIN;
}
for (int i = 0; i < 128; i++)
{
tempArray_bin[i] = 120;
if (tempArray[i] > (int16)(thresholding_max*CCD_BIN_RATE) )
{
tempArray_bin[i] = 250; //bin 存储导数阈值
}
if (tempArray[i] < (int16)(thresholding_min*CCD_BIN_RATE) )
{
tempArray_bin[i] = 0; //bin 存储导数阈值
}
}
}
/***************************************************************
名称:
输入:
输出:
描述:
:
****************************************************************/
void CCD_line_count()
{
char line_L_num = 1;
char line_R_num = 1;
temp = (char)(ABS(ANGLE_final) * CCD_recovery); //计算还原数据
int16 LINE_all_L[10];
int16 LINE_all_R[10];
LINE_all_L[0] = -SOBEL_MIN;
LINE_all_R[0] = 127 + SOBEL_MIN;
/*********************************************
*名称:查线
********************************************/
for(int i = 0; i < 128; i++)
{
if(tempArray_bin[i] == 250)
{
if(i - LINE_all_L[line_L_num - 1] >= SOBEL_MIN)
{
LINE_all_L[line_L_num] = i;
line_L_num++;
}
else
{
LINE_all_L[line_L_num - 1] = (int16) ( ( i + LINE_all_L[line_L_num - 1]) /2 );
}
}
}
for(int i = 127; i >= 0; i--)
{
if(tempArray_bin[i] == 0)
{
if(i - LINE_all_R[line_R_num - 1] <= -SOBEL_MIN)
{
LINE_all_R[line_R_num] = i;
line_R_num++;
}
else
{
LINE_all_R[line_R_num - 1] = (int16) ( ( i + LINE_all_R[line_R_num - 1]) /2 );
}
}
}
LINE_L_number = line_L_num - 1; //LINE_number为图中的线数
LINE_R_number = line_R_num - 1; //LINE_number为图中的线数
for(int i = 0; i < LINE_L_number; i++)
{
LINE_L[i] = (int16)( (LINE_all_L[i + 1] - 64) - temp*(LINE_all_L[i + 1] - 64)/64);
}
for(int i = 0; i < LINE_R_number; i++)
{
LINE_R[i] = (int16)( (LINE_all_R[i + 1] - 64) - temp*(LINE_all_R[i + 1] - 64)/64);
}
for(int i = 0; i < 128; i++)
{
tempArray_creat[i] = 120;
}
for(int i = 0; i < LINE_L_number; i++)
{
tempArray_creat[LINE_L[i] + 64] = 250; //CRE 为生成线后的图 没有使用 仅是看
}
for(int i = 0; i < LINE_R_number; i++)
{
tempArray_creat[LINE_R[i] + 64] = 0; //CRE 为生成线后的图 没有使用 仅是看
}
}
/***************************************************************
名称:
输入:
输出:
描述:
:
****************************************************************/
void CCD_measure(void)
{
switch(LINE_L_number)
{
case 0:
{
switch(LINE_R_number)
{
case 0:
{
WAY_value = 0;
}break;
case 1:
{
// if(right_angle_state == 1)
// {
//
// right_angle_state = 0;
// WAY_value = 90;
// }
// else
// {
WAY_value = LINE_R[0] - LINE_width/2;
// }
}break;
case 2:
{
;
}break;
default:
{
;
}break;
}
}break;
case 1:
{
switch(LINE_R_number)
{
case 0:
{
// if(right_angle_state == 1)
// {
//
// right_angle_state = 0;
// WAY_value = 90;
// }
// else
// {
WAY_value = LINE_L[0] + LINE_width/2;
// }
}break;
case 1:
{
if(LINE_L[0] < LINE_R[0])
{
WAY_value = (LINE_L[0] + LINE_R[0])/2;
if((LINE_R[0] - LINE_L[0]) > LINE_width_MIN)
{
LINE_width = LINE_R[0] - LINE_L[0];
}
}
else
{
if(LINE_L[0] - LINE_R[0] <= CCD_CENTER_WIDTH_MAX)
{
WAY_value = (LINE_L[0] + LINE_R[0])/2; //重复流程
}
}
}break;
case 2:
{
;
}break;
default:
{
;
}break;
}
}break;
case 2:
{
switch(LINE_R_number)
{
case 0:
{
;
}break;
case 1:
{
;
}break;
case 2:
{
//CROSS_static = 4;
//led(BEEP,LED_OFF); //蜂鸣器响
//DELAY_MS(500);
//led(BEEP,LED_ON); //蜂鸣器响
}break;
default:
{
;
}break;
}
}break;
default:
{
;
}break;
}
/*********************************************
*名称:切内道补偿数值
********************************************/
WAY_value_sorce = WAY_value;
WAY_value = (int)(WAY_value + (float)(WAY_value)/64*WAY_anxious);
}
作者:
旋风麦林
时间:
2015-4-2 14:28
不明觉厉的样子。。
作者:
1205032010
时间:
2015-4-2 14:53
6666666666
作者:
1908572033
时间:
2015-4-2 15:07
顶啊顶
作者:
黑色枫夜
时间:
2015-4-2 16:19
66666
作者:
浅笑无痕
时间:
2015-4-2 20:29
6666的感觉
作者:
Moonshine
时间:
2015-4-5 16:26
谢谢啦,很是受教
作者:
自动化1202
时间:
2015-4-5 17:28
:lol:lol
作者:
宇宙开拓
时间:
2015-4-7 21:07
问一下楼主,你是怎么解决旁边赛道的干扰的?
作者:
xianyu1993
时间:
2015-4-21 16:19
宇宙开拓 发表于 2015-4-7 21:07
问一下楼主,你是怎么解决旁边赛道的干扰的?
用60~90的镜头采不到旁边赛道··
作者:
wyx225913
时间:
2015-4-23 12:11
好厉害
作者:
申继鹏
时间:
2015-4-23 12:40
可否分享下楼主的直立,速度,方向控制和CCD曝光时间中断分配时间思路?
作者:
乁year
时间:
2015-4-23 12:51
好厉害的样子
作者:
xianyu1993
时间:
2015-5-14 18:15
好吧 问题来了 楼主是怎么解决旁边赛道干扰的!!!我连续欧姆弯第一个弯接第二个弯直接当中心线跑了
欢迎光临 智能车制作 (http://111.231.132.190/)
Powered by Discuz! X3.2