智能车打工日记(二):关于起跑线与出入车库

   日期:2020-05-16     浏览:153    评论:0    
核心提示:关于第十五届全国大学生智能汽车竞速比赛的车库元素的一些处理方式人工智能

目录

  • 车库元素一览
  • 入车库
    • 20cm摄像头拍下的车库图
    • 起跑线的识别
    • 入车库的拉线
  • 出车库

车库元素一览

车库元素是今年赛道元素新增的元素。车库赛道元素是在起跑线旁设置的方形区域,它的尺寸如下图所示:

车模出发是从车库驶出,在运行一周之后在驶入车库内。比赛时间是从车模驶出车库和返回车库之间的时间差计算。因此计时线圈是放置在车库门口处。赛道上的斑马线和斑马线下的磁铁放置与往届规则相同。
车库应用于“基础四轮组”,“直立节能组”,“双车接力组”

入车库

20cm摄像头拍下的车库图

起跑线的识别

因为时间紧迫,这里采用最简单的入车库(左入)斑马线识别方法:

  1. 找到左前边线的拐点
  2. 从下(拐点的y坐标)向上(拐点的y坐标+m),从左(拐点的x坐标)到右(中线位置),进行寻找由黑到白的转变边界像素点。
  3. 找到了第一个边界,以固定的y坐标(转变边界像素点的y坐标+n),从左到右,重新扫线。
  4. 找到第一个由白转黑的像素点和第一个由黑转白的像素点,记录距离(length),作为判断之后斑马线长度的依据
  5. 持续向右扫线,每找到一个疑似斑马线的像素块,就把边界像素的距离与length进行比较,在设定误差之内,判定斑马线。
  6. 记录斑马线数量,与判定起跑线的斑马线数量阈值比较。

代码:

byte Garage_Judge(byte i)
        {
            byte y = 0, x = 0, count = 0, pixel_cnt = 0, zebraWidth = 0;
            //左边车库
            if (i == 0)
            {
                for (OlRow = LeftLine_1.Agl_Row; OlRow <= LeftLine_1.Agl_Row + 20; OlRow++)
                {
                    for (OlLine = (byte)(LeftLine_1.Agl_Line - 5); OlLine >= 93; OlLine--)
                    {
                        //SetText_1("Zerba Scan :"+ OlRow+" "+ OlLine);
                        if (J_Pixels[OlRow][OlLine] == white && J_Pixels[OlRow][OlLine - 1] == black)
                        {
                            y = (byte)(OlRow + 3);
                            //x = (byte)(OlLine-1);
                            SetText_1("Find Zebra Point: " + y + " " + OlLine);
                            break;
                        }
                    }
                    if (y != 0)
                        break;
                }
                if (y == 0)
                {
                    SetText_1("Lost Zebra Point");
                    return 0;
                }
                for (x = LeftLine_1.Agl_Line; x >= 185 - LeftLine_1.Agl_Line; x--)
                {
                    if (J_Pixels[y][x + 1] == white && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Scan Start: " + y + " " + x);
                        pixel_cnt = 1;
                    }
                    else if (J_Pixels[y][x + 1] == black && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Add: " + y + " " + x);
                        pixel_cnt++;
                    }
                    else if (J_Pixels[y][x + 1] == black && J_Pixels[y][x] == white)
                    {
                        if (count == 0 && pixel_cnt >= 3 && pixel_cnt <= 10)
                        {
                            zebraWidth = pixel_cnt;
                            SetText_1("zebraWidth = " + zebraWidth);
                            SetText_1("zebraStart Point: " + x + " " + y);
                            count = 1;
                        }
                        else if (count > 0 && my_fabs(pixel_cnt - zebraWidth) <= 4)
                        {
                            //SetText_1("Zebra End: " + y + " " + (x - 1));
                            count++;
                        }
                        else
                        {
                            // SetText_1("Zebra Error: " + y + " " + (x - 1));
                        }
                    }
                }
                SetText_1("Zebra Count = " + count);
                if (count >= 6)
                {
                    SetText_1("Proved to be Garage");
                    return 1;
                }
                else
                {
                    SetText_1("Not Proved to be Garage");
                    return 0;
                }
            }
            else  //右边车库
            {
                for (OlRow = RightLine_1.Agl_Row; OlRow <= RightLine_1.Agl_Row + 20; OlRow++)
                {
                    for (OlLine = (byte)(RightLine_1.Agl_Line + 5); OlLine <= 93; OlLine++)
                    {
                        //SetText_1("Zerba Scan :"+ OlRow+" "+ OlLine);
                        if (J_Pixels[OlRow][OlLine] == black && J_Pixels[OlRow][OlLine - 1] == white)
                        {
                            y = (byte)(OlRow + 3);
                            //x = (byte)(OlLine-1);
                            SetText_1("Find Zebra Point: " + y + " " + OlLine);
                            break;
                        }
                    }
                    if (y != 0)
                        break;
                }
                if (y == 0)
                {
                    SetText_1("Lost Zebra Point");
                    return 0;
                }
                for (x = RightLine_1.Agl_Line; x <= 185 - RightLine_1.Agl_Line; x++)
                {
                    if (J_Pixels[y][x - 1] == white && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Scan Start: " + y + " " + x);
                        pixel_cnt = 1;
                    }
                    else if (J_Pixels[y][x - 1] == black && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Add: " + y + " " + x);
                        pixel_cnt++;
                    }
                    else if (J_Pixels[y][x - 1] == black && J_Pixels[y][x] == white)
                    {
                        if (count == 0 && pixel_cnt >= 3 && pixel_cnt <= 10)
                        {
                            zebraWidth = pixel_cnt;
                            SetText_1("zebraWidth = " + zebraWidth);
                            SetText_1("zebraStart Point: " + x + " " + y);
                            count = 1;
                        }
                        else if (count > 0 && my_fabs(pixel_cnt - zebraWidth) <= 4)
                        {
                            //SetText_1("Zebra End: " + y + " " + (x - 1));
                            count++;
                        }
                        else
                        {
                            // SetText_1("Zebra Error: " + y + " " + (x - 1));
                        }
                    }
                }
                SetText_1("Zebra Count = " + count);
                if (count >= 6)
                {
                    SetText_1("Proved to be Garage");
                    return 1;
                }
                else
                {
                    SetText_1("Not Proved to be Garage");
                    return 0;
                }
            }
        }

由于入库图像与环岛入环图像较为相似,入车库判断函数的优先级需要高于入环判断函数。
实践证明,识别成功率很高。

入车库的拉线

拉线分为4个阶段:

  1. 阶段0:判断为车库
  2. 阶段1:左前拐点消失
  3. 阶段2:低行右边边线消失
  4. 阶段3:右边边线重新出现
  5. 阶段4:左边边线出现

出车库

目前最稳定的方法为直接控制出库。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服