在阅读了两篇关于设定阈值来识别LED图像的论文后,对如何设定合适的阈值来对不同的LED-ID进行解码有了初步的认识,下面是我对这几种方法的理解及思考。

(1)三次多项式拟合


算法基于的思路非常简单,通过构造一个多项式曲线对列矩阵上点的灰度值分别作差,然后平方来消除正负,着重刻画差的大小,再全体求和得到一个以a0、a1、a2、a3为变量来描绘差的整体大小的函数E,分别对a0、a1、a2、a3求偏导并令其为0,得到令E为最小值的a0、a1、a2、a3,再将其代入原式中即得到所要求的多项式f(xi),相当于对灰度值进行了一个非线性回归,多项式在每一个xi点处的值即为该点灰度值的阈值。然而偏导为零仅为E取得最小值的必要条件,无法保证得到的多项式曲线是最优的,因此该法数学上有天然的缺陷,并且得到的曲线一般比较平缓,缺乏对快速密集信号的响应能力,在照度较低时误码率高。

(2)迭代阈值

对目标图片的像素先进行合适大小的分组(像素数应当可以被整除),每组分割过大,阈值曲线无法正确地落在灰度值的中间;分割过小,阈值曲线将接近图像的最大灰度值,均无法得到合理的阈值。分组完成以后算出每组的平均灰度值T,并将此平均灰度值T作为阈值将原来小组的灰度值再分成两组(大于和小于该均值T),然后分别计算这两个子小组的平均灰度值U1、U2,将其相加取平均得到新的灰度值Tk,用Tk的值取代上面的T并重复上述过程直到Tk=T(实际操作中难以达到且性价比不高,故设定合理的值α>0,当α>|Tk-T|时认为满足条件)。

(3)快速自适应阈值

其基本思想是计算像素灰度值的平均波动值。该算法可通过对函数的递归调用来完成,因此其在硬件上易于实现。

更快的计算方法是计算到xi处灰度值的前s个灰度值,并对其根据与xi的距离分别进行加权(1-1/s)n,离得越远影响越小,离得近的影响大。S的取值通常为所处理像素列大小的1/8。r为比例系数,可通过实验来合理选取其大小(有0.85左右的经验值)。

(4)平均极值法

该算法的核心在于“线性插值”和“阈值计算”两个部分。首先为了提高采样点,对实验中得到的像素向量进行线性插值。
然后找出其中的灰度最大值Gmax,对该灰度值两边的像素分别交替求局部极小值和局部极大值,每个相邻的极大值和极小值的平均值即为它们之间的像素点的灰度阈值Gthreshold。其中,由于要剔除可能存在的噪声对信号的影响,因此要设定一个参考值Gref来进行区分,并且目标极值Pcursor与上一个极值之间的距离应当大于一个采样率。

最后

在实际选取ROI来进行处理时,由于选取的ROI往往比LED圆形区域要大,因此很难确保ROI的宽度值/2以后的列像素落在LED区域的中央。为此,应对ROI进行适当的裁剪并对列数进行判断,若为奇数则选取中间相邻的3列,然后取分别进行处理的结果进行比对,以少数服从多数的原则进行取舍;若为偶数,则选取中间的2列,然后进行处理并遵循保护信号1的原则(当然这可能会使被噪声干扰的可能性增加),最后再将最终的处理结果输出。

下面是示例部分代码:

for (int i = 0; i < srcROI.size(); i++){resizeROI(srcROI[i], srcROI[i]);       //裁剪ROI,在测试里发现,由于本来框的拟合就较好这个resize意义并不是很大}double T = 0;int output = 0;vector<int>outputarray;     //result arrayint s = ((srcROI[0].rows / 8)+0.5);         //得到s的合适值,四舍五入select(srcROI[0], srcROI[0]);int colnumber = 0;if (srcROI[0].cols%2==0){colnumber = 2;}else{colnumber = 3;}vector<vector<int>>resultarray;int rownumber = srcROI[0].rows;switch (colnumber)         {case 2:for(int c = 0; c < 2; c++){//先处理前s-1个像素,这里的思路是用第s个像素的阈值来代替其阈值singlepixelthreshold(srcROI[0], T, rownumber, s - 1, s);for (int i = 0; i < s - 1; i++){uchar* data = srcROI[0].ptr<uchar>(i);if (data[c] > T){output = 1;                       //默认白色为1 }else{output = 0;}outputarray.push_back(output);}//处理后面的像素for (int i = s - 1; i < rownumber; i++){singlepixelthreshold(srcROI[0], T, rownumber, i, s);uchar* data = srcROI[0].ptr<uchar>(i);if (data[c] > T){output = 1;                     //默认白色为1 }else{output = 0;}outputarray.push_back(output);}resultarray.push_back(outputarray);outputarray.clear();}for (int i = 0; i < rownumber; i++){//对照验证,有一个1就为1,尽可能保护1resultarray[0][i] || resultarray[1][i] ? outputarray.push_back(1) : outputarray.push_back(0);}break;case 3:for (int c = 0; c < 3; c++){//先处理前s-1个像素,这里的思路是用第s个像素的阈值来代替其阈值singlepixelthreshold(srcROI[0], T, rownumber, s - 1, s);for (int i = 0; i < s - 1; i++){uchar* data = srcROI[0].ptr<uchar>(i);if (data[c] > T){output = 1;                       //默认白色为1 }else{output = 0;}outputarray.push_back(output);}//处理后面的像素for (int i = s - 1; i < rownumber; i++){singlepixelthreshold(srcROI[0], T, rownumber, i, s);uchar* data = srcROI[0].ptr<uchar>(i);if (data[c] > T){output = 1;                     //默认白色为1 }else{output = 0;}outputarray.push_back(output);}resultarray.push_back(outputarray);outputarray.clear();}int sum = 0;for (int i = 0; i < rownumber; i++){//对照验证,少数服从多数sum = resultarray[0][i] + resultarray[1][i] + resultarray[2][i];sum >= 2 ? outputarray.push_back(1) : outputarray.push_back(0);}break;}
return 0;
}
void resizeROI(Mat input, Mat &output) {                //筛选出不全为0的行,作为新ROI的边界int rownumber = input.rows;int colnumber = input.cols;int top, bottom;                                //记录行数//TOPfor (int i = 0; i < rownumber; i++)                //会损失掉一开始部分的0信号{int exit = 0;uchar* data = input.ptr<uchar>(i);for (int j = 0; j < colnumber; j++){if (data[j] <= 20) {           //背景并不是全黑的,所以不能取0continue;}else {exit = 1;break;}}if (exit == 1) {top = i;break;}}//BOTTOMfor (int i = rownumber-1; i > 0; i--)              //会损失掉末尾部分的0信号{int exit = 0;uchar* data = input.ptr<uchar>(i);for (int j = 0; j < colnumber; j++){if (data[j] <= 20) {continue;}else {exit = 1;break;}}if (exit == 1) {bottom = i;break;}}output = input(Rect(0, top, colnumber, bottom - top + 1));                //截图
}void select(Mat input, Mat &output) {int rownumber = input.rows;int colnumber = input.cols;if (colnumber%2==0)             //整除{output = input(Rect((colnumber / 2) - 1, 0, 2, rownumber));}else {output = input(Rect((colnumber / 2) - 1, 0, 3, rownumber));}
}void singlepixelthreshold(Mat input, double &output, int rownumber, int i, int s) {double T = 0;double f = 0;int n = 0;for (int j = i; j > i-s; j--){uchar* data = input.ptr<uchar>(j);T += pow((1 - 1.f / s), n)*data[0];f += pow((1 - 1.f / s), n);n++;}output = 0.88*T / f;                //这里的r取0.88,得到最终的阈值
}

LED通信的ID识别报告相关推荐

  1. AIR32F103(九) CAN总线的通信和ID过滤机制及实例

    目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...

  2. 基于Jetson Nano与STM32通信的颜色识别与伺服驱动器控制

    基于Jetson Nano与STM32通信的颜色识别与伺服驱动器控制 jetrson nano部分 颜色识别 串口通信 数据传输 完整代码 stm32 部分 数据解读 电机控制 主函数 电机加减速 硬 ...

  3. 人工智能行业:人脸识别报告,“刷脸”时代到来

    https://www.toutiao.com/a6665970984035549708/ 人工智能行业:人脸识别报告,"刷脸"时代到来,看好掌握核心技术与应用场景深耕的企业 类别 ...

  4. 企业通信基础设施行业调研报告 - 市场现状分析与发展前景预测

    企业通信基础设施市场的企业竞争态势 该报告涉及的主要国际市场参与者有Alcatel-Lucent.Avaya.Cisco Systems.Ericsson.Genband.IBM.Microsoft. ...

  5. LED数码管的识别及检测方法

    1. LED数码管介绍 LED数码管也称半导体数码管,它是将若干发光二极管按一定图形排列并封装在一起的最常用的数码显示器件之一.LED数码管种类很多,品种五花八门,这里仅向初学者介绍最常用的小型&qu ...

  6. 通信原理抽样定理MATLAB实验报告,通信原理抽样定理实验报告

    与<通信原理抽样定理实验报告>相关的范文 通信原理软件实验报告 学 院:信息与通信工程学院 班 级: 班内序号: 学生姓名: 学 号: 实验二 时域仿真精度分析 一[实验目的] 1. 了解 ...

  7. 第一次参加kaggle竞赛:Happywhale - Whale and Dolphin Identification(ID识别问题:top9.4% 150/1558)

    一.ID识别问题 ID1: ID2: 下图是哪个ID: 二.训练数据分布 51033张训练图片, 27956张测试图片,public LB用了24%的测试图片,最后结果以private LB的结果为准 ...

  8. LED水下手电筒行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)

    LED水下手电筒市场的企业竞争态势 该报告涉及的主要国际市场参与者有Underwater Kinetics.Light & Motion.Bigblue Dive Lights.Princet ...

  9. AS608指纹模块与stm32f103c8t6通信实现指纹识别

    目录 AS608指纹模块 stm32f103c8t6最小系统板以及其他外设 工程资料 遇到的问题  AS608指纹模块 光学指纹模块更好用一点,电容式指纹模块的通信协议有一点不一样. 网上可以搜到相关 ...

最新文章

  1. java word模板替换多行_java poi word模板替换段落的换行显示
  2. 深度学习:人脸识别学习笔记
  3. 没有IF-ELSE的工厂
  4. Lolipa魔方财务主题-虚拟主机源码
  5. 电脑时钟倒计时_倒计时久坐休息提醒工具
  6. 由DB2分页想到的,关于JDBC ResultSet 处理大数据量
  7. 小D课堂 - 零基础入门SpringBoot2.X到实战_第2节 SpringBoot接口Http协议开发实战_12、SpringBoot2.x文件上传实战...
  8. Web服务器性能压力测试工具
  9. TPC-DS标准规范(2)
  10. ES系列:解决Cluster state has not been recovered yet, cannot write to the [null] index问题
  11. linux 密码字典生成,Linux下的字典生成工具Crunch 创造自己的专属字典
  12. 如何解决win10 软件运行看不见窗口问题
  13. 模电_数电_微机接口_微机应用实验装置,QY-MS535F
  14. GSM多时隙NV配置
  15. 解读基金—读书框架笔记①
  16. 音量(DB)为什么都是负值
  17. CDH大数据平台 ERROR Heartbeating to 192.168.0.200:7182 failed
  18. 关于继电器开关带来的干扰
  19. sent2vec教程
  20. MacBook Pro使用初体验之Mac快捷键汇总(持续更新中)

热门文章

  1. 语音编码标准(G.711 G.723 G.726 G.729 iLBC) .
  2. 语音编码标准(G.711 G.723 G.726 G.729 iLBC)
  3. Python骚操作—自动刷抖音
  4. Java语言为excel添加水印,使用原生POI, (XSSFWorkbook, XSSFSheet), 真正背景图水印效果,非普通图片张贴
  5. Tomcat闪退或者访问不到主页等情况
  6. 模拟复杂红绿灯交通指示程序编程显示黄灯闪烁箭头指示
  7. Android drozer漏洞检测
  8. mysql 8安装方法_Mysql8.0.17安装教程【推荐】
  9. 计算机故障声音,不同的电脑故障声音分别是什么意思【详解】
  10. 荣耀卖掉会有鸿蒙系统吗,华为为什么要把荣耀卖掉 荣耀卖掉之后依然还是那个荣耀吗?...