图像处理之路行道线检测

  • 实验思路
  • 实验代码
  • 总结

实验思路

通过将垂直投影与一维滤波相减与一阈值比较来记录LR,找到LR的中点即为可能存在于行道线上的点,将这些点进行霍夫变换,得到一条落点最多的极坐标曲线,即为行道线所在的线。

实验代码

  1. 计算投影:
void CalProj(BYTE *pImg, int width, int height,int *projOrg)
{int realHeight = height / 15;
int x, y;
BYTE *pRow, *pCol;
memset(projOrg, 0, sizeof(int)*width);
for(pRow=pImg, y=0;y<realHeight;y++,pRow++) for (x = 0, pCol = pRow; x < width; x++, pCol++) { projOrg[x] += *pCol; }
for (x = 0; x < width; x++)
{projOrg[x] /= realHeight;
}
}

因为要将将图像分块处理,所以计算时只能计算一部分的投影,将每列相加后归一 化即得到垂直投影图。
2. 一维均值滤波

 void AverFilter(int *pData, int width,int windowLength,int *pResult)
{int i, j, sum;int halfWindow = windowLength / 2;memset(pResult, 0, sizeof(int)*width);for (i = halfWindow; i <= width - halfWindow; i++){sum = 0;for (j = i - halfWindow; j <= i + halfWindow; j++){sum += pData[j];}pResult[i] = sum / windowLength;}
}

这里直接将窗口内求平均然后赋值,然后用垂直投影图减去滤波后的投影图,对这个图求阈值
3. Otsu求阈值

 int Otsu(int *hist)
{int threshold;int gmin,gmax;gmin = 0;gmax = 256;int sum = 0, size = 0;float u1 = 0, u2 = 0, u1sum = 0, w1 = 0, w2 = 0, dist, distMax = 0;while (hist[gmax] == 0)--gmax;while (hist[gmin] == 0)++gmin;for (int i = gmin; i < gmax; i++){sum += hist[i] * i;size += hist[i];}for (int i = gmin; i < gmax; i++){dist = 0;w1 += hist[i];u1sum += i * hist[i];u1 = u1sum / w1;w2 = size - w1;u2 = (sum - u1sum) / w2;dist = w1 * w2*pow(u1 - u2, 2);if (dist > distMax){distMax = dist;threshold = i;}}return threshold;
}

求阈值时先根据直方图求出全图的最大、最小像素值,这样可以缩小搜索范围,计算w2、u2时可以通过整体减去w1、u1来求得可以加快速度,最终返回这个阈值。
4. 找到行道线的中点

 int GetMid(int *pProjOrg, int *pProjFilt,int width)
{bool isBegin;int hist[256];int midsum = 0;int begin[32], end[32],mid[32];memset(hist, 0, sizeof(int) * 256);int num;for (int i = 0; i < width; i++){num = abs(pProjOrg[i] - pProjFilt[i]);hist[num]++;}int threshold = Otsu(hist);for (int i = 0, isBegin = true; i < width; i++){num = pProjOrg[i] - pProjFilt[i];if (num > threshold){if (isBegin){begin[midsum] = i;}isBegin = false;}else{if (!isBegin){end[midsum] = i - 1;midsum++;}isBegin = true;}mid[midsum] = (end[midsum] - begin[midsum]) / 2;}return mid[32];
}

当投影与投影的滤波相减大于阈值后记录为行道线的起点,当差小于阈值后记录为终点,将中点计算出记录进一个数组中,返回重点的数组。
5. 图像分块处理

 void Divide(BYTE *pImg, int width,int height)
{int *pProj, *pProjFilt;int block = width * height / 15;int mid[32], allMid[32][15];for (int i = 0; i < 15; i++){CalProj(pImg+i*block, width, height, pProj);AverFilter(pProj, width, 3, pProjFilt);mid[32] = GetMid(pProj, pProjFilt, width);for (int j = 0; j < 32; j++){allMid[j][i] = mid[j];}}
}

将图像分成15块,对每一块进行求垂直投影、滤波、求这一块的中点数组的过程,并将所有中点数组存进二维数组,第一维记录所有的中点值,第二维记录这些值所在哪一块。
6. 霍夫变换

 void houghTransform(int mid[32][15])
{const double pi = 3.14;double LUTsin[91], LUTcos[91];int rou, theat;int count1[533][91];int count2[533][91];for (int i = 0; i <= 90; i++){float cur = i * pi / 180;LUTsin[i] = sin(cur);LUTcos[i] = cos(cur);}int x, int y;for(int i=0;i<32;i++)for (int j = 0; j < 15; j++){x = mid[i][j];y = (j+1)*23;if (x <= 452)//图像分左右两块处理{for (int theat = 1; theat < 90; theat++){rou = x * LUTcos[theat] + y * LUTsin[theat];if (rou < 553 && rou>0){count1[rou][theat]++;} }}if (x > 452){for (int theat = 1; theat < 90; theat++){rou = x * LUTcos[theat] + y * LUTsin[theat];if (rou < 553 && rou>0){count2[rou][theat]++;}}}}int max1 = 0;int max1_rou = 0, max1_theat = 0;max1 = count1[0][0];for (int i = 1; i < 553; i++)for (int j = 1; j < 90; j++){if (count1[i][j] > max1){max1 = count1[i][j];max1_rou = i;max1_theat = j;}}int max2 = 0;int max2_rou = 0, max2_theat = 0;max2 = count2[0][0];for (int i = 1; i < 553; i++)for (int j = 1; j < 90; j++){if (count2[i][j] > max2){max2 = count2[i][j];max2_rou = i;max2_theat = j;}}int k1, k2, b1, b2;exchange(max1_rou, max1_theat, &k1, &b1);exchange(max2_rou, max2_theat, &k2, &b2);
}

将二维数组中的值转换为x、y进行霍夫变换,并对图像分左右处理,因为霍夫变换投票前两名的结果会很接近,其实是一边的行道线,所以分左右处理,得到两边的极坐标方程的参数转换为直角坐标画出如图:

总结

这次实验让我学习到了在处理实际问题中,代码对于适应不同环境的能力的重要性,之前觉得对于道路的照片直接进行二值化也可以得到行道线的位置,但没有考虑光照等的因素,这样在天黑的时候二值化就什么也得不到了,但是通过计算投影及投影的滤波的差就可以很好地解决光线过暗的问题,但我在求左右两条行道线的时候把图像分成了两块,这样似乎也是不妥的,因为车遇到拐弯的时候同一条行道线可能会在左右两半图像中出现,这样就不能识别为一条线了,但是霍夫变换的投票又不能只取前两名,应该可以设定一个阈值,将投票结果高的都显示出来,这样应该能显示出图像上很多线段,但在例图的情况下还是分块处理效果比较好。

图像处理之道路行道线检测相关推荐

  1. Python实现道路车道线检测(附源码)

    车道线检测是自动驾驶汽车以及一般计算机视觉的关键组件.这个概念用于描述自动驾驶汽车的路径并避免进入另一条车道的风险. 在本文中,我们将构建一个机器学习项目来实时检测车道线. 我们将使用 OpenCV ...

  2. yolov5+车道线检测

    目标检测与车道线检测在自动驾驶以及车辆定位中起着重要的辅助作用,是环境感知中不可缺少的一个部分.基于深度学习的车道线检测方法近年来也在不断的提升,比如论文:Ultra Fast Deep Lane D ...

  3. ECCV2020超快车道线检测算法——Ultra Fast Structure-aware Deep Lane Detection论文浅读

    文章目录 前言 一.深度分割的局限性 二.目前车道线检测的难点 三.超快速车道线检测算法 1.算法定义 2.如何解决速度的问题 3.如何解决"no-visual-clue"的问题 ...

  4. ECCV2020|超快的车道线检测,代码模型已开源

    作者|cfzd 来源|https://zhuanlan.zhihu.com/p/157530787 很高兴和大家分享一下我们刚刚被 ECCV 2020 接收的新工作:一种超快速的车道线检测算法(Ult ...

  5. ECCV2020超快车道线检测算法:Ultra Fast Structure-aware Deep Lane Detection

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者:cfzd| 来源:知乎 https://zhuanlan.zhihu.com/p/1575307 ...

  6. ECCV 2020 | 超快的车道线检测

    本文转载自知乎,已获作者授权转载. 链接:https://zhuanlan.zhihu.com/p/157530787 很高兴和大家分享一下我们刚刚被 ECCV 2020 接收的新工作:一种超快速的车 ...

  7. 基于摄像头的车道线检测方法一览

    首发于 自动驾驶的挑战和发展 写文章 基于摄像头的车道线检测方法一览 黄浴 ​ 自动驾驶话题下的优秀答主 174 人 赞同了该文章 车道线,重要的路上语义信息,检测车道线对L2-L3-L4级别的自动驾 ...

  8. Opencv-Python处理车道线检测

    利用Opencv和Python结合完成车道线检测 1 前言 去年对Opencv系统学习了一段时间,后面没有继续更新博客,但自己也有继续学习啦,哈哈,最近做了一个小项目,利用图像处理算法解决车道线检测. ...

  9. 【车道线检测】车道线检测算法汇总

    文章目录 零. 概述 1. DataSet 2. 车道线检测难点 3. 数据增强 一.基于分割和辅助实例化信息的方法 1. HDMapNet: An Online HD Map Constructio ...

最新文章

  1. ES6 -Set 和 Map 数据结构
  2. oracle备份片校验,oracle rman 备份日志单独备份和交叉校验
  3. 【安利向】入坑半年的GPU云平台,三分钟训练起飞!xiu~
  4. linux用pe大小做逻辑卷,Linux常用命令之--逻辑卷
  5. linux报mce清除不良代码,如何分析系统MCE异常?
  6. Linux录音软件audacity安装:sudo yum install audacity
  7. python代码编写_高质量Python代码编写的5个优化技巧
  8. 信息学竞赛中的直觉与证明 - 刘汝佳
  9. mac远程桌面windows
  10. html代码标签优化与提速,HTML代码标签优化与提速
  11. 红孩儿编辑器的开发 1 字体库的生成过程
  12. Java中IO流-18-flush和close方法的区别
  13. 如何将知识结构化,形成知识管理体系(干货分享)
  14. java毕业设计企业门户网站源码+lw文档+mybatis+系统+mysql数据库+调试
  15. UID-04-PS-书籍装帧
  16. 【超详细图解】字符串匹配Boyer-Moore算法:文本编辑器中的查找功能是如何实现的?
  17. 项目成本管理-成本控制工具技术:挣值管理
  18. 这6个自学网站在知乎得到40万的热推!凭什么?看了就知道!
  19. 高大上的2014WE大会
  20. isblank java_判空我推荐StringUtils.isBlank

热门文章

  1. python 设计模式-2
  2. mmorpg 游戏服务器设计
  3. 多屏幕炒股计算机配置,多屏幕股票交易计算机配置建议使用i59400F计算机主机配置(最多六个屏幕)...
  4. 从小白到大神Java学习路线
  5. SUMO中车辆类型的定义及路由文件的写法
  6. CSS改变图片颜色的三种方法
  7. 进出口合同的履行及具体操作程序
  8. windows mobile POOM
  9. dhclient出错
  10. 涨握在线|微软宣布400亿回购计划,华为发布mate30对战Iphone 11