触摸屏滤波

第1种尝试 中位值平均滤波法

首先移植的是liujun6037的代码,他的代码思路为:对X、Y的坐标连续采样十次;不足十次则认为数据无效,不做任何操作;然后对十次数据进行排序;最后取中间三次的数据进行平均,得到最终的X、Y坐标。不同的是,我把冒泡排序换成我常用的选择排序,其实还是O(n^2)。其效果如图1所示。可以清楚地看到,本次尝试很失败,有很多莫名其妙的散点。

代码1 第一种尝试

01void ads_GetXY(void)
02{
03  u8 cnt=0;
04  u8 i, j, k, min;
05  u16 temp;
06  u16 tempXY[2][9], XY[2];
07  do
08  {
09    if(ads_ReadXY())
10    {
11      tempXY[0][cnt] = X;
12      tempXY[1][cnt] = Y;
13      cnt++;
14    }
15  }while(cnt<9);
16  if(cnt==9)
17  {
18    for(k=0; k<2; k++)
19    { // 降序排列
20      for(i=0; i<cnt-1; i++)
21      {
22        min=i;
23        for (j=i+1; j<cnt; j++)
24        {
25          if (tempXY[k][min] > tempXY[k][j]) min=j;
26        }
27        temp = tempXY[k][i];
28        tempXY[k][i] = tempXY[k][min];
29        tempXY[k][min] = temp;
30      }
31      // 求中间值的均值
32      XY[k] = (tempXY[k][3]+tempXY[k][4]+tempXY[k][5]+tempXY[k][6]) / 4;
33    }
34  }
35  // 矫正坐标
36  X = ((XY[0]-350)/11);
37  Y = ((XY[1]-400)/14);
38}

图1 第一种尝试 
图1 第一种尝试

 

第2种尝试 差值平均滤波法

由于第一种尝试比较失败,我就在网上搜到了参考2的算法。尝试了一下,效果极差,线条极其发散,图片就不贴了。代码贴到这里作为反面例程。

代码2 第二种尝试

01void ads_GetXY(void)
02{
03  u8 cnt=0;
04  u8 i, j, k, min;
05  u16 temp;
06  u16 tempXY[2][9], avgXY[2][3], XY[2];
07  s16 diffXY[2][3];
08  do
09  {
10    if(ads_ReadXY())
11    {
12      tempXY[0][cnt] = X;
13      tempXY[1][cnt] = Y;
14      cnt++;
15    }
16  }while(cnt<9);
17  if(cnt==9)
18  {
19    for(k=0; k<2; k++)
20    { // 取平均值
21      avgXY[k][0] = (tempXY[k][0]+tempXY[k][1]+tempXY[k][2])/3;
22      avgXY[k][1] = (tempXY[k][3]+tempXY[k][4]+tempXY[k][5])/3;
23      avgXY[k][2] = (tempXY[k][6]+tempXY[k][7]+tempXY[k][8])/3;
24      // 取差值
25      diffXY[k][0] = avgXY[k][0] - avgXY[k][1];
26      diffXY[k][1] = avgXY[k][1] - avgXY[k][2];
27      diffXY[k][2] = avgXY[k][2] - avgXY[k][0];
28      // 取差值的绝对值
29      diffXY[k][0] = (diffXY[k][0] > 0) ? diffXY[k][0] : -diffXY[k][0];
30      diffXY[k][1] = (diffXY[k][1] > 0) ? diffXY[k][1] : -diffXY[k][1];
31      diffXY[k][2] = (diffXY[k][2] > 0) ? diffXY[k][2] : -diffXY[k][2];
32      // 取最小的数得平均值
33      if(diffXY[k][0] < diffXY[k][1])
34      {
35        if(diffXY[k][2] < diffXY[k][1])
36          XY[k] = (avgXY[k][0]+avgXY[k][2])>>1;
37        else
38          XY[k] = (avgXY[k][0]+avgXY[k][1])>>1;
39      }
40      else if(diffXY[k][2] < diffXY[k][1])
41        XY[k] = (avgXY[k][0]+avgXY[k][2])>>1;
42      else
43        XY[k] = (avgXY[k][1]+avgXY[k][2])>>1;
44    }
45  }
46  // 矫正坐标
47  X = ((XY[0]-350)/11);
48  Y = ((XY[1]-400)/14);
49}

 

第3种尝试 中位值平均加阈值滤波法

既然第一种尝试的线条已经比较收敛,那么散点是怎么出来的呢?经过达克斯特兄的一点指导和我的多次实验,终于干掉了这个头疼的散点。原来虽然使用中位值平均滤波法可以稳定获取符合触摸屏范围的数据,但是却无法滤除跳变的散点。对于跳变的散点必须通过加阈值才能消除。下面贴出我的代码。代码思路:采样符合触摸屏范围的数据若干次,将其排序,取中间两位的差值;若差值大于阈值,则丢弃。因为数据已经排序,因此差值肯定是正值或零值,即无需申明为有符号数。同时由于阈值判断的加入,我们可以将数据的采样次数适当调整,此处仅为4次,所得效果已经非常令人满意。需要注意的是采样数据不宜过多,否则连续的线会变成离散的点。

代码3 第3种尝试

01#define SAMP_CNT      4
02#define SAMP_CNT_DIV2 2
03u8 ads_GetXY(void)
04{
05  u8 i, j, k, min;
06  u16 temp;
07  u16 tempXY[2][SAMP_CNT], XY[2];
08  // 采样
09  for(i=0; i<SAMP_CNT; i++)
10  {
11    if(ads_ReadXY())
12    {
13      tempXY[0][i] = X;
14      tempXY[1][i] = Y;
15    }
16  }
17  // 滤波
18  for(k=0; k<2; k++)
19  { // 降序排列
20    for(i=0; i<SAMP_CNT-1; i++)
21    {
22      min=i;
23      for (j=i+1; j<SAMP_CNT; j++)
24      {
25        if (tempXY[k][min] > tempXY[k][j]) min=j;
26      }
27      temp = tempXY[k][i];
28      tempXY[k][i] = tempXY[k][min];
29      tempXY[k][min] = temp;
30    }
31    // 设定阈值
32    if((tempXY[k][SAMP_CNT_DIV2]-tempXY[k][SAMP_CNT_DIV2-1]) > 5)
33      return 0;
34    // 求中间值的均值
35    XY[k] = (tempXY[k][SAMP_CNT_DIV2]+tempXY[k][SAMP_CNT_DIV2-1]) / 2;
36  }
37  // 矫正坐标
38  X = ((XY[0]-350)/11);
39  Y = ((XY[1]-400)/14);
40  return 1;
41}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值