




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
关于Touch Panel校准算法的研究Haiyong Lei1. 概述由于存在机械误差和ADC误差, touch panel获取的点坐标与屏幕上的点坐标总是存在偏差, 所以touch panel需要通过一定的软件校准.2. 校准算法目前普遍采用的是5点校准, 即取屏幕四角各一个点加上中心一个点, 作为校准的基准参考, 如图1.图1: 校准点的位子五点的坐标定义为:左下: x0y0 (屏幕坐标), X0Y0 (TP坐标)左上: x0y1 (屏幕坐标), X0Y1 (TP坐标)右下: x1y0 (屏幕坐标), X1Y0 (TP坐标)右上: x1y1 (屏幕坐标), X1Y1 (TP坐标)中间: xcyc (屏幕坐标), XcYc (TP坐标)2.1 算法1算法1基于如下公式把TP坐标转换成屏幕坐标:x_screen = Kx * (X_tp - X_offset) / SCF + x_offsety_screen = Ky * (Y_tp - Y_offset) / SCF + y_offset其中Kx,y是X/Y轴比例因子:Kx = (x1 - x0) / (X1 - X0) * SCFKy = (y1 - y0) / (Y1 - Y0) * SCFX_offset用于消除偏离误差:x_offset = xcy_offset = ycX_offset = XcY_offset = YcSCF是SCALE FACTOR这里用于整数计算时保持计算精度。五个基准点包含的冗余信息, 可用于排除人为误差, 假定一个合理误差sigma,则以下公式近式成立:|X0 - X0| sigma, |X1 - X1| sigma|Y0 - Y0| sigma, |Y1 - Y1| sigma|Xc - (X1 + X0 + X1 + X0) / 4| sigma|Yc - (Y1 + Y0 + Y1 + Y0) / 4 | sigma校准完成后,Kx,y和X/Y_offset四个参数予以永久保存。算法1的优点是比较简单,缺点是无法消除TP屏倾斜误差。对于精度要求不高场合是个合适的选择。2.2 算法2算法2是tslib中采用的校准算法, tslib是开源TP算法库, 广泛使用在各种touch panel应用场合,特别是Android平台。tslib包含多种算法, 校准是其中之一, 具体公式如下:x_screen = (A0 * X_tp + A1 * Y_tp + A2) / A6y_screen = (A3 * X_tp + A4 * Y_tp + A5) / A6系数A0到A5经计算得出, A6是SCALE FACTOR.算法2的优点是效果最好,缺点是计算复杂,特别A0到A5的计算需要用到浮点,如果处理器不支持浮点运算的话,需要转换为定点运算。3 实现3.1 算法1/* * Copyright (C) 2015. * * Author: Haiyong Lei * */#ifndef TS_CALIB_H#define TS_CALIB_H/ DEBUG#define TS_DEBUG#ifdef TS_DEBUG#include #define TS_LOG printf#else#define TS_LOG#endif#define N_CALIB_POINTS5 / number points for calibration/ NAME OF POINTS#define LEFT_BOTTOM0#define LEFT_TOP1#define RIGHT_BOTTOM2#define RIGHT_TOP3#define CENTER4/ FLIP FLAGS#define FLIP_X1#define FLIP_Y2/ ERRORS#define E_SUCCESS0#define E_TOO_MANY_POINTS-1#define E_BAD_POINT_X0-2#define E_BAD_POINT_X1-3#define E_BAD_POINT_Y0-4#define E_BAD_POINT_Y1-5#define E_BAD_POINT_XCENTER-6#define E_BAD_POINT_YCENTER-7struct ts_calib_data int scr_xN_CALIB_POINTS;/ screen calibration pointsint scr_yN_CALIB_POINTS;int scr_xres;/ screen resolutionint scr_yres;int scr_xcenter;/ screen centerint scr_ycenter;int tp_xN_CALIB_POINTS;/ touch panel calibration pointsint tp_yN_CALIB_POINTS;int tp_xres;/ touch panel resolutionint tp_yres;int tp_xcenter;/ touch panel centerint tp_ycenter;int tp_xyflip;/ touch panel axis xy flip flagsint Kx;/ axis x ratioint Ky;/ axis y ratioint precision;/ calibration precisionint scaling;/ scaling factor;/* initialize touch panel calibration data: Params: scr_xres: screen x resolution scr_yres: screen i resolution tp_xres: tp x resolution tp_yres: tp y resolution Return:*/void ts_init(struct ts_calib_data *calib, int scr_xres, int scr_yres,int tp_xres, int tp_yres);/* set touch panel xy direction flip flags: Params: tp_xyflip: set the flag to flip Return:*/void ts_set_xyflip(struct ts_calib_data *calib, int tp_xyflip);/* reset touch panel xy direction flip flags: Params: tp_xyflip: set the flag to no flip Return:*/void ts_reset_xyflip(struct ts_calib_data *calib, int tp_xyflip);/* set calibration precision: Params: precision: the minimum in distance of two touch panel readingsthey can be considered the same. The unit is the touchpanel reading unit. Return:*/void ts_set_precision(struct ts_calib_data *calib, int precision);/* set calibration scaling: Params: scaling: the scaling factor, the default is 8192. Return:*/void ts_set_scaling(struct ts_calib_data *calib, int scaling);/* set calibration data: Params: Kx: the ratio of axis x. Ky: the ratio of axis y. tp_xcenter: touch panel center points axis x. tp_ycenter: touch panel center points axis y. Return:*/void ts_set_calib_data(struct ts_calib_data *calib, int Kx, int Ky,int tp_xcenter, int tp_ycenter);/* smooth N of touch panel continous readings: Params: x_in: N x reading of touch panel. y_in: N y reading of touch panel. n: the number of N. x_out: smoothed x reading output. y_out: smoothed y reading output. Return:*/void ts_smooth_xy(int *x_in, int *y_in, int n, int* x_out, int* y_out);/* convert touch panel coordinate to screen using the calibration data: Params: tp_x: x reading of touch panel. tp_y: y reading of touch panel. scr_x: screen x position output. scr_y: screen y position output. Return:*/void ts_linear_map_xy(struct ts_calib_data *calib, int tp_x, int tp_y, int *scr_x, int *scr_y);/* add calibration point Params: n: the Nth point used by calibration, N 5. scr_x: x position in screen coordinate. scr_y: y position in screen coordinate. tp_x: x reading of touch panel. tp_y: y reading of touch panel. Return: E_SUCCESS if succeed.*/int ts_add_calib_point(struct ts_calib_data *calib, int n, int scr_x, int scr_y, int tp_x, int tp_y);/* process calibration: Params: Return: E_SUCCESS if succeed. Note: use ts_add_calib_point to feed 5 points before calibration.*/int ts_calibrate(struct ts_calib_data *calib);#endif/* * Copyright (C) 2015. * * Author: Haiyong Lei * * The touchscreen calibration libray. * */#include #include ts_calib.h#define PRECISION40/ related to touch panel resolution, / example: if touch panel resolution is 4096,/ the precision is 40/4096.#define SCALING8192void ts_init(struct ts_calib_data *calib, int scr_xres, int scr_yres,int tp_xres, int tp_yres)TS_LOG(ts_calib init with resultion: screen: W%dx,H%d, tp: W%dx,H%d,scr_xres, scr_yres, tp_xres, tp_yres);memset(calib, 0, sizeof (struct ts_calib_data);calib-scr_xres = scr_xres;calib-scr_yres = scr_yres;calib-scr_xcenter = scr_xres / 2;calib-scr_ycenter = scr_yres / 2;calib-tp_xres = tp_xres;calib-tp_yres = tp_yres;calib-tp_xcenter = tp_xres / 2;calib-tp_ycenter = tp_yres / 2;calib-Kx = scr_xres * SCALING / tp_xres;calib-Ky = scr_yres * SCALING / tp_yres;calib-precision = PRECISION;calib-scaling = SCALING;void ts_set_xyflip(struct ts_calib_data *calib, int tp_xyflip)TS_LOG(ts_calib set xyflip: %d,tp_xyflip);calib-tp_xyflip |= tp_xyflip;void ts_reset_xyflip(struct ts_calib_data *calib, int tp_xyflip)TS_LOG(ts_calib reset xyflip: %d,tp_xyflip);calib-tp_xyflip &= tp_xyflip;void ts_set_precision(struct ts_calib_data *calib, int precision)TS_LOG(ts_calib set precision: %d,precision);calib-precision = precision;void ts_set_scaling(struct ts_calib_data *calib, int scaling)TS_LOG(ts_calib set scaling: %d,scaling);calib-scaling = scaling;void ts_set_calib_data(struct ts_calib_data *calib, int Kx, int Ky,int tp_xcenter, int tp_ycenter)TS_LOG(ts_calib set Kx/Ky: %d,%d, center: X%d,Y%d,Kx, Ky, tp_xcenter, tp_ycenter);calib-Kx = Kx;calib-Ky = Ky;calib-tp_xcenter = tp_xcenter;calib-tp_ycenter = tp_ycenter;/ smooth N points by averagingvoid ts_smooth_xy(int *x_in, int *y_in, int n, int* x_out, int* y_out)int x_sum = 0;int y_sum = 0;int i;/ average n samplesfor (i = 0; i tp_xyflip & FLIP_X)tp_x = calib-tp_xres - tp_x;if (calib-tp_xyflip & FLIP_Y)tp_y = calib-tp_yres - tp_y;if (*scr_x)int x = (calib-Kx * (tp_x - calib-tp_xcenter) / calib-scaling+ calib-scr_xcenter;/ boundary checkif (x calib-scr_xres)x = calib-scr_xres;*scr_x = x;if (*scr_y)int y = (calib-Ky * (tp_y - calib-tp_ycenter) / calib-scaling+ calib-scr_ycenter;/ boundary checkif (y calib-scr_yres)y = calib-scr_yres;*scr_y = y;int ts_add_calib_point(struct ts_calib_data *calib, int n, int scr_x, int scr_y, int tp_x, int tp_y)if (n = N_CALIB_POINTS)TS_LOG(ts_calib error: %dth point is out of range.,n);return E_TOO_MANY_POINTS;if (calib-tp_xyflip & FLIP_X)tp_x = calib-tp_xres - tp_x;if (calib-tp_xyflip & FLIP_Y)tp_y = calib-tp_yres - tp_y;calib-scr_xn = scr_x;calib-scr_yn = scr_y;calib-tp_xn = tp_x;calib-tp_yn = tp_y;TS_LOG(ts_calib add %dth point: screen: X%d,Y%d, tp: X%d,Y%d,n, scr_x, scr_y, tp_x, tp_y);return E_SUCCESS;/ variance(a0, a1, ., an) =/ 1/n * (a0 - a)2 + (a1 - a)2 + . (an - a)2,/ where, a = (a0 + a1 + . an) / n/static int variance(int p0, int p1)int pt = (p0 + p1) /2;int v = (p0 - pt) * (p0 - pt) +(p1 - pt) * (p1 - pt);return v /2;/* * the calibration procedure requires to collect five points: * * * (x0,y1 )-(x1,y1) * | | * | | * | | * | | * | | * | (x2,y2) | * | | * | | * | | * | | * | | * (x0 ,y0 )-(x1 ,y0) * * To linear convert touch panel coordinate to screen, we * use formula: * * x = Kx * (X - X2) / SCALING + x2 * y = Ky * (Y - Y2) / SCALING + x2 * * The ratio Kx,y can be computed by: * * Kx = (x1 - x0) / (X1 - X0) * SCALING * Ky = (y1 - y0) / (Y1 - Y0) * SCALING * * x, y: screen coordinates, X, Y: touch panel coordinates. * The SCALING factor is to keep calculation precision. * * The equation needs two points to solve, but we have five.The * redundant points can be used to valid points themselves, * points are considered enough good if: * * variance(X0, X0) precision2 * variance(X1, X1) precision2 * variance(Y0, Y0) precision2 * variance(Y1, Y1) precision2 * * and for the center point: * * X2 = (X1 + X0) + (X1 + X0) / 4 * Y2 = (Y1 + Y0) + (Y1 + Y0) / 4 * variance(X2, X2) precision2 * variance(Y2, Y2) precision * calib-precision;x00 = calib-tp_xLEFT_BOTTOM;x01 = calib-tp_xLEFT_TOP;x10 = calib-tp_xRIGHT_BOTTOM;x11 = calib-tp_xRIGHT_TOP;y00 = calib-tp_yLEFT_BOTTOM;y01 = calib-tp_yRIGHT_BOTTOM;y10 = calib-tp_yLEFT_TOP;y11 = calib-tp_yRIGHT_TOP;if (v = variance(x00, x01) square_prec)TS_LOG(ts_calib error: bad point x0: %d,%d, variance: %d%d.,x00, x01, v, square_prec);return E_BAD_POINT_X0;if (v = variance(x10, x11) square_prec)TS_LOG(ts_calib error: bad point x1: %d,%d, variance: %d%d.,x10, x11, v, square_prec);return E_BAD_POINT_X1;if (v = variance(y00, y01) square_prec)TS_LOG(ts_calib error: bad point y0: %d,%d, variance: %d%d.,y00, y01, v, square_prec);return E_BAD_POINT_Y0;if (v = variance(y10, x11) square_prec)TS_LOG(ts_calib error: bad point y1: %d,%d, variance: %d%d.,y10, y11, v, square_prec);return E_BAD_POINT_Y1;x20 = calib-tp_xCENTER;y20 = calib-tp_yCENTER;x21 = (x10 + x11 + x00 + x01) / 4;y21 = (y10 + y11 + y00 + y01) / 4;if (v = variance(x20, x21) square_prec)TS_LOG(ts_calib error: bad point x2: %d,%d, variance: %d%d.,x20, x21, v, square_prec);return E_BAD_POINT_XCENTER;if (v = variance(y20, y21) square_prec)TS_LOG(ts_calib error: bad point y2: %d,%d, variance: %d%d.,y20, y21, v, square_prec);return E_BAD_POINT_YCENTER;scr_xdist = calib-scr_xRIGHT_BOTTOM - calib-scr_xLEFT_BOTTOM;scr_ydist = calib-scr_yLEFT_TOP - calib-scr_yLEFT_BOTTO
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版桥梁梁板运输工程配套设施建设与供应合同
- 纪念白求恩图文课件
- 语音管理知识培训总结课件
- 2025专卖店装修租赁经营合同
- 语言文件基础知识培训课件
- 2025合同履行规定
- 2025年解除汽车租赁合同范例
- 2025科技公司股权转让合同模板
- 营销团队激励计划设计模板
- 企业文化建设方案策划及实施跟踪工具
- 建筑装饰造型设计基础-完整全套教学课件
- 全过程工程咨询服务详细清单
- 法律法规法学 - 马工程《宪法学》重点整理
- 小学四年级道德与法治上册教材分析
- 淋巴瘤基础知识
- GB/T 4956-2003磁性基体上非磁性覆盖层覆盖层厚度测量磁性法
- GB/T 14038-2008气动连接气口和螺柱端
- 胰十二指肠切除术课件
- 风险分级管控责任清单(市政道路工程)
- (临床治疗)继发性甲旁亢课件
- UNIT 1 LESSON 1 LIFESTYLES课件第一课时
评论
0/150
提交评论