首页 > 作文

屏幕校正

更新时间:2023-03-10 18:48:18 阅读: 评论:0

真心话大冒险惩罚-姜维三国杀

屏幕校正
2023年3月10日发(作者:狗的习性)

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

最近搞个触摸屏校准,参考了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)-1AT,那么公式变为

为啥要这么变?别和我说什么最⼩⼆乘解左逆右逆什么最优解之类的,我就是想要搞个⽅阵,A的转置AT和A相乘就变成⽅阵,令A=

ATA,b=,这样x=A-1∙b⼜来了!接下来只要求出ATA和就可以⽤克拉默法则了。

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

那么可以放⼼求解:

重点来了,以上公式统统不⽤纠结,带⼊上⾯公式可以发现⼀个规律:

ts_calibration_common.c

intperform_calibration(calibration*cal)

{

intj;

floatn,x,y,x2,y2,xy,z,zx,zy;

floatdet,a,b,c,e,f,i;

floatscaling=65536.0;

/*Getsumsformatrix*/

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]);

}

/*Getdeterminantofmatrix--checkifdeterminantistoosmall*/

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:determinantistoosmall--%fn",det);

return0;

}

/*Getelementsofinvermatrix*/

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;

/*Getsumsforxcalibration*/

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]);

}

/*Nowmultiplyouttogetthecalibrationforframebufferxcoord*/

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%fn",(a*z+b*zx+c*zy),

(b*z+e*zx+f*zy),

(c*z+f*zx+i*zy));

(c*z+f*zx+i*zy));

/*Getsumsforycalibration*/

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]);

}

/*Nowmultiplyouttogetthecalibrationforframebufferycoord*/

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%fn",(a*z+b*zx+c*zy),

(b*z+e*zx+f*zy),

(c*z+f*zx+i*zy));

/*Ifwegothere,we'reOK,soassignscalingtoa[6]andreturn*/

cal->a[6]=(int)scaling;

return1;

}

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

完结撒花。

本文发布于:2023-03-10 18:48:17,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/1678445298206742.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:屏幕校正.doc

本文 PDF 下载地址:屏幕校正.pdf

上一篇:咖啡能染发吗
下一篇:返回列表
标签:屏幕校正
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图