博主使用的逐飞家的总钻风摄像头,这是一款灰度摄像头,配合逐飞的底层库,可以很快的上手。在我当时拿到总钻风的第一时间,就用逐飞的底层库,配合tft显示屏,显示简单的图像,虽然简单,当时的心情其实还是很激动的。

而这时,我们显示的,其实就是一张灰度图像。我的是120*188的灰度图像,例如:

针对这些灰度图像,我们需要对它进行阈值处理以便之后的赛道信息提取。

首先,我们得知道,我们所得到了这120*188的图像,实际上也就是120*188个不同灰度值的像素点组成,对于这么多个像素点处理的最基本的思想,就是找到一个阈值,能够确保这个阈值可以把赛道和背景分离出来,而这,也就是所谓的图像二值化处理,它通过不同的算法得到图像的一个跳变阈值,将大于这个阈值的区域置为全白,小于它的阈值置为全黑。

下面给出几种得到阈值的算法思路和代码:

(一)迭代法求阈值

由于赛道的蓝色背景和白色赛道的灰度分布十分明显,我们可以用适用于整个图像的单个(全局)阈值,在大多数应用中,通常图像之间有较大变化,即使全局阈值是一种合适的方法 ,也需要有能对每幅图像自动估计阈值的算法。下面的迭代算法可用于这一目的:

基本思路:

1.为全局阈值T选择一个初始估计值。

2.用T分割该图像。这将产生两组像素: G1 由灰度值大于T的所有像素组成,G2由所有小于等于的像素组成。
3.对G和G2的像素分别计算平均灰度值(均值) m1和m2。

4.计算一个新的阈值: T=1/2(m1+m2)。

5.重复步骤2到步骤4,直到连续迭代中的T值间的差小于一个预定义的参数ΔT为止。

#define Thres          128    //阈值
#define ERROR      2      //误差int16  EdgeThres = 18; //晚上20  白天25 18
float  BlackThres = 58;   //黑白阈值//迭代法计算阈值
void Iteration_Threshould(void)
{uint16_t i = 0,j = 0,N0 = 0,N1 = 0,flag = 0;float T0,T1,T2,T_center;uint32_t S0 = 0,S1 = 0;T2 = BlackThres;do{for(i=0;i<ROW_H;i++){for(j=0;j<COL_W;j++){if(image[i][j] < T2){S0 += image[i][j];N0++;}else{S1 += image[i][j];N1++;}}}T0 = S0/N0;T1 = S1/N1;T_center = (T0+T1)/2;if(T2 < T_center){if((T_center - T2)> ERROR){flag = 1;}else{flag = 0;}}else{if((T2 - T_center) > ERROR){flag = 1;}else{flag = 0;}}T2 =T_center;BlackThres = T2;}while(flag);}

当与物体和背景相关的直方图模式间存在一个相当清晰的波谷时,这个简单的算法工作得很好。
在速度是一个重要因素的情形下, 参数ΔT用于控制这代的次数。通常,ΔT越大,则算法执行的迭代次数越少。所选的初始阈值必须大于图像中的最小灰度级而小于最大灰度级。图像的平均灰度对于T来说是较好的初始选择。

(二)基于Otus的最佳全局阈值处理

阈值处理可以视为一种统计决策理论问题, 其目的是在把像素分配给两个或多个组(也称为分类)的过程中使引人的平均误差最小。

Otus,也称大津法, 该方法在类间方差最大的情况下是最佳的。基本概念是,好阈值分类就其像素灰度值而论,应是截然不同的,反过来说,就其灰度值而言给出最好的类间分离的阈值就是最好的(最佳的)阈值。除了其最佳性之外,大津法还有一个重要的特性,即它完全以在一幅图像的直方图上执行计算为基础,直方图是很容易得到的一维阵列。

基本思路:

1.计算灰度级中每个像素在整幅图像中的个数

2.计算每个像素值的点在整幅图像中的概率

3.计算全局灰度均值

4.计算类间方差

5.得到Otus阈值

#define GrayScale 256int pixelCount[GrayScale];
float pixelPro[GrayScale];uint8 my_adapt_threshold(uint8 *image, uint16 col, uint16 row)
{uint16 width = col;uint16 height = row;int i, j, pixelSum = width * height/4;uint8* data = image;  //指向像素数据的指针for (i = 0; i < GrayScale; i++){pixelCount[i] = 0;pixelPro[i] = 0;}uint32 gray_sum=0;//统计灰度级中每个像素在整幅图像中的个数  for (i = 0; i < height; i+=2){for (j = 0; j < width; j+=2){pixelCount[(int)data[i * width + j]]++;  //将当前的点的像素值作为计数数组的下标gray_sum+=(int)data[i * width + j];       //灰度值总和}}//计算每个像素值的点在整幅图像中的比例  for (i = 0; i < GrayScale; i++){pixelPro[i] = (float)pixelCount[i] / pixelSum;}//遍历灰度级[0,255]  float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;for (j = 0; j < GrayScale; j++)         {w0 += pixelPro[j];  //背景部分每个灰度值的像素点所占比例之和   即背景部分的比例u0tmp += j * pixelPro[j];  //背景部分       每个灰度值的点的比例 *灰度值 w1=1-w0;u1tmp=gray_sum/pixelSum-u0tmp;u0 = u0tmp / w0;              //背景平均灰度u1 = u1tmp / w1;              //前景平均灰度u = u0tmp + u1tmp;            //全局平均灰度deltaTmp = w0 * pow((u0 - u), 2) + w1 * pow((u1 - u), 2);if (deltaTmp > deltaMax){deltaMax = deltaTmp;threshold = j;}if (deltaTmp < deltaMax){break;}}return threshold;
}

通过以上两种算法可以得到全局阈值,接下来我们可以直接根据得到的阈值选择去二值化

void Binarization()
{for(int i=0;i< MT9V03X_CSI_H;i++){for(int j=0;j<MT9V03X_CSI_W;j++){if( mt9v03x_csi_image[i][j]>threshold){image_deal[i][j]=white;}else {image_deal[i][j]=black;       }image_showlcd[i][j]=image_deal[i][j];}}
}

以上步骤,我们可以得到一帧稳定的二值化图像

至此,针对一般的赛道场地,以上两种二值化的方法完全可以适用,但我们不排除会出现一些极端的情况,例如阳光的影响,万一一道上帝之光照射到赛道上,造成了赛道部分的灰度值发生畸变,这时候,基于全局的阈值算法似乎就显得有些无法应对,也可以采用逐飞的差比和灰度处理。但目前来看一般赛场不会出现特别极端的情况,以上两种算法其实完全够用

智能车图像处理(一)阈值处理相关推荐

  1. 【第十七届智能车】智能车图像处理(2)-赛道边界的简单提取和无元素循迹

    本博客使用的图像是188*120的大津法二值化图像.摄像头安装高度为25cm(离地),前瞻长度约1m. 智能车图像处理的过程就是读取输入的图像,经过处理后向控制部分输出一个偏差值,控制部分根据再这个偏 ...

  2. 智能车图像处理-阳光算法

    阳光算法见仁见智,多阈值OSTU和模糊OSTU是我参考论文进行改进的,整篇内容都放进了我的本科毕业论文中. 感谢大家的留言和指正,首先,这个算法经过实践,确实存在问题,因为当时毕业比较忙,我在智能车上 ...

  3. 【第十七届智能车】智能车图像处理(1)-图像预处理

    本博客使用的硬件是逐飞总钻风130°无畸变摄像头,采用的图像分辨率为188*120,主控为CH32V307VCT6,使用DVI接口进行连接. 前言 我们在本次比赛中采用的是头尾车总钻风摄像头+中间车线 ...

  4. 智能车图像处理逆透视教程

    去畸变请参考:图像处理去畸变教程_LoseHu的博客-CSDN博客 去畸变+逆透视请参考:​​​​​​​​​​​​​​​​​​​​​智能车去畸变+逆透视教程_LoseHu的博客-CSDN博客 逆透视: ...

  5. 智能车图像处理去畸变教程

    逆透视请参考:智能车逆透视教程(含上位机.源码)_Wyean的博客-CSDN博客  去畸变+逆透视请参考:智能车去畸变+逆透视教程_LoseHu的博客-CSDN博客 去畸变:如下 1.简介 对于镜头而 ...

  6. 智能车图像处理11-斜入十字补线

    前言 这篇文章主要讲述智能车竞赛中如何对于斜入十字进行补线操作. 一.代码 思路讲解: 补十字相较于 其他元素 是比较简单的 核心就是找十字路口: 四个拐点(也许看不到四个,比如斜入时可能只能看到一个 ...

  7. 智能车图像处理8-右环岛状态机与补线

    前言 这篇文章主要讲述智能车竞赛中如何判断右环岛并且进行状态补线. 一.函数主体 /* 注释1:环岛的八个状态 环岛分为八个状态.以右环岛为例,一二三状态都在未入环的直道上,这时候需要把右环岛的 中拐 ...

  8. 智能车图像处理之透视变换

    透视变换介绍 透视变换被广泛应用于投影仪器.倒车影像等视觉设备当中.在智能车竞赛中,通过摄像头对赛道信息的采集,在单片机上提取赛道两边的边缘,经过处理后控制小车在赛道边缘内行驶.但由于摄像头与赛道之间 ...

  9. 17届智能车图像处理部分讲解

    目录 须知 寻边线 寻拐点 补线 最后 须知 讲解代码使用的摄像头为总钻风摄像头,图像像素为188*120,图像进行了二值化,这里建议如果需要对光线有要求的同学使用灰度处理.没有使用过上位机,展示的图 ...

最新文章

  1. 北电ERS1600,8300,8600交换机的基本技术-第六章 二层冗余技术(MLT,SMLT,IST)
  2. python是如何实现进程池和线程池的_高并发:线程、线程锁与线程池(精华),手写代码实现线程池...
  3. usb打印机linux识别不了怎么办,win10不识别usb打印机怎么回事_win10系统不识别usb打印机如何修复-系统城...
  4. Java向C++发送结构体
  5. BusinessEtiquette,Communication Skill(外企职场商务礼仪与沟通技巧)
  6. Android 系统(132)---ODM 开发用户常见需求文档(六)
  7. 基于JAVA+SpringBoot+Mybatis+MYSQL的婚纱影楼摄影网站
  8. 自动量策略的开发和优化
  9. hack wifi android,WiFi Hack AIO 2010 - WiFi v1.2
  10. 拿下最佳论文、世界第一,这个团队过去一年真的牛
  11. Matlab 2016a 安装包及破解教程
  12. 最新QQ勋章墙+防撤回V9.6.1版本+实测可用
  13. 广东工业大学华立学院c语言试题,广东工业大学华立学院考试试卷《高频电子线路》-2015.doc...
  14. 视频教程-备战2020毕业季—毕业设计论文实战课程讲解-.NET
  15. 虚拟机win7系统忘记开机密码怎么办
  16. keil软件是干嘛的?keil软件怎么用?
  17. 硬件安全技术-5G时代IOT环境下芯片安全风险与挑战
  18. 用AI画一只漂亮的羽毛
  19. Python concurrent.futures 的 map 函数解释
  20. 开发中国最好的视频推荐系统

热门文章

  1. 管理目录和文件的属性
  2. emd分解matlab程序
  3. 【办公-WORD】特殊字符替换-^l-下箭头(↓),^p-换行等等
  4. C语言保留小数相关问题
  5. 京东笔试Java暑期实习笔经21/3/27
  6. 中创股份在科创板提交上会稿:计划募资6亿元,景新海为董事长
  7. JAVA 日历输出_java控制台输出日历
  8. 喷枪打字效果(实现文字一个一个出现)
  9. 数据库的关系表:一对多、多对多实例
  10. 一文掌握组织项目等级划分维度,标准和实例