最近搞个触摸屏校准,参考了Tslib,感觉这个算法挺巧妙。

一般触摸屏校准无非以下几种情况:



根据触摸的AD值和LCD分辨率不同,两者会有比例关系。触摸屏安装的时候可能会和LCD不太契合,比如贴歪了,可能会有移动和旋转的误差,使得两者坐标有偏差。

正因为有这些误差,才需要校正。假设屏上有个P点,在LCD的坐标是(X, Y),在触摸屏上是(X’, Y’)。在二维坐标下上面三种情况分别可以用如下三个矩阵表示(不是我编的):

咱也不用考虑当前哪种情况了,假设三个误差都存在(某项不存在的话,后面带入计算自然会去除掉),就全部乘一下:

其中 X,Y是LCD坐标由自己设定,X′和Y′触摸屏的坐标,由测量得知。而我们目的就是求αx,βx,ΔX和αy,βy,ΔY这6个未知数而已,那只要构建6个方程,只需要取屏幕上3个点即可。

注意:重点来了不要被上面的推导过程吓到,又是三角函数又是矩阵相乘,其实没人会关心触摸屏和LCD到底贴歪了多少度,移动了多少个像素点,只要知道我们的目的是为了求这些系数,这些值能帮助我们将触摸屏坐标转化为LCD坐标就可以了,更简化且平易近人的写法如下:

解方程的话,可以用克拉默法则,自己玩的话随便取3个点手算也行,注意3点法需要取独立点,即在屏幕上画出三个已知LCD坐标的点,最好不要连成一条线,然后记录下这些点的触摸屏坐标,代入方程可得:

这样可以求出A,B,C,D,E和F,若按矩阵写法(还是换回α和β的写法)如下:
写成方程就是 b= A∙x,或x = A-1 ∙ b,其中A是系数矩阵,b是常数列向量,x是未知数列向量。对应上面x坐标的公式b就是,未知数列向量就是

:要求的线性方程x = A-1 ∙ b中,A-1=A*/|A|,设Δ = |A|也就是系数矩阵A的行列式值,伴随矩阵A*与b相乘之后得到Aj,那么未知数解xj = |Aj|/|A|。本方程3个未知数的|A1|,|A2|和|A3|标记为为Δx1、Δx2和Δx3,那么3个未知数解分别是αx = Δx1/Δ,βx = Δx2/Δ,ΔX = Δx3/Δ。这是克拉默法则。


以上铺垫完毕,通通不用记,下面说说Tslib里面的5点法,或者叫n点法,改写上面的矩阵如下:


按照之前3点法的解法我们也用克拉默法则,但是忽然发现A居然不是方阵!!A是nx3(n>3)的矩阵!A-1都没有意义了!x = A-1 ∙ b都没了! 还有啥用!!

等等,有点大惊小怪了,不是方阵的话A-1就是个伪逆矩阵吧!n>3左逆矩阵为 A-1 = (ATA)-1 AT,那么公式变为

为啥要这么变?别和我说什么最小二乘解左逆右逆什么最优解之类的,我就是想要搞个方阵,A的转置AT 和A相乘就变成方阵,令A = ATA,b = ,这样x = A-1 ∙ b又来了!接下来只要求出ATA和就可以用克拉默法则了。


为了计算方便我们定义如下:

那么可以放心求解:

重点来了,以上公式统统不用纠结,带入上面公式可以发现一个规律

ts_calibration_common.c

int perform_calibration(calibration *cal)
{int j;float n, x, y, x2, y2, xy, z, zx, zy;float det, a, b, c, e, f, i;float scaling = 65536.0;/* Get sums for matrix */n = x = y = x2 = y2 = xy = 0;for (j = 0; j < 5; j++) {n += 1.0;x += (float)cal->x[j];y += (float)cal->y[j];x2 += (float)(cal->x[j]*cal->x[j]);y2 += (float)(cal->y[j]*cal->y[j]);xy += (float)(cal->x[j]*cal->y[j]);}/* Get determinant of matrix -- check if determinant is too small */det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);if (det < 0.1 && det > -0.1) {printf("ts_calibrate: determinant is too small -- %f\n", det);return 0;}/* Get elements of inverse matrix */a = (x2*y2 - xy*xy)/det;b = (xy*y - x*y2)/det;c = (x*xy - y*x2)/det;e = (n*y2 - y*y)/det;f = (x*y - n*xy)/det;i = (n*x2 - x*x)/det;/* Get sums for x calibration */z = zx = zy = 0;for (j = 0; j < 5; j++) {z += (float)cal->xfb[j];zx += (float)(cal->xfb[j]*cal->x[j]);zy += (float)(cal->xfb[j]*cal->y[j]);}/* Now multiply out to get the calibration for framebuffer x coord */cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));printf("%f %f %f\n", (a*z + b*zx + c*zy),(b*z + e*zx + f*zy),(c*z + f*zx + i*zy));/* Get sums for y calibration */z = zx = zy = 0;for (j = 0; j < 5; j++) {z += (float)cal->yfb[j];zx += (float)(cal->yfb[j]*cal->x[j]);zy += (float)(cal->yfb[j]*cal->y[j]);}/* Now multiply out to get the calibration for framebuffer y coord */cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));printf("%f %f %f\n", (a*z + b*zx + c*zy),(b*z + e*zx + f*zy),(c*z + f*zx + i*zy));/* If we got here, we're OK, so assign scaling to a[6] and return */cal->a[6] = (int)scaling;return 1;
}

此时会发现算出的这些红色的系数公式和Tslib内的perform_calibration函数内的一模一样

完结撒花。

Tslib的触摸屏5点校准算法原理和实现相关推荐

  1. 电阻触摸屏的校准算法

    一.   为什么要校准 简单来说,电阻式触摸屏就是一种传感器,它利用压力感应进行控制,将矩形区域中触摸点(X,Y)的物理位置转换为代表 X坐标和 Y 坐标的电压 电阻式触摸屏的主要部分是一块与显示器表 ...

  2. CRF(条件随机场)与Viterbi(维特比)算法原理详解

    摘自:https://mp.weixin.qq.com/s/GXbFxlExDtjtQe-OPwfokA https://www.cnblogs.com/zhibei/p/9391014.html C ...

  3. 三维目标检测算法原理

    三维目标检测算法原理 输入输出接口 Input: (1)图像视频分辨率(整型int) (2)图像视频格式(RGB,YUV,MP4等) (3)左右两边的车道线位置信息摄像头标定参数(中心位置(x,y) ...

  4. 3D-2D:PnP算法原理

    3D-2D:PnP算法原理 1.问题背景-- 什么是PnP问题 ? 2.PnP问题的求解方法 2.1 P3P 2.1.1 算法的实际理解 2.1.2 算法的数学推导 2.1.3 算法的缺陷 2.2 直 ...

  5. MySQL索引背后的数据结构及算法原理【转】

    http://blog.codinglabs.org/articles/theory-of-mysql-index.html MySQL索引背后的数据结构及算法原理[转] 摘要 本文以MySQL数据库 ...

  6. 文本分类的基本思想和朴素贝叶斯算法原理

    文本分类的基本思想和朴素贝叶斯算法原理

  7. Bagging与随机森林算法原理小结

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boos ...

  8. 干货 | 非常全面的谱聚类算法原理总结

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 谱聚类算法是目前最流行的聚类算法之一,其性能及适用场景优于传统的聚 ...

  9. 层次聚类算法原理总结

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 层次聚类(hierarchical clustering)基于簇间 ...

  10. 从传感器到算法原理,机器人、视觉避障尽在此文

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:计算机视觉life 避障是指移动机器人在行走过程中,通过 ...

最新文章

  1. MyBatis学习--简单的增删改查
  2. div的contentEnable属性
  3. bert简介_关于BERT:你不知道的事
  4. Linux基础二(挂载、关机重启与系统等级)
  5. [luoguP2760] 科技庄园(背包DP)
  6. 联想小新/YOGA新品发布会官宣:定档10月20日
  7. 自学c语言中相关知识,设计出医院住院管理系统.要求如下所述:,C语言课程设计题Z目.doc...
  8. 如何走技术路线的研究生论文?
  9. vue-cli3 中 sockjs-node/info?t=报错 的解决方法
  10. JQuery之事件冒泡
  11. JavaScript篇 深入理解JavaScript函数
  12. VOD崛起《暮光之城》带动电影同步发行模式
  13. 从0到1:如何创建YouTube频道(手把手设置指南)
  14. python操作autocad_利用python控制Autocad:pyautocad方式
  15. qt程序报错error C2248: “ThreadTest::ThreadTest”: 无法访问 private 成员(在“ThreadTest”类中声明)
  16. 中国越野车和皮卡市场趋势报告、技术动态创新及市场预测
  17. android车载应用市场,车载市场
  18. python从入门到入魔第三天——time库和datetime库基本使用
  19. BZOJ 1367 [Baltic2004]sequence
  20. 技术人变现的9个路线

热门文章

  1. java B2B2C Springcloud电子商城系统- Gateway初体验
  2. 90-0004Web颜色标准【中英文颜色对照】
  3. 链表上手代码---表头插入
  4. 图像文字识别:Python批量识别图片中的文字并自动改名
  5. QQ登录和分享(精简版)
  6. C#之Dispose
  7. 在三角形中rt是什么意思_数学知识点RT三角形是什么意思
  8. android下拉菜单_如何调整和重新排列Android的快速设置下拉菜单
  9. 单摄像机对于二维平面的测量
  10. 常用的免费好用的DNS有哪些?