声明:

由于学校代码不宜外泄,本文目的也只是记录生活、分享思路,故将除了变量申明部分保留了一部分外,所有组委会例程代码均被删除,在文中也有标记,剩下部分均为博主自己写出,应该不涉及保密。真有来学习的(不会真有人来吧)同学别看糊涂了。

正文:

博主参加的是北科21年的智能车校内赛,处理方法都是在提供的例程基础上添加的。例程使用的都是【区域生长】思想的搜索框架。基本上都是选用了【最大连通区域】进行主区域的搜索。

以下分享本次我对图像的处理代码,供大家参考学习。注意,每辆车的处理都不完全一样,请主要关注处理思路。而且在结束之后,我才找到一种更为稳定的补线思路。我将放在文末与各位分享。

#include "search.h"/********   变量声明  ********/
uint8        video_ori[MAX_VIDEO_LINE][MAX_VIDEO_POINT];  //图像原始数据,video_ori[m][n]代表图像的从下数第m行,从左数第n点,0为最黑,255为最白
//==============================图像数据================================//
Int16_point  g_CenterPosition[MAX_POINT_NUM];//中心点数组,下标代表第几个,存储相应中心点的坐标值
Int16_point  g_LeftEdge[MAX_POINT_NUM], g_RightEdge[MAX_POINT_NUM];//左、右边界点数组,下标代表第几个,存储相应边界点的坐标值
float        g_LeftDown_x, g_LeftDown_y, g_LeftUp_x, g_LeftUp_y, g_RightDown_x, g_RightDown_y, g_RightUp_x, g_RightUp_y;//左下、左上、右下、右上拐点数据
int          g_CenterNum;//中心点个数
int          g_ImageLine,g_sum;
int          g_Display,DirectionControlLine,DirectionControlWhole;//加权计算控制中心中的权值和项; 加权计算控制中心中的加权和项
int          g_LeftEdgeNum, g_RightEdgeNum;//图像识别结束后为左、右边界点个数
//==============================图像处理用变量==========================//
uint16       g_Start[10], g_End[10], g_SEnum;   //存放当前行各白块起始、结束位置的数组,下标为10意味着每行最多10个白块;白块计数器
uint8        g_SearchFlag=1;//区分当前是否在搜索第一行,值为1表明正在搜索第一行,否则为其余行
int          g_Cover;//白块联通长度
uint8        g_CoverIndex[10],g_CoverNum;//;当前行与前一行左右边界对应白块有重合的白块数
int         banma = 0;
//==============================新添的变量==============================//
int a = 0;
float b = 0;
double c = 0;
//======================================================================///*********  search:处理数据即测试算法的函数 ********/
void search()
{   g_LeftEdgeNum=0; g_RightEdgeNum=0;g_SearchFlag=1;int i,line, white_width = 0;/*int IMAGE_MIDDLE;int j;*//*用于大津法*///=======================图像识别=========================////PS:此时我们的图像已经提取完毕 我们从底部开始,向上识别图像//图像识别数据初始化//大津法(效果不好,故暂时注释掉)//int width = MAX_VIDEO_POINT;//int height = MAX_VIDEO_LINE;//int pixelCount[GrayScale] = { 0 }; //每个灰度值所占像素个数//float pixelPro[GrayScale] = { 0 };//每个灰度值所占总像素比例//int pixelSum = width * height; //总像素//uint8 * data = video_ori[MAX_VIDEO_LINE]; //指向像素数据的指针// //统计灰度级中每个像素在整幅图像中的个数//for (i = 0; i < height; i++)//{//    for (j = 0; j < width; j++)// {//     pixelCount[(int)video_ori[i][j]]++; //将像素值作为计数数组的下标// }//}计算灰度集中每个像素在整幅图像中的比例//for (i = 0; i < GrayScale; i++)//{// pixelPro[i] = (float)pixelCount[i] / pixelSum;//}遍历灰度级[0,255]//float wf, wb, uftmp, ubtmp, uf, ub, u, deltaTmp, deltaMax = 0;//for (i = 0; i < GrayScale; i++) // i作为阈值//{//    wf = wb = uftmp = ubtmp = uf = ub = u = deltaTmp = 0;// for (j = 0; j < GrayScale; j++)// {//     if (j <= i) //背景部分//        {//         wb += pixelPro[j];//背景像素点占整个图像的比例//           ubtmp += j * pixelPro[j];//       }//     else //前景部分//       {//         wf += pixelPro[j];//前景像素点占整个图像的比例//           uftmp += j * pixelPro[j];//       }// }// ub = ubtmp / wb;//背景平均灰度μ0//   uf = uftmp / wf;//前景平均灰度μ1//   deltaTmp = (float)(wb * wf * (ub - uf)*(ub-uf)); //类间方差公式 g = w1 * w2 * (u1 - u2) ^ 2//   if (deltaTmp > deltaMax)//   {//     deltaMax = deltaTmp;//     IMAGE_MIDDLE = i;//    }//}//g_CenterNum = 0;g_LeftEdgeNum = 0;g_RightEdgeNum = 0;g_SearchFlag=1;int banmajishu = 0;//注意,此处删除了寻找画面白块部分!!!!!!!
//下面开始正式补线int r_down_flag = 0;//右下拐点标志int r_up_flag = 0;//右上拐点标志int l_down_flag = 0;//左下拐点标志int l_up_flag = 0;//左上拐点标志int l_xie_crossroad_jin = 0;//近左斜标志int r_xie_crossroad_jin = 0;//近右斜标志int straightway = 0;//直道标志int before_crossroad = 0;//正十字前标志int ing_crossroad = 0;//正十字中标志int l_xie_crossroad_yuan = 0;//远左斜标志int r_xie_crossroad_yuan = 0;//远右斜标志int ing_crossroad_pd = 0;//正十字中与弯道离奇拐点、远斜十字判别标志for (i = 0; i < 20; i++){if (video_ori[i][0] > IMAGE_MIDDLE && video_ori[i][161] > IMAGE_MIDDLE){ing_crossroad_pd++;}}for (i = 5; i < 50; i++)//判断上面拐点类型{if (g_RightEdge[i].y - g_RightEdge[i + 1].y < 5 && g_RightEdge[i-1].y - g_RightEdge[i].y > 5 && g_RightEdge[i - 2].y - g_RightEdge[i].y > 10 && g_LeftEdge[i - 10].y < 20){r_up_flag = 1;g_RightUp_x = i;g_RightUp_y = g_RightEdge[i].y;//break;/*printf("%d\n",2);*/}if (g_LeftEdge[i+1].y - g_LeftEdge[i].y < 5 && g_LeftEdge[i].y - g_LeftEdge[i - 1].y > 5 && g_LeftEdge[i].y - g_LeftEdge[i - 2].y > 10 && g_RightEdge[i - 10].y > 140){l_up_flag = 1;g_LeftUp_x = i;g_LeftUp_y = g_LeftEdge[i].y;//break;/*printf("%d\n",4);*/}}for (i = 7; i < 40; i++)//判断下面拐点类型{if (g_RightEdge[i+1].y - g_RightEdge[i].y > 5 && g_RightEdge[i+2].y - g_RightEdge[i].y > 10 && g_RightEdge[i-1].y - g_RightEdge[i].y < 5 && g_RightEdge[i - 4].y - g_RightEdge[i].y >= 0){r_down_flag = 1;g_RightDown_x = i;g_RightDown_y = g_RightEdge[i].y;//break;/*printf("%d\n",1);*/}if (g_LeftEdge[i].y - g_LeftEdge[i + 1].y > 5 && g_LeftEdge[i].y - g_LeftEdge[i + 2].y > 10 && g_LeftEdge[i].y - g_LeftEdge[i - 1].y < 5 && g_LeftEdge[i].y - g_LeftEdge[i - 4].y >= 0){l_down_flag = 1;g_LeftDown_x = i;g_LeftDown_y = g_LeftEdge[i].y;/*if (g_LeftDown_y > 81){l_down_flag = 0;}*/}}if (r_down_flag == 1 && r_up_flag == 1 && l_down_flag == 0 && l_up_flag == 0){l_xie_crossroad_jin = 1;}else if (r_down_flag == 0 && r_up_flag == 0 && l_down_flag == 1 && l_up_flag == 1){r_xie_crossroad_jin = 1;}else if (r_down_flag == 1 && r_up_flag == 1 && l_down_flag == 1 && l_up_flag == 1){before_crossroad = 1;}else if (r_down_flag == 0 && r_up_flag == 1 && l_down_flag == 0 && l_up_flag == 1 && ing_crossroad_pd > 10){ing_crossroad = 1;}else {r_down_flag = 0, r_up_flag = 0, l_down_flag = 0, l_up_flag = 0;}if (r_down_flag == 0 && r_up_flag == 0 && l_down_flag == 0 && l_up_flag == 0 && l_xie_crossroad_jin == 0 && r_xie_crossroad_jin == 0)//远斜十字拐点判别{for (i = 0; i < 55; i++){if (g_LeftEdge[i + 1].y == 0 && g_RightEdge[i - 1].y > g_RightEdge[i + 1].y && g_RightEdge[i + 2].y > g_RightEdge[i + 1].y && g_RightEdge[i + 1].y < 155 && g_RightEdge[i - 1].y < 155 && g_RightEdge[i + 2].y < 155){r_down_flag = 1;g_RightDown_x = i + 1;g_RightDown_y = g_RightEdge[i + 1].y;}if (g_LeftEdge[i].y == 0 && g_LeftEdge[i + 1].y == 0 && g_LeftEdge[i + 2].y != 0 && g_LeftEdge[i + 3].y != 0 && g_LeftEdge[i + 2].y > 10){r_up_flag = 1;g_RightUp_x = i + 2;g_RightUp_y = g_LeftEdge[i + 2].y;}if (g_RightEdge[i + 1].y == 161 && g_LeftEdge[i - 1].y < g_LeftEdge[i + 1].y && g_LeftEdge[i + 2].y < g_LeftEdge[i + 1].y && g_LeftEdge[i + 1].y > 5 && g_LeftEdge[i -1].y > 5 && g_LeftEdge[i + 2].y > 5){l_down_flag = 1;g_LeftDown_x = i + 1;g_LeftDown_y = g_LeftEdge[i + 1].y;}if (g_RightEdge[i].y == 161 && g_RightEdge[i + 1].y == 161 && g_RightEdge[i + 2].y != 161 && g_RightEdge[i + 3].y != 161 && g_RightEdge[i + 2].y < 151){l_up_flag = 1;g_LeftUp_x = i + 2;g_LeftUp_y = g_RightEdge[i + 2].y;}}}int x_d = 0, x_u = 0;int r_turn_pd = 0;int l_turn_pd = 0;int r_near_turn = 0;//右近弯标志int r_far_turn = 0;//右远弯标志int l_near_turn = 0;//左近弯标志int l_far_turn = 0;//左远弯标志int r_turn_fuzhu = 0;int l_turn_fuzhu = 0;for (i = 0; i < 60; i++){if (g_LeftEdge[i].y == 0 && g_RightEdge[i].y < 161 && g_RightEdge[i].y < g_RightEdge[i - 1].y){l_turn_pd++;}if (g_RightEdge[i].y == 161 && g_LeftEdge[i].y > 0 && g_LeftEdge[i].y > g_LeftEdge[i - 1].y){r_turn_pd++;}if (g_LeftEdge[i].y == 0){l_turn_fuzhu++;}if (g_RightEdge[i].y == 161){r_turn_fuzhu++;}}if (l_turn_pd > 30 && video_ori[l_turn_pd][100]< IMAGE_MIDDLE/*&& r_turn_fuzhu < 10*/){l_near_turn = 1;}if (l_turn_pd > 10 && l_turn_pd < 30 && l_turn_fuzhu-l_turn_pd<8){l_far_turn = 1;}if (r_turn_pd > 30 && video_ori[r_turn_pd][60] < IMAGE_MIDDLE/*&& l_turn_fuzhu < 10*/){r_near_turn = 1;}if (r_turn_pd > 10 && r_turn_pd < 30 && r_turn_fuzhu-r_turn_pd<8){r_far_turn = 1;}if (l_far_turn == 1 && r_far_turn == 1){l_far_turn = 0;r_far_turn = 0;}if (l_far_turn == 1){for (i = 20; i < 55; i++){if (g_LeftEdge[i].y == 0 && g_LeftEdge[i - 1].y > 0){x_d = i;}if (g_LeftEdge[i].y == 0 && g_LeftEdge[i + 1].y > 0){x_u = i;}}}if (r_far_turn == 1){for (i = 25; i < 55; i++){if (g_RightEdge[i].y == 161 && g_RightEdge[i - 1].y < 161){x_d = i;}if (g_RightEdge[i].y == 161 && g_RightEdge[i + 1].y < 161){x_u = i;}}/*for (i = x_d; i < 55; i++){if (g_RightEdge[i].y == 161 && g_RightEdge[i + 1].y < 161){x_u = i;}}*/}if (x_d == 0 && x_u == 0){l_far_turn = 0;r_far_turn = 0;}if (r_down_flag == 0 && r_up_flag == 0 && l_down_flag == 0 && l_up_flag == 0){straightway = 1;}else if (r_down_flag == 1 && r_up_flag == 1 && l_down_flag == 0 && l_up_flag == 0 && l_xie_crossroad_jin == 0){l_xie_crossroad_yuan = 1;}else if (r_down_flag == 0 && r_up_flag == 0 && l_down_flag == 1 && l_up_flag == 1 && r_xie_crossroad_jin == 0){r_xie_crossroad_yuan = 1;}if (l_near_turn == 1 && l_xie_crossroad_jin == 1){l_xie_crossroad_jin = 0;}if (r_near_turn == 1 && r_xie_crossroad_jin == 1){r_xie_crossroad_jin = 0;}int l_ku = 0;int r_ku = 0;int l_ku_qian = 0;int l_ku_zhong = 0;int l_ku_hou = 0;int r_ku_qian = 0;int r_ku_zhong = 0;int r_ku_hou = 0;if (banma == 1){l_down_flag = 0;l_up_flag = 0;r_down_flag = 0;r_up_flag = 0;int r_ku_pd = 0;int l_ku_pd = 0;for (i = 0; i < 60; i++){if (g_LeftEdge[i].y == 0){l_ku_pd++;}if (g_RightEdge[i].y == 161){r_ku_pd++;}}if (l_ku_pd > r_ku_pd){l_ku = 1;}else{r_ku = 1;}if (l_ku == 1){for (i = 0; i < 30; i++){if (g_LeftEdge[i - 1].y < g_LeftEdge[i + 1].y && g_LeftEdge[i + 2].y < g_LeftEdge[i + 1].y){l_down_flag = 1;g_LeftDown_x = i + 1;g_LeftDown_y = g_LeftEdge[i + 1].y;}}for (i = 55; i > 35; i--){if (g_LeftEdge[i + 1].y - g_LeftEdge[i].y < 5 && g_LeftEdge[i].y - g_LeftEdge[i - 1].y > 5){l_up_flag = 1;g_LeftUp_x = i;g_LeftUp_y = g_LeftEdge[i].y;}}if (l_down_flag == 1 && l_up_flag == 1&&g_LeftDown_y<g_LeftUp_y){l_ku_qian = 1;}if (l_ku_qian == 0 && l_up_flag == 1){l_ku_zhong = 1;}}else if (r_ku == 1){for (i = 0; i < 30; i++){if (g_RightEdge[i - 1].y > g_RightEdge[i + 1].y && g_RightEdge[i + 2].y > g_RightEdge[i + 1].y){r_down_flag = 1;g_RightDown_x = i + 1;g_RightDown_y = g_RightEdge[i + 1].y;}}for (i = 55; i > 38; i--){if (g_RightEdge[i].y - g_RightEdge[i+1].y < 3 && g_RightEdge[i-1].y - g_RightEdge[i].y > 3){r_up_flag = 1;g_RightUp_x = i;g_RightUp_y = g_RightEdge[i].y;}}if (r_down_flag == 1 && r_up_flag == 1&&g_RightUp_y<g_RightDown_y){r_ku_qian = 1;}if (r_ku_qian == 0 && r_up_flag == 1){r_ku_zhong = 1;}}r_near_turn = 0;l_near_turn = 0;r_far_turn = 0;l_far_turn = 0;r_xie_crossroad_yuan = 0;l_xie_crossroad_yuan = 0;}float b_r, k_r, b_l, k_l;//补线斜率和截距if (banma == 1){g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = 81;}}else if (before_crossroad == 1)//正十字前中心求取{k_r = (g_RightUp_y - g_RightDown_y) / (g_RightUp_x - g_RightDown_x);b_r = g_RightDown_y - k_r * g_RightDown_x;for (i = g_RightDown_x; i < g_RightUp_x + 1; i++){g_RightEdge[i].y = k_r * g_RightEdge[i].x + b_r;}k_l = (g_LeftUp_y - g_LeftDown_y) / (g_LeftUp_x - g_LeftDown_x);b_l = g_LeftDown_y - k_l * g_LeftDown_x;for (i = g_LeftDown_x; i < g_LeftUp_x + 1; i++){g_LeftEdge[i].y = k_l * g_LeftEdge[i].x + b_l;}g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}}else if (ing_crossroad == 1)//正十字中中心求取{k_r = (g_RightUp_y - 161) / g_RightUp_x;b_r = 161;for (i = 0; i < g_RightUp_x + 1; i++){g_RightEdge[i].y = k_r * g_RightEdge[i].x +b_r;}k_l = g_LeftUp_y  / g_LeftUp_x ;b_l = 0;for (i = 0; i < g_LeftUp_x + 1; i++){g_LeftEdge[i].y = k_l * g_LeftEdge[i].x;}g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}}else if (l_xie_crossroad_jin == 1)//近左斜十字中心求取{k_r = (g_RightUp_y - g_RightDown_y) / (g_RightUp_x - g_RightDown_x);b_r = g_RightDown_y - k_r * g_RightDown_x;for (i = g_RightDown_x; i < g_RightUp_x + 1; i++){g_RightEdge[i].y = k_r * g_RightEdge[i].x + b_r;}int left_create = g_RightUp_x;k_l = -k_r;b_l = g_LeftEdge[left_create].y - k_l * g_RightUp_x;for (i = left_create; i >= 0; i--){g_LeftEdge[i].y = k_l * g_LeftEdge[i].x + b_l;}g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}}else if (r_xie_crossroad_jin == 1)//近右斜十字中心求取{k_l = (g_LeftUp_y - g_LeftDown_y) / (g_LeftUp_x - g_LeftDown_x);b_l = g_LeftDown_y - k_l * g_LeftDown_x;for (i = g_LeftDown_x; i < g_LeftUp_x + 1; i++){g_LeftEdge[i].y = k_l * g_LeftEdge[i].x + b_l;}int right_create = g_LeftUp_x;k_r = -k_l;b_r = g_RightEdge[right_create].y - k_r * g_LeftUp_x;for (i = right_create; i >= 0; i--){g_RightEdge[i].y = k_r * g_RightEdge[i].x + b_r;}g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}}else if (l_xie_crossroad_yuan == 1)//远左斜十字中心求取{k_r = (g_RightUp_y - g_RightDown_y) / (g_RightUp_x - g_RightDown_x);b_r = g_RightDown_y - k_r * g_RightDown_x;for (i = g_RightDown_x; i < g_RightUp_x + 1; i++){g_RightEdge[i].y = k_r * g_RightEdge[i].x + b_r;}g_RightEdgeNum = g_RightUp_x;g_LeftEdgeNum = g_RightUp_x;g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = k_r * g_RightEdge[i].x + b_r / 2;}}else if (r_xie_crossroad_yuan == 1)//远右斜十字中心求取{k_l = (g_LeftUp_y - g_LeftDown_y) / (g_LeftUp_x - g_LeftDown_x);b_l = g_LeftDown_y - k_l * g_LeftDown_x;for (i = g_LeftDown_x; i < g_LeftUp_x + 1; i++){g_LeftEdge[i].y = k_l * g_LeftEdge[i].x + b_l;}g_RightEdgeNum = g_LeftUp_x;g_LeftEdgeNum = g_LeftUp_x;g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_LeftEdge[i].x;g_CenterPosition[i].y = k_l * g_LeftEdge[i].x + (161 - b_l) / 2;}}else if (l_near_turn == 1)//左近弯中心求取{int left_pinyi = g_RightEdge[0].y;for (i = 0; i <= l_turn_pd; i++){g_LeftEdge[i].y = g_RightEdge[i].y - left_pinyi - 2 * i;}g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}}else if (r_near_turn == 1)//右近弯中心求取{int right_pinyi = 161 - g_LeftEdge[0].y;for (i = 0; i <= r_turn_pd; i++){g_RightEdge[i].y = g_LeftEdge[i].y + right_pinyi + 2 * i;}g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}}else if (l_far_turn == 1){g_CenterNum = g_RightEdgeNum;g_LeftEdgeNum = x_d;DEBUG_VAR(g_CenterNum, d)for (i = 0; i <= x_d; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}k_l = -2 * g_CenterPosition[x_d].y / (x_u - x_d);b_l = -k_l * (x_d + x_u) / 2;for (i = x_d; i <= g_RightEdgeNum/*(x_d + x_u) / 2*/; i++){g_CenterPosition[i].x = i;g_CenterPosition[i].y = k_l * i + b_l;}}else if (r_far_turn == 1){g_CenterNum = g_LeftEdgeNum;g_RightEdgeNum = x_d;DEBUG_VAR(g_CenterNum, d)for (i = 0; i <= x_d; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}k_r = 2 * (161 - g_CenterPosition[x_d].y) / (x_u - x_d);b_r = 161 - k_r * (x_d + x_u) / 2;for (i = x_d; i <= g_RightEdgeNum/*(x_d + x_u) / 2*/; i++){g_CenterPosition[i].x = i;g_CenterPosition[i].y = k_r * i + b_r;}}//else if (l_ku_qian == 1)//{//  g_CenterNum = g_LeftUp_x;//    g_RightEdgeNum = g_LeftUp_x;// g_LeftEdgeNum = g_LeftDown_x;//    DEBUG_VAR(g_CenterNum, d)// int start = g_LeftDown_x;//    int end_x = (g_LeftDown_x + g_LeftUp_x) / 2;//    int end_y = (g_LeftDown_y + g_LeftUp_y) / 2;//    k_l = (g_RightEdge[start].y - g_LeftUp_y) / (start - g_LeftUp_x);//    b_l = g_LeftUp_y - k_l * g_LeftUp_x;// for (i = start; i < g_LeftUp_x+1; i++)// {//     g_RightEdge[i].y = k_l * i + b_l;//   }// for (i = 0; i < start; i++)// {//     g_CenterPosition[i].x = i;//       g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;//   }// for (i = start; i < g_LeftUp_x; i++)//    {//     g_CenterPosition[i].x = i;//       g_CenterPosition[i].y = (k_l-1) * i + b_l + 81 - g_RightEdge[start].y;// }// /*for (i = end_x; i < g_LeftUp_x; i++)//  {//     g_CenterPosition[i].x = i;//       g_CenterPosition[i].y =  -i + b_l + 81 - g_RightEdge[start].y;// }*///   }//else if (r_ku_qian == 1)//{//  g_CenterNum = g_RightUp_x;//   g_RightEdgeNum = g_RightDown_x;//  g_LeftEdgeNum = g_RightUp_x;// DEBUG_VAR(g_CenterNum, d)// int start = g_RightDown_x;//   //int end_x = (g_LeftDown_x + g_LeftUp_x) / 2;//  //int end_y = (g_LeftDown_y + g_LeftUp_y) / 2;//  k_r = (g_LeftEdge[start].y - g_RightUp_y) / (start - g_RightUp_x);//   b_r = g_RightUp_y - k_r * g_RightUp_x;//   for (i = start; i < g_RightUp_x + 1; i++)//  {//     g_LeftEdge[i].y = k_r * i + b_r;//    }// for (i = 0; i < start; i++)// {//     g_CenterPosition[i].x = i;//       g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;//   }// for (i = start; i < g_RightUp_x; i++)//   {//     g_CenterPosition[i].x = i;//       g_CenterPosition[i].y = (k_r + 1) * i + b_r + 81 - g_LeftEdge[start].y;//   }//}//else if (l_ku_zhong == 1)//{//  g_CenterNum = g_LeftUp_x;//    g_RightEdgeNum = g_LeftUp_x;// g_LeftEdgeNum = g_LeftUp_x;//  DEBUG_VAR(g_CenterNum, d)// k_l = (161 - g_LeftUp_y) / (-g_LeftUp_x);//    b_l = 161;//   for (i = 0; i < g_LeftUp_x; i++)//    {//     g_RightEdge[i].y = k_l * i + b_l;//       g_LeftEdge[i].y = k_l * i;//   }// for (i = 0; i < g_LeftUp_x; i++)//    {//     g_CenterPosition[i].x = g_RightEdge[i].x;//        g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;//   }//}//else if (r_ku_zhong == 1)//{//  g_CenterNum = g_RightUp_x;//   g_RightEdgeNum = g_RightUp_x;//    g_LeftEdgeNum = g_RightUp_x;// DEBUG_VAR(g_CenterNum, d)//     k_r = g_RightUp_y / g_RightUp_x;// for (i = 0; i < g_RightUp_x; i++)//   {//     g_LeftEdge[i].y = k_r * i;//       g_RightEdge[i].y = k_r * i + 161;//   }// for (i = 0; i < g_RightUp_x; i++)//   {//     g_CenterPosition[i].x = g_RightEdge[i].x;//        g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;//   }//}else{g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}}/*g_CenterNum = g_RightEdgeNum;DEBUG_VAR(g_CenterNum, d)for (i = 0; i < g_RightEdgeNum; i ++){g_CenterPosition[i].x = g_RightEdge[i].x;g_CenterPosition[i].y = (g_RightEdge[i].y + g_LeftEdge[i].y) / 2;}*/}

代码较长,而且图像处理是一个工程文件,这里给出的是search.c文件中内容,即主要的图像处理文件。通过以上代码可以较好地处理包括正十字、斜十字、左右弯道,可以勉强处理车库问题,但由于难以稳定,在上文给出的代码中就被我注释掉了。下面给出处理效果图:

处理思路:

1、正十字:不论是十字前还是十字中,都需要寻找拐点。

(1)找到四个拐点则为正十字中,左右两边分别用上下拐点拟合直线来补出缺线;

(2)找到上面两个拐点则为正十字中,左右分别用上拐点与(0,0)、(0,161)拟合直线来补出缺线。

2、斜十字:

(1)若只找到右边两个拐点,则为左斜十字中(两拐点离车近)。

(2)而左斜十字前,即两“拐点”离车远的情况则不同。在四个拐点都没找到且不为左右斜十字中时,重新扫线二次找拐点(换了要求)。找到右边两个拐点先补出直线,方法与上面类似。再为左边拟合一个镜像的直线,最后再求取中线得出。

(3)右斜十字的方法同上。

3、弯道:

(1)近弯:若判断为左近弯,那么右边边界不变,通过右边界平移出一个y值为负的左边界,之后两者求中值即可。右近弯方法同上。

(2)远弯:判断为左远弯后,扫线找出一个x_d值,在此之下依旧相加除以二,在此之上的中心线拟合为直线。

4、入库

通过找寻斑马线,找到斑马线后找拐点来补线。建议通过控制开环入库,简单好用。

更优处理

自己的思路是无论直道、弯道、还是正、斜十字和车库,都是识别出道路类型后,最后进行处理。但这样多重的识别势必需要不同的辨识点来分辨,最常用的就是拐点。道路类型一多,很容易造成“串道”,比如十字成了弯道、车库成了弯道等等。

为什么会这样呢?是因为采用的中心求取思路非常简单粗糙,因为之前在边沿搜索的时候并没有区分两边,而是直接把一个白块的start认为是左边,end认为是右边 故中心数将与左右边的数相等,而中心位置直接由左右边相加除2所得。

另一种思路,在小车处于直道正中央时,处理这时的图像,此时左右边界线与理想中心线距离时相等的,记录每一行这种边界线与理想中心线之间的距离组成一个数组,姑且称这些距离为视距。这样在处理直道和弯道时可以不用辨识,使用同一种处理方法。直道不必多说,找每一行距离左边界线或者右边界线视距的点,即为中心点;弯道也是类似,但我自己也不清楚了。给出下图,看看有没有天才自己悟出来,哈哈哈哈

智能车校内赛图像处理相关推荐

  1. 2021年举行的第一场智能车校内赛 - 上海海事大学

    在朋友圈看到上海海事大学王天真教授发送的照片,显示了刚刚结束的校内赛的部分场景. 智能车校内赛顺利举办,各类车型大比拼.感谢团队老师通力合作.希望疫情早日过去,2021国赛更美好! ▲ 全向运行组别 ...

  2. 北京科技大学天津学院第三届智能车校内赛总决赛完美落幕

    2020年12月4日18时,北京科技大学天津学院第三届智能车校内赛总决赛在我院众创空间二楼智能车实践平台举办. ▲ 决赛现场,同学们观战 本届校内赛总决赛分为光电四轮组.摄像头直立组.电磁三轮组和无线 ...

  3. 第十六届全国大学生智能车竞赛赛题规划

    ➤01 背景介绍 1.筹备工作 根据 智能车竞赛相关的教高司公函:公函[2005]201号文.教高司[2005]13号 , 全国大学生智能汽车竞赛 从2006年开始已经举办了十五届了.特别是2020年 ...

  4. 恩智浦智能车大赛2020_我院第十三届“恩智浦”杯智能车校内选拔赛宣讲会顺利举行...

    2020年11月28日9:00,第十三届"恩智浦"杯智能车校内选拔赛宣讲会在长安大学北校区明远2201教室成功举行. 到场嘉宾 本次活动由我院大学生科技创新创业协会智能车部承办.本 ...

  5. 两所大学中的智能车竞赛校内赛

    简 介: 第十六届全国大学生智能车竞赛将会在2021年暑期举行.首先是在7月份进行各个分赛区比赛,8月将会在哈尔滨工程大学举办全国总决赛.现在各个学校分别举办了校内的比赛,以期检验同学们车模作品制作进 ...

  6. 北科智能车为什么能这么牛?

    北科智能车为什么能这么牛? 多年以前写的一篇日记,发一篇博客纪念我曾经为这个团队奋斗的经历. 昨天北京科技大学第十届智能车校内赛总决赛在教职工礼堂成功举办,我做为一名组织者,从选手报名到决赛完成几乎全 ...

  7. STM32F4智能车主板蝙蝠侠外形PCB

    本人为参加智能车校内赛,制作了这个酷炫的蝙蝠侠外形的摄像头组的pcb,并在华科邀请赛中凭借主控和代码获得奖项.比赛已经结束了,也可以将主控开源了. 主控芯片选取的stm32f4,在满足性能的情况下降低 ...

  8. 智能车学习日记【一】——让小车跑正方形赛道(摄像头图像处理赛道)

    智能车学习日记[一]--让小车跑正方形赛道 目录 开篇 舵机 赛道图像处理 图像处理 代码![在这里插入图片描述](https://img-blog.csdnimg.cn/9ec0eb76bd8941 ...

  9. 参加智能车大赛还是电赛?在做电磁炮中我找到了答案

    我们是来自中北大学的参赛队伍(焦道坤,赵之岑,李炳金),同时参加了智能车和电赛,并在2019年全国电子设计竞赛H题组获得国一的成绩,感谢达尔闻邀约. 应标题,我的答案是:智能车-- 虽然连续两年做智能 ...

最新文章

  1. php--------返回404状态
  2. c语言 python-C语言、Java语言和python语言的区别在哪里
  3. 一些让人受益匪浅的话--转
  4. 如何判断数组所有数都不等于一个数_【每日算法Day 91】求解数组中出现次数超过1/3的那个数
  5. PowerShell尝试登录SQL Server
  6. 为什么只有奇次谐波_关于开关电源谐波失真,这有一份测量分析方法经验分享!...
  7. 「雕爷学编程」Arduino动手做(20)—水银开关模块
  8. 我的《野蛮生长》书摘
  9. javascrpt 继承
  10. 漫画:给女朋友解释为什么随机播放歌曲并不随机
  11. 虚拟无线接入网:行业的演进方向
  12. Hvv近期0day总结三
  13. SpringBoot+SQLSERVER2000问题 简要总结
  14. java restsharp_如何在asp.net核心中使用RestSharp.NetCore (How to use RestSharp.NetCore in asp.net core)...
  15. python爬取“堆糖网”小姐姐 图片
  16. 集团类企业信息化原则与思路
  17. Connection error: QRedisClient compiled without ssh support
  18. 健康指南:趴桌睡觉三大危害
  19. Elasticsearch嵌套式对象Nested分析
  20. Zbrush学习笔记

热门文章

  1. JAVA梅森旋转随机算法,你没听过的梅森旋转算法
  2. 如何查看自己的公网ip
  3. 嵌入式系统求职回忆录
  4. Tesra超算网络——AI训练深度学习平台,降低了AI开发的成本和门槛
  5. 分布式系统中的一致性模型
  6. 浏览器被毒霸占领这样去掉
  7. Linux服务器怎么关闭防火墙?
  8. 如何才能招聘到合适的以太坊区块链开发者
  9. java 对象查找_Java如何从数组中查找对象元素?
  10. Linux命令教程第二期