搜索
bottom↓
回复: 43

基于MMSE的触摸屏应用多点校准算法

[复制链接]

出0入0汤圆

发表于 2012-3-26 22:58:53 | 显示全部楼层 |阅读模式
本帖最后由 jeffwei 于 2012-3-26 23:06 编辑

前两天看到ADI的应用笔记AN1021《基于MMSE的触摸屏应用多点校准算法》很不错,传个中文版上来。希望对大家有帮助。












本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-3-27 20:55:33 | 显示全部楼层
正好用上,谢谢楼主哈,

出0入0汤圆

发表于 2012-3-31 12:54:24 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-3-31 13:10:27 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-4-7 00:08:48 | 显示全部楼层
效果很好,rt-thread加9寸屏,校准算法给力

出0入0汤圆

发表于 2012-4-7 09:09:23 | 显示全部楼层
恩  不错!!!谢谢LZ哈!

出0入0汤圆

发表于 2012-4-26 19:48:34 | 显示全部楼层
不错啊,学习了

出0入0汤圆

发表于 2012-5-21 15:14:48 | 显示全部楼层
为什么我下载下来不是pdf

出0入0汤圆

 楼主| 发表于 2012-5-21 17:19:42 | 显示全部楼层
enmimi 发表于 2012-5-21 15:14
为什么我下载下来不是pdf

下载的文件大小是284.35 KB的话就把后缀名改为PDF

出0入0汤圆

发表于 2012-12-26 17:39:21 | 显示全部楼层
经典,学习中,甚是有用。谢谢LZ

出0入0汤圆

发表于 2012-12-26 17:39:36 | 显示全部楼层
经典,学习中,甚是有用。谢谢LZ

出0入0汤圆

发表于 2013-4-2 09:07:25 | 显示全部楼层
谢谢楼主呀,  好东西。。。。。。。。。。。

出0入0汤圆

发表于 2013-4-2 12:46:27 | 显示全部楼层
本帖最后由 baihesfj 于 2013-4-2 13:29 编辑
jeffwei 发表于 2012-5-21 17:19
下载的文件大小是284.35 KB的话就把后缀名改为PDF


void Do_Calibration(signed short int *Px, signed short int *Py) // do calibration for point(Px, Py)
{                                                               // using the calculated coefficients
       
        *Px=(signed short int)(KX1*(*Px)+KX2*(*Py)+KX3+0.5);
        *Py=(signed short int)(KY1*(*Px)+KY2*(*Py)+KY3+0.5);
}


楼主这个函数 是 有触摸屏的物理坐标 转化得到 LCD的显示坐标吗?应该怎么调用你

出0入0汤圆

发表于 2013-4-2 13:45:17 | 显示全部楼层
tanghong668 发表于 2012-4-7 00:08
效果很好,rt-thread加9寸屏,校准算法给力

兄弟 ,这个算法你是怎么调用的,能分享下吗?

出0入0汤圆

发表于 2013-4-2 22:49:16 | 显示全部楼层
touch->x = (rt_uint16_t)(touch->KXn1 * touch->x + touch->KXn2 * touch->y + touch->KXn3 + 0.5);
touch->y = (rt_uint16_t)(touch->KYn1 * touch->x + touch->KYn2 * touch->y + touch->KYn3 + 0.5);
按照RTT标准来就行了

出0入0汤圆

发表于 2013-4-8 14:01:26 | 显示全部楼层
                                                    int i;
                                                        int Points=N;
                                                        float a[3],b[3],c[3],d[3],k;
                                                        if(Points<3)
                                                        {
                                                                return ;
                                                        }
                                                        else
                                                        {
                                                                if(Points==3)
                                                                {
                                                                        for(i=0; i<Points; i++)
                                                                        {
                                                                                a[i]=(float)(screenPtr[i][0]);
                                                                                b[i]=(float)(screenPtr[i][1]);
                                                                                c[i]=(float)(displayPtr[i][0]);
                                                                                d[i]=(float)(displayPtr[i][1]);
                                                                        }
                                                                }
                                                                else if(Points>3)
                                                                {
                                                                        for(i=0; i<3; i++)
                                                                        {
                                                                                a[i]=0;
                                                                                b[i]=0;
                                                                                c[i]=0;
                                                                                d[i]=0;
                                                                        }
                                                                        for(i=0; i<Points; i++)
                                                                        {
                                                                                a[2]=a[2]+(float)(screenPtr[i][0]);
                                                                                b[2]=b[2]+(float)(screenPtr[i][1]);
                                                                                c[2]=c[2]+(float)(displayPtr[i][0]);
                                                                                d[2]=d[2]+(float)(displayPtr[i][1]);
                                                                                a[0]=a[0]+(float)(screenPtr[i][0])*(float)(screenPtr[i][0]);
                                                                                a[1]=a[1]+(float)(screenPtr[i][0])*(float)(screenPtr[i][1]);
                                                                                b[0]=a[1];
                                                                                b[1]=b[1]+(float)(screenPtr[i][1])*(float)(screenPtr[i][1]);
                                                                                c[0]=c[0]+(float)(screenPtr[i][0])*(float)(displayPtr[i][0]);
                                                                                c[1]=c[1]+(float)(screenPtr[i][1])*(float)(displayPtr[i][0]);
                                                                                d[0]=d[0]+(float)(screenPtr[i][0])*(float)(displayPtr[i][1]);
                                                                                d[1]=d[1]+(float)(screenPtr[i][1])*(float)(displayPtr[i][1]);
                                                                        }
                                                                        a[0]=a[0]/a[2];
                                                                        a[1]=a[1]/b[2];
                                                                        b[0]=b[0]/a[2];
                                                                        b[1]=b[1]/b[2];
                                                                        c[0]=c[0]/a[2];
                                                                        c[1]=c[1]/b[2];
                                                                        d[0]=d[0]/a[2];
                                                                        d[1]=d[1]/b[2];
                                                                        a[2]=a[2]/Points;
                                                                        b[2]=b[2]/Points;
                                                                        c[2]=c[2]/Points;
                                                                        d[2]=d[2]/Points;
                                                                }
                                                                k=(a[0]-a[2])*(b[1]-b[2])-(a[1]-a[2])*(b[0]-b[2]);
                                                                TPA=((c[0]-c[2])*(b[1]-b[2])-(c[1]-c[2])*(b[0]-b[2]))/k;
                                                                TPB=((c[1]-c[2])*(a[0]-a[2])-(c[0]-c[2])*(a[1]-a[2]))/k;
                                                                TPC=(b[0]*(a[2]*c[1]-a[1]*c[2])+b[1]*(a[0]*c[2]-a[2]*c[0])+b[2]*(a[1]*c[0]-a[0]*c[1]))/k;
                                                               
                                                                TPD=((d[0]-d[2])*(b[1]-b[2])-(d[1]-d[2])*(b[0]-b[2]))/k;
                                                                TPE=((d[1]-d[2])*(a[0]-a[2])-(d[0]-d[2])*(a[1]-a[2]))/k;
                                                                TPF=(b[0]*(a[2]*d[1]-a[1]*d[2])+b[1]*(a[0]*d[2]-a[2]*d[0])+b[2]*(a[1]*d[0]-a[0]*d[1]))/k;
                                                               
                                                                TPDivider = (int)scaling;
                                                                //return Points;

出0入0汤圆

发表于 2013-4-8 14:04:07 | 显示全部楼层
调用的时候 是这样的  
i=(float)((TPA*tpx)+(TPB*tpy)+TPC+0.5);
j=(float)((TPD*tpx)+(TPE*tpy)+TPF+0.5);

i,j 分别为转换后的 X ,Y的逻辑坐标,就是要显示 的坐标,   可怎么不正确呢?

出0入0汤圆

发表于 2013-4-8 14:04:59 | 显示全部楼层
tanghong668 发表于 2013-4-2 22:49
touch->x = (rt_uint16_t)(touch->KXn1 * touch->x + touch->KXn2 * touch->y + touch->KXn3 + 0.5);
touch ...

看看是这样调用的吗?

出0入0汤圆

发表于 2013-4-8 14:39:43 | 显示全部楼层
tanghong668 发表于 2013-4-2 22:49
touch->x = (rt_uint16_t)(touch->KXn1 * touch->x + touch->KXn2 * touch->y + touch->KXn3 + 0.5);
touch ...

touch->x = (rt_uint16_t)(touch->KXn1 * touch->x + touch->KXn2 * touch->y + touch->KXn3 + 0.5);
touch->y = (rt_uint16_t)(touch->KYn1 * touch->x + touch->KYn2 * touch->y + touch->KYn3 + 0.5);
你好, 这里面的  touch->x  和  "=" 号右面的  touch->x 是同一个变量吗?  是物理坐标还是逻辑坐标?,如果是物理坐标,  下一步怎么得到逻辑坐标呢?  如果是逻辑坐标,那 物理坐标怎么求出的呢?

出0入0汤圆

发表于 2013-4-8 14:45:44 | 显示全部楼层
上面的是校准的算法,你需要自己弄几个采样点,我的9寸屏弄了9个采样点,
如下:
//LCD的9个采样点
rt_uint16_t ReferencePoint[Number][2] = {
  { CALIBRATION_WIDTH  , CALIBRATION_HEIGHT  },
  { 400 , CALIBRATION_HEIGHT },
  { 800-CALIBRATION_WIDTH  , CALIBRATION_HEIGHT },

  { CALIBRATION_WIDTH , 240 },
  { 400  , 240 },
  { 800-CALIBRATION_WIDTH , 240 },

  { CALIBRATION_WIDTH , 480-CALIBRATION_HEIGHT },
  { 400  , 480-CALIBRATION_HEIGHT },
  { 800-CALIBRATION_WIDTH , 480-CALIBRATION_HEIGHT },
};

出0入0汤圆

发表于 2013-4-8 15:53:46 | 显示全部楼层
const int displayPtr[5][2] =
{
        {50,50},
        {750,50},
        {50,550},
        {750,550},
        {400,300},
        //{80,60},
        //{720,60},
        //{80,540},
        //{720,540},
        //{400,300},       
};
这是我的LCD的五个采样点,    是对应的放在ReferencePoint[N][2]里面吧, 你的 那几个LCD采样点 那样写没看懂呢,  我的QQ:729731698  ,能加我QQ聊吗?  

出0入0汤圆

发表于 2013-4-8 16:45:58 | 显示全部楼层
好资料,mark

出0入0汤圆

发表于 2013-5-30 16:04:42 | 显示全部楼层
顶起

出0入0汤圆

发表于 2013-6-21 15:14:17 | 显示全部楼层
谢谢啊.....

出0入0汤圆

发表于 2013-6-21 16:07:49 | 显示全部楼层
本帖最后由 cnxh 于 2013-6-21 16:15 编辑

Iar,MEGA16,环境,手动设置ReferencePoint 初始化成校准点位置,手动设置SamplePoint初始化成采样点位置,就是校准点和采样点重合,怎么软件模拟不对,软件模拟时采样的x,y为零,计算结果,x=0,y=-1,不是都为0,怎么回事,有测试了下,随意改变,x,y的值返回的x全部为0,y全部为-1
void Do_Calibration(signed short int *Px, signed short int *Py);
int Get_Calibration_Coefficient();
int main( void )
{
   signed short int x = 0,y = 0;
    Get_Calibration_Coefficient();
   while(1)
   {
       Do_Calibration(&x,&y);
   }
}
#define N 9                                 //校准的参考点的数目
#define CALIBRATION_WIDTH 800
#define CALIBRATION_HEIGHT 400
signed short int ReferencePoint[N][2]=
{
    { CALIBRATION_WIDTH  , CALIBRATION_HEIGHT  },
    { 400 , CALIBRATION_HEIGHT },
    { 800-CALIBRATION_WIDTH  , CALIBRATION_HEIGHT },

    { CALIBRATION_WIDTH , 240 },
    { 400  , 240 },
    { 800-CALIBRATION_WIDTH , 240 },

    { CALIBRATION_WIDTH , 480-CALIBRATION_HEIGHT },
    { 400  , 480-CALIBRATION_HEIGHT },
    { 800-CALIBRATION_WIDTH , 480-CALIBRATION_HEIGHT },
     
};      //理想位置的参考点
signed short int SamplePoint[N][2] =
{
    { CALIBRATION_WIDTH  , CALIBRATION_HEIGHT  },
    { 400 , CALIBRATION_HEIGHT },
    { 800-CALIBRATION_WIDTH  , CALIBRATION_HEIGHT },

    { CALIBRATION_WIDTH , 240 },
    { 400  , 240 },
    { 800-CALIBRATION_WIDTH , 240 },

    { CALIBRATION_WIDTH , 480-CALIBRATION_HEIGHT },
    { 400  , 480-CALIBRATION_HEIGHT },
    { 800-CALIBRATION_WIDTH , 480-CALIBRATION_HEIGHT },
     
};         //采样位置的参考点
double KX1, KX2, KX3, KY1, KY2, KY3;        //系数的校准算法
void Do_Calibration(signed short int *Px, signed short int *Py) // 做校准点 (Px,Py) 使用的计算的系数
{
    *Px=(signed short int)(KX1*(*Px)+KX2*(*Py)+KX3+0.5);
    *Py=(signed short int)(KY1*(*Px)+KY2*(*Py)+KY3+0.5);
}
int Get_Calibration_Coefficient() //计算的系数,校准算法: KX1、 KX2、 KX3、 KY1、 KY2、 KY3
{
    int i;
    int Points=N;
    double a[3],b[3],c[3],d[3],k;
    if(Points<3)
    {
        return 0;
    }
    else
    {
        if(Points==3)
        {
            for(i=0; i<Points; i++)
            {
                a=(double)(SamplePoint[0]);
                b=(double)(SamplePoint[1]);
                c=(double)(ReferencePoint[0]);
                d=(double)(ReferencePoint[1]);
            }
        }
        else if(Points>3)
        {
            for(i=0; i<3; i++)
            {
                a=0;
                b=0;
                c=0;
                d=0;
            }
            for(i=0; i<Points; i++)
            {
                a[2]=a[2]+(double)(SamplePoint[0]);
                b[2]=b[2]+(double)(SamplePoint[1]);
                c[2]=c[2]+(double)(ReferencePoint[0]);
                d[2]=d[2]+(double)(ReferencePoint[1]);
                a[0]=a[0]+(double)(SamplePoint[0])*(double)(SamplePoint[0]);
                a[1]=a[1]+(double)(SamplePoint[0])*(double)(SamplePoint[1]);
                b[0]=a[1];
                b[1]=b[1]+(double)(SamplePoint[1])*(double)(SamplePoint[1]);
                c[0]=c[0]+(double)(SamplePoint[0])*(double)(ReferencePoint[0]);
                c[1]=c[1]+(double)(SamplePoint[1])*(double)(ReferencePoint[0]);
                d[0]=d[0]+(double)(SamplePoint[0])*(double)(ReferencePoint[1]);
                d[1]=d[1]+(double)(SamplePoint[1])*(double)(ReferencePoint[1]);
            }
            a[0]=a[0]/a[2];
            a[1]=a[1]/b[2];
            b[0]=b[0]/a[2];
            b[1]=b[1]/b[2];
            c[0]=c[0]/a[2];
            c[1]=c[1]/b[2];
            d[0]=d[0]/a[2];
            d[1]=d[1]/b[2];
            a[2]=a[2]/Points;
            b[2]=b[2]/Points;
            c[2]=c[2]/Points;
            d[2]=d[2]/Points;
        }
        k=(a[0]-a[2])*(b[1]-b[2])-(a[1]-a[2])*(b[0]-b[2]);
        KX1=((c[0]-c[2])*(b[1]-b[2])-(c[1]-c[2])*(b[0]-b[2]))/k;
        KX2=((c[1]-c[2])*(a[0]-a[2])-(c[0]-c[2])*(a[1]-a[2]))/k;
        KX3=(b[0]*(a[2]*c[1]-a[1]*c[2])+b[1]*(a[0]*c[2]-a[2]*c[0])+b[2]*(a[1]*c[0]-a[0]*c[1]))/k;
        KY1=((d[0]-d[2])*(b[1]-b[2])-(d[1]-d[2])*(b[0]-b[2]))/k;
        KY2=((d[1]-d[2])*(a[0]-a[2])-(d[0]-d[2])*(a[1]-a[2]))/k;
        KY3=(b[0]*(a[2]*d[1]-a[1]*d[2])+b[1]*(a[0]*d[2]-a[2]*d[0])+b[2]*(a[1]*d[0]-a[0]*d[1]))/k;
        return Points;
    }
}

出0入0汤圆

发表于 2013-6-21 17:17:18 | 显示全部楼层
老兄,你测试过吗

出0入0汤圆

 楼主| 发表于 2013-6-22 09:38:46 | 显示全部楼层
cnxh 发表于 2013-6-21 17:17
老兄,你测试过吗

当然是用过的,我用在7寸屏上的,前面也有网友用在9寸上的
你自己拿个屏幕试一试就知道了

出0入0汤圆

发表于 2013-6-22 10:20:39 | 显示全部楼层
表示 这个算法很不错的,我的9寸屏上使用效果很好

出0入0汤圆

发表于 2013-6-22 17:11:29 | 显示全部楼层
jeffwei 发表于 2013-6-22 09:38
当然是用过的,我用在7寸屏上的,前面也有网友用在9寸上的
你自己拿个屏幕试一试就知道了
...

没有硬件,是软件仿的,能发一个,你改过的吗

出0入0汤圆

发表于 2013-6-22 17:12:08 | 显示全部楼层
tanghong668 发表于 2013-6-22 10:20
表示 这个算法很不错的,我的9寸屏上使用效果很好

你好,能发一个你的吗

出0入0汤圆

 楼主| 发表于 2013-6-23 21:12:23 | 显示全部楼层
没有改过,直接用的
我的屏幕直接校准了固化参数
没有校准选项的

出0入0汤圆

发表于 2013-8-9 01:13:41 来自手机 | 显示全部楼层
学习学习,Mark

出0入0汤圆

发表于 2013-10-14 19:16:25 | 显示全部楼层
好用,不错

出0入0汤圆

发表于 2014-4-1 11:53:15 | 显示全部楼层
tanghong668 发表于 2013-6-22 10:20
表示 这个算法很不错的,我的9寸屏上使用效果很好

你好,你的9寸屏效果都很好吗,没有飞点的吗,我是8寸屏,但是在边缘处偶尔会有飞点?能请教一下吗?

出0入0汤圆

发表于 2014-4-1 11:54:30 | 显示全部楼层
jeffwei 发表于 2013-6-23 21:12
没有改过,直接用的
我的屏幕直接校准了固化参数
没有校准选项的

请问你每次校准参数都相同吗,我校准的时候会有偏差,能请教一下吗?

出0入0汤圆

发表于 2014-4-1 11:55:53 | 显示全部楼层
tanghong668 发表于 2013-6-22 10:20
表示 这个算法很不错的,我的9寸屏上使用效果很好

对校准点的选择有什么要求吗?

出0入0汤圆

 楼主| 发表于 2014-4-1 14:38:09 | 显示全部楼层
wll_2012 发表于 2014-4-1 11:54
请问你每次校准参数都相同吗,我校准的时候会有偏差,能请教一下吗?

屏幕大了抖动大,不可能每次都是一样的,但是基本差不多。如果差太多,建议换一家的触摸屏,我遇到过一家的超级抖动,不能用.

出0入0汤圆

发表于 2014-4-1 14:43:32 | 显示全部楼层
jeffwei 发表于 2014-4-1 14:38
屏幕大了抖动大,不可能每次都是一样的,但是基本差不多。如果差太多,建议换一家的触摸屏,我遇到过一家 ...

但是现在的电子产品不是也有大屏幕的吗,感觉还是可以的,我的才是8寸屏,在边缘处偶尔会有抖动,作为一个产品的话觉得这样应该不太好吧,你有什么好的解决办法吗?

出0入0汤圆

 楼主| 发表于 2014-4-1 16:55:29 | 显示全部楼层
wll_2012 发表于 2014-4-1 14:43
但是现在的电子产品不是也有大屏幕的吗,感觉还是可以的,我的才是8寸屏,在边缘处偶尔会有抖动,作为一 ...

增加校准点数试试吧

出0入0汤圆

发表于 2014-5-17 13:38:26 | 显示全部楼层
,我的这个10.2寸触摸屏刚开始读到的值就是这样的,请问触摸屏质量有问题吗?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-5-17 15:22:29 | 显示全部楼层
关键是看屏幕的数据稳定不

出0入0汤圆

发表于 2014-5-20 09:25:56 | 显示全部楼层
jeffwei 发表于 2014-5-17 15:22
关键是看屏幕的数据稳定不

你用的是哪家的触摸屏?

出0入0汤圆

 楼主| 发表于 2014-5-21 22:18:22 | 显示全部楼层
wll_2012 发表于 2014-5-20 09:25
你用的是哪家的触摸屏?

那时候在淘宝买的,就几片,后来换了地方工作,界面直接上HMI

出0入0汤圆

发表于 2014-6-6 11:00:58 | 显示全部楼层
baihesfj 发表于 2013-4-8 14:01
int i;
                                                        int Points=N;
                                                        float a[3],b[3],c[3],d[3],k;

你代码 错了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-18 22:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表