小工具知识网

当前位置: 首页 > 行业知识 > 智能车摄像头算法——圆环元素

行业知识

智能车摄像头算法——圆环元素

2026-11-07 08:49:43 来源:互联网转载

入环

  • 1.入环的函数
    • (1)搜上下边线
    • (2)找凸起的弧
    • (3)两点之间补线
    • (4)判断上线是否单调
    • 2.找圆环
    • 3.补���入环出环

      1.入环的函数

      (1)搜上下边线

      搜上下边线,处理圆环的时,可以利用上下边线的特点。

      uint8_t UpdownSideGet(uint8_t imageInput[OV7725_UART_H][OV7725_UART_W], uint8_t imageOut[2][OV7725_UART_W]){    uint8_t i = 0, j = 0;    uint8_t last = OV7725_UART_H/2;    imageOut[0][OV7725_UART_W-1] = 0;    imageOut[1][OV7725_UART_W-1] = OV7725_UART_H-1;     //从图像中间行    从中到下     从中到上      扫描    //处理中间单独那一列的上下边线    for(i = last; i >= 0; i--)    {        if(!imageInput[i][OV7725_UART_W/2])        {            imageOut[up][OV7725_UART_W/2] = i;            break;        }    }    for(i = last; i  0; i--)//遍历每一列    {        imageOut[up][i] = 0;        imageOut[down][i] = OV7725_UART_H-1;        for(j = imageOut[0][i+1] + 5; j > 0; j--)//一列中的扫描每行  从上列的行数+10开始向上扫描        {            if(!imageInput[j][i])            {                imageOut[up][i] = j;                break;            }        }        for(j = imageOut[1][i+1] - 5; j  0; j--)            {                if(!imageInput[j][i])                {                    imageOut[up][i] = j;                    break;                }            }            for(j = imageOut[1][i-1] - 5; j  

      (2)找凸起的弧

      找凸起的弧,用于圆环的检测。如下图红色的线。

      RoundaboutGetArc函数中传入的num代表着,要检测的这个圆弧大小,要求这个圆弧包含多少个点。

      以左圆环为例:

      先判断边线丢不丢线,不丢线再进行下一步。由于是遍历一幅图像左边线数组的每一行,我们就找这样一个特征:它下面连续递减点的个数+它上面连续递减点的个数+跟它横坐标一样大的点的个数 >=我们设定的值。这个就是我们认为的圆弧

      /*!  * @brief    判断左右边线是否存在弧形  * 输出的 index 圆弧的顶点位置  * @param    imageInput : 二值图像信息  * @param    imageOut   : 边线数组  * @param    status     : 1:左边线  2:右边线  * @param    num        : 圆弧的大小 用点数表示  (连续N个增  连续N个减)  * @return   1 有弧线    0  没弧线  */uint8_t RoundaboutGetArc(uint8_t imageSide[OV7725_UART_H][2], uint8_t status, uint8_t num,uint8_t* index){    int i = 0;    uint8_t inc = 0, dec = 0, n = 0;    switch(status)    {      case 1:        for(i = START_H-2; i > END_H; i--)        {        //没有丢线              if(imageSide[i][0] != 1 && imageSide[i+1][0] != 1)            {                if(imageSide[i][0] == imageSide[i+1][0])                {                    n++;                    continue;                }                if(imageSide[i][0] > imageSide[i+1][0])                {                    inc++;                    inc+=n;                    n=0;                }                else                {                    dec++;                    dec+=n;                    n=0;                }                /* 有弧线 */                if(inc > num && dec > num)                {                    *index = i + num;                    return 1;                }            }            else            {                inc = 0;                dec = 0;n=0;            }        }        break;      case 2:        for(i = START_H-2; i > END_H; i--)        {            if(imageSide[i][1] != OV7725_UART_W-1 && imageSide[i+1][1] != OV7725_UART_W-1)            {                if(imageSide[i][1] == imageSide[i+1][1])                {                    n++;                    continue;                }                if(imageSide[i][1] > imageSide[i+1][1])                {                    inc++;                    inc+=n;                    n = 0;                }                else                {                    dec++;                    dec+=n;                    n=0;                }                /* 有弧线 */                if(inc > num && dec > num)                {                    *index = i + num;                    return 1;                }            }            else            {                inc = 0;                dec = 0;n=0;            }        }        break;    }    return 0;}

      (3)两点之间补线

      /*!   * @brief    补线处理   *   * @param    imageSide  : 边线   * @param    status     : 1:左边线补线   2:右边线补线   * @param    startX     : 起始点 列数   * @param    startY     : 起始点 行数   * @param    endX       : 结束点 列数   * @param    endY       : 结束点 行数   *   * @return   *   * @note     endY 一定要大于 startY   *   */ void ImageAddingLine(uint8_t imageSide[OV7725_UART_H][2], uint8_t status, uint8_t startX, uint8_t startY, uint8_t endX, uint8_t endY) {     int i = 0;     // 直线 x = ky + b     float k = 0.0f, b = 0.0f;     switch(status)     {       case 1://左补线         {             k = (float)((float)endX - (float)startX) / (float)((float)endY - (float)startY);             b = (float)startX - (float)startY * k;             for(i = startY; i  

      (4)判断上线是否单调

      /*!  * @brief    判断上边线是否单调  * @param    X1 :起始X点  * @param    X2 :终止X点              X1 = imageIn[0][i+1])            num++;        else            num = 0;        if (num >= (X2-X1)*4/5)            return 1;    }    for(i = X1; i  

      2.找圆环

      找圆环的特征,以左圆环为例,要求“左边线有弧,右边线单调”。左边线有弧已经说过了,这里的“右边线单调”:需要右边线在一定的横坐标范围内单调的点数大于我们设定的值,才认为是这里的“右边线单调”。

      uint8_t RoadIsRoundabout(uint8_t Upimage[2][OV7725_UART_W], uint8_t imageInput[OV7725_UART_H][OV7725_UART_W], uint8_t image[OV7725_UART_H][2], uint8_t *flag){    uint8_t i = 0;    errL=0, errR=0;    leftState = 0, rightState = 0;     count = 0;    uint8_t num = 0, py;        // 从车头往前 左边线是否单调    for(i = START_H-2; i > END_H; i--)    {        if(image[i][0] == 1)            continue;        if(image[i][0] >= image[i+1][0])    // i是Y坐标值  0 是图像左线X坐标        {            if(image[i][0]                num = 0;                leftState = 1;   // 左单调标志                break;            }        }        else        {            num = 0;        }        if(i         if(image[i][1] == OV7725_UART_W-1)            continue;        if(image[i][1]            if(image[i][1]OV7725_UART_W/2 + 5)                           num++;            else                    num = 0  ;            if(num == 50)            {                num = 0;                rightState = 1;                break;            }        }        else        {              num = 0;        }        if(i         count = 0;        if(RoundaboutGetArc(image, 2, round_size, &count))        {            *flag = 1;            return 1;        }        else        {            return 0;        }    }    /* 右边单调, 检测左侧是否是环岛 */    if(rightState == 1 && leftState == 0&& errR == 0)    {        count = 0;        if(RoundaboutGetArc(image, 1, round_size, &count))        {            *flag = 2;            return 2;        }    }    return 0;}    uint8_t i = 0, err5 = 0;    uint8_t pointX = 0, pointY = 0, inc = 0, dec = 0;    uint8_t flag= 0, Down_flag = 0;    static uint8_t finderr = 0;    static uint8_t err1 = 0;    switch(*state)    {    //奇数为入右圆环        case 1:                      // 检查弧线            err1 = RoundaboutGetArc(imageSide, 2, 3, &pointY);            // 有弧线 进行补线 连接弧线最右点 和 图像左下角            if(err1)            {                pointX = imageSide[pointY][1];                ImageAddingLine(imageSide, 2, pointX, pointY, OV7725_UART_W-1, START_H);                finderr = 1;            }            else            {                if(finderr)                    *state = 3;//准备进入环岛            }            break;            /* 发现左环岛 环岛出口处补线 */               case 3:            for(i=1;i                     ImageSide[i][0]= ImageSide[i][0]+50;               }            if(RoadUpSide_Mono(30, OV7725_UART_W-1,UpdowmSide) == 1)//上线单调增进入下一步                  *state = 5;              break;        case 5 :                err5 = RoundaboutGetArc(imageSide, 1, 10, &pointY);                //检查下线                for(i = OV7725_UART_W-1; i  0; i--)                {                    if(UpdowmSide[1][i] == 119)                          inc++;                    else                         dec++;                    if( dec                         Down_flag = 1;                        break;                    }                 }                flag = RoadUpSide_Mono(20, OV7725_UART_W,UpdowmSide);                if(flag && err5 && Down_flag)                {                     *state = 7;                }                break;        case 7:                ImageAddingLine(imageSide, 1, 80, 10, 0, START_H);                flag = RoadUpSide_Mono(50, OV7725_UART_W,UpdowmSide);                if(flag==0)                {                    *state = 0;                    finderr = 0;                    err1 = 0;                }

上一篇:揭秘游戏源代码获取攻略,轻松下载,启程游戏开发之旅!

下一篇:服务器怎么看后台管理?