金牌会员
 
- 积分
- 1056
- 威望
- 497
- 贡献
- 285
- 兑换币
- 278
- 注册时间
- 2014-7-23
- 在线时间
- 137 小时
- 毕业学校
- 辽宁科技大学
|
/***************************************************************
名称:CCD相关函数
输入:
输出:
描述:
:
****************************************************************/
#include "common.h"
#include "include.h"
/***************************************************************
名称:基本定义
输入:
输出:
描述:
:
****************************************************************/
#define SOBEL_MIN 10 //最小跳变沿距离
#define SOBEL_BIN_MIN 20 //CCD最小处理跳变沿阈值
#define LENTH_WIDTH 20 //双线丢线 判断
#define CCD_recovery 0.8 //角度校正 CCD 数据
#define WAY_value_change_MAX 20 //允许最大坐标变化值
#define LINE_width_MIN 40 //允许的最小路宽
#define WAY_anxious 40 //切线比例 越大跑法内切越大
uint8 CCD_BUFF[TSL1401_SIZE]; //0 原图 1 2 二值化图
uint8 tempArray[TSL1401_SIZE]; //SOBEL 导数图
uint8 tempArray_bin[TSL1401_SIZE]; //SOBEL 导数二值图
uint8 tempArray_creat[TSL1401_SIZE]; //边线图
int16 WAY_value = 0; //方向偏移 - 左偏 + 右偏
int16 WAY_value_sorce = 0; //CCD无内切原始数值
int16 WAY_value_last = 0; //方向偏移 - 左偏 + 右偏
uint8 thresholding = 0; //导数阈值 (程序计算)
uint8 LINE_width = 0;
char LINE_number = 0; //线数
char CCD_exposure_time = 10; //曝光时间
int16 LINE_1[1]; //线数为一时保存的坐标
int16 LINE_2[2];
int16 LINE_3[3];
int16 LINE_4[4];
int16 LINE_1_last[1]; //线数为一时保存的坐标
int16 LINE_2_last[2];
int16 LINE_3_last[3];
int16 LINE_4_last[4];
char CROSS_static = 0; // 1直线 2弯道 3人字路口 6右直角 7左直角 8十字路口
uint8 right_angle_state = 0;
/***************************************************************
名称:函数声明
输入:
输出:
描述:
:
****************************************************************/
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()
{
int8 gradX;
uint8 thresholding_deal = 0;
CCD_BUFF[0] = CCD_BUFF[1];
CCD_BUFF[127] = CCD_BUFF[126];
for (int j = 1; j < 127; j++)
{
gradX = CCD_BUFF[j + 1] - CCD_BUFF[j - 1];
tempArray[j] = ABS(gradX); //CCD 导数图 tempArray
if(tempArray[j] > thresholding_deal)
{
thresholding_deal = tempArray[j];
}
}
thresholding = thresholding_deal; //保存导数最大值
if(thresholding < SOBEL_BIN_MIN)
{
thresholding = SOBEL_BIN_MIN;
}
for (int i = 0; i < 128; i++)
{
if (tempArray[i] > (uint8)(thresholding*0.6) )
{
tempArray_bin[i] = 120; //bin 存储导数阈值
}
else
{
tempArray_bin[i] = 0;
}
}
}
/***************************************************************
名称:
输入:
输出:
描述:
:
****************************************************************/
void CCD_line_count()
{
int16 LINE_all[10];
char temp;
char line_num = 1;
temp = (char)(ABS(ANGLE_final) * CCD_recovery); //计算还原数据
LINE_all[0] = -SOBEL_MIN;
for(int i = 0; i < 128; i++)
{
if(tempArray_bin[i] == 120)
{
if(i - LINE_all[line_num - 1] >= SOBEL_MIN)
{
LINE_all[line_num] = i;
line_num++;
}
else
{
LINE_all[line_num - 1] = (int16) ( ( i + LINE_all[line_num - 1]) /2 );
}
}
else
{
;
}
}
LINE_number = line_num - 1; //LINE_number为图中的线数
for(int i = 0; i < 128; i++)
{
tempArray_creat[i] = 0;
}
for(int i = LINE_number; i > 0; i--)
{
tempArray_creat[LINE_all[i] ] = 255; //CRE 为生成线后的图 没有使用 仅是看
}
switch(LINE_number)
{
char i;
case 0: break;
case 1:
for(i = 0; i < 1; i++)
{
LINE_1[i] = (int16)( (LINE_all[i+1] - 64) - temp*(LINE_all[i+1] - 64)/64);//temp * (60 - 行数) / 60 * (LINE_all[i+1] - 40)/40)
}
break;
case 2:
for(i = 0; i < 2; i++)
{
LINE_2[i] = (int16)( (LINE_all[i+1] - 64) - temp*(LINE_all[i+1] - 64)/64);
}
break;
case 3:
for(i = 0; i < 3; i++)
{
LINE_3[i] = (int16)( (LINE_all[i+1] - 64) - temp*(LINE_all[i+1] - 64)/64);
}
break;
case 4:
for(i = 0; i < 4; i++)
{
LINE_4[i] = (int16)( (LINE_all[i+1] - 64) - temp*(LINE_all[i+1] - 64)/64);
}
break;
default: break;
}
}
/***************************************************************
名称:
输入:
输出:
描述:
:
****************************************************************/
void CCD_measure(void)
{
switch(LINE_number)
{
/*********************************************
*名称:0线
********************************************/
case 0:
{
WAY_value = 0;
}break;
/*********************************************
*名称:1线
********************************************/
case 1:
{
// if(right_angle_state == 1)
// {
//
// right_angle_state = 0;
// WAY_value = 90;
// }
// else
// {
/*********************************************
*名称:位置猜测位置
********************************************/
if(LINE_1[0] < 0)
{
LINE_2[0] = -32;
LINE_2[1] = +32;
WAY_value = LINE_1[0] + LINE_width/2;
}
else
{
LINE_2[1] = 32;
LINE_2[0] = -32;
WAY_value = LINE_1[0] - LINE_width/2;
}
// }
/*********************************************
*名称:变化猜测位置
********************************************/
// if(ABS(LINE_1[0] - LINE_2[0]) < LENTH_WIDTH)
// {
// LINE_2[0] = LINE_1[0];
// LINE_2[1] = LINE_1[0] + LINE_width;
// WAY_value = LINE_1[0] + LINE_width/2;
// }
// else
// {
// if(ABS(LINE_1[0] - LINE_2[1]) < LENTH_WIDTH)
// {
// LINE_2[1] = LINE_1[0];
// LINE_2[0] = LINE_1[0] - LINE_width;
// WAY_value = LINE_1[0] - LINE_width/2;
// }
// }
}break;
/*********************************************
*名称:2线
********************************************/
case 2:
{
if((LINE_2[1] - LINE_2[0]) < LINE_width_MIN)
{
if(ABS(WAY_value_sorce - LINE_2[0]) > ABS(WAY_value_sorce - LINE_2[1]) )
{
WAY_value = LINE_2[1];
}
else
{
WAY_value = LINE_2[0];
}
}
else
{
if(LINE_2[0] > 0 || LINE_2[1] < 0)
{
LINE_2[0] = LINE_2_last[0];
LINE_2[1] = LINE_2_last[1];
}
LINE_2_last[0] = LINE_2[0];
LINE_2_last[1] = LINE_2[1];
if((LINE_2[1] - LINE_2[0]) > LINE_width_MIN)
{
LINE_width = ABS(LINE_2[1] - LINE_2[0]);
}
WAY_value = (LINE_2[0] + LINE_2[1])/2;
CROSS_static = 0;
}
}break;
/*********************************************
*名称:3线
********************************************/
case 3:
{
WAY_value = (LINE_3[0] + LINE_3[2])/2;
}break;
/*********************************************
*名称:4线
********************************************/
case 4:
{
led(BEEP,LED_OFF); //蜂鸣器响
if(ABS(LINE_4[0] - LINE_4[1]) > ABS(LINE_4[2] - LINE_4[3]) )
{
WAY_value = (LINE_4[0] + LINE_4[1])/2;
}
else
{
WAY_value = (LINE_4[2] + LINE_4[3])/2;
}
led(BEEP,LED_ON); //蜂鸣器响
}break;
default: break;
}
/*********************************************
*名称:切内道补偿数值
********************************************/
WAY_value_sorce = WAY_value;
WAY_value = (int)(WAY_value + (float)(WAY_value)/64*WAY_anxious);
}
/***************************************************************
名称:CCD相关函数
输入:
输出:
描述:
:
****************************************************************/
#ifndef _CCD_H_
#define _CCD_H_
extern uint8 CCD_BUFF[TSL1401_SIZE]; //图像存储区
extern uint8 tempArray[TSL1401_SIZE];
extern uint8 tempArray_bin[TSL1401_SIZE]; //SOBEL 导数二值图
extern uint8 tempArray_creat[TSL1401_SIZE];
extern int16 WAY_value; //方向偏移 - 左偏 + 右偏
extern uint8 thresholding;
extern char LINE_number;
extern char CROSS_static; //道路信息
extern uint8 right_angle_state; //检测直角状态
extern char CCD_exposure_time;
extern int16 LINE_1[1];
extern int16 LINE_2[2];
extern int16 LINE_3[3];
extern int16 LINE_4[4];
extern void CCD_init(void); //CCD 初始化函数
extern void CCD_hand(void); //CCD 处理函数
#endif
|
评分
-
1
查看全部评分
-
|