DSP

DSP 实现模式识别小程序

2019-07-13 12:52发布

  花了两个星期的时间,终于把一个简单的模式识别程序移植到开发板上了。程序是现成的,以前用VC实现的。在移植过程中,中间走了一些弯路,花费了不少时间。 程序很简单,用模板匹配法实现数字5和非5的识别,最终显示出来。关于特征值的选取,我一开始把图像分成了5*5个区域,用每个区域的像素值当做特征值。原来VC上,就是这么分的,连阈值我都是直接照搬原程序。实验的时候发现,即使同一个数字,每次从摄像头读取后的像素值差别比较大,毕竟不是读BMP图片。最后改用比值做特征值,分成3*4个区域,区域分的太多反而会受误差影响较大。重新训练选取阈值,最后的结果差强人意,可以大致区分出5和其他数字,但有时也会失败。 程序过程如下: 1.       初始化。从摄像头中读图并二值化存入对应数组。由于摄像头的数据直接放在DDR2中,所以从摄像头读数就是从DDR2对应的地址读数。 2.       把二值化的图像显示出来。就是把二值化的图像数据放到DDR2中。 3.       对图像进行边界扫描。这是为了下一步标准化做准备。上边界确定方法如下:        //从上往下扫描,找到上边界     tmp=(Uint8 *)sample;        for (i=10;i            //边界有黑线,i不从0开始        {           count=0;          //              for (j=0;j               {             // 指向图像第i行,第j个象素的指针                      tmp = (Uint8 *)sample + lLineBytes * i + j;                        //获得该点的灰度值                      //gray = *(lpSrc);                        //看是否为黑点                      if (*tmp == 0)                      {                             count++;                //若黑点数>10,把此行作为字符大致的最高点              }           //如果该点不是黑点,继续循环               }                 if(count>10)                           {                               top=i;                                                                      break;                              }          } 很简单,就是从上往下一行一行统计黑像素个数,当首先超过阈值时(我取10),记录位置,作为上边界。其他边界以此类推。 4.       标准化。把读到的图像尺寸标准化。代码如下: height=rect.bottom-rect.top;        width=rect.right-rect.left;       lLineBytes=150;        //分配空间存标准化后的图像        dest=malloc(150*200);        memset(dest,0xff,150*200);                 //计算缩放因子        //横坐标方向的缩放因子        wscale=(double)tarWidth/width;        //纵坐标方向的缩放因子        hscale=(double)tarHeight/height;                 for(i=0 ;i<200 ;i++)            {                  for(j=0 ;j<150 ;j++)                      {                         //计算映射坐标                             i_src=top +(Uint32)(i /hscale);                             j_src=left +(Uint32)(j /wscale);                             //将相对应的象素点进行映射操作                             src=sample + lLineBytes *  i_src + j_src;                             dest = transample + 150 * i + j;                             *dest=*src;                                           }               } 就是把原来图像的像素映射到标准大小的框框中。我这里标准化大小为:150*200 5.       计算标准化后图像的黑 {MOD}像素总个数。 6.       计算3*4个区域中每个区域的黑 {MOD}像素个数,算出特征值。 7.       与模板比较,显示结果。 我的模板是事先存好的,保存了3*4个特征值,比较的时候从文件中读取即可。这样不用每次都从摄像头中读模板。   遇到问题: 1.  我没有用DSP/BIOS所以开始的时候在CMD文件中遇到了麻烦,编译总是过不去,提示我文件太大,放不到L2 Cache中,L2 Cache128K大小,我这么小的程序居然会超,我怎么也想不明白。.我发现cinit .far. text占用空间较大。.cinit则用来存放全局变量的初始值   .far 好像也是存放初始值的。.text是代码大小。最后没办法,全都放到了DDR中。这才能够编译通过。 2.  开始我从屏幕上取的窗口大小为200*240的,就是摄像头存放在DDR中数据大小,后来发现读的图像不正确,改为320*240后,问题解决,应该是VPFE的设置有问题。