找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3576|回复: 3
打印 上一主题 下一主题
收起左侧

单片机EasyTrace32摄像头颜色跟踪识别,移植这个可以完成

[复制链接]
跳转到指定楼层
楼主
ID:136928 发表于 2018-8-24 15:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
更正一处bug:easytrace.c文件中第81行修改为s = (difVal)*240/(511 - (maxVal+minVal));

单片机源程序如下:
  1. #include "EasyTracer.h"

  2. #define min3v(v1, v2, v3)   ((v1)>(v2)? ((v2)>(v3)?(v3):(v2)):((v1)>(v3)?(v3):(v1)))
  3. #define max3v(v1, v2, v3)   ((v1)<(v2)? ((v2)<(v3)?(v3):(v2)):((v1)<(v3)?(v3):(v1)))

  4. typedef struct{
  5.     unsigned char  red;             // [0,255]
  6.     unsigned char  green;           // [0,255]
  7.     unsigned char  blue;            // [0,255]
  8. }COLOR_RGB;//RGB格式颜色

  9. typedef struct{
  10.     unsigned char hue;              // [0,240]
  11.     unsigned char saturation;       // [0,240]
  12.     unsigned char luminance;        // [0,240]
  13. }COLOR_HSL;//HSL格式颜色

  14. typedef struct{
  15.     unsigned int X_Start;              
  16.     unsigned int X_End;
  17.         unsigned int Y_Start;              
  18.     unsigned int Y_End;
  19. }SEARCH_AREA;//区域

  20. //读取RBG格式颜色,唯一需要移植的函数
  21. extern unsigned short GUI_ReadBit16Point(unsigned short x,unsigned short y);
  22. static void ReadColor(unsigned int x,unsigned int y,COLOR_RGB *Rgb)
  23. {
  24.         unsigned short C16;

  25.         C16 = GUI_ReadBit16Point(x,y);

  26.         Rgb->red   =         (unsigned char)((C16&0xf800)>>8);
  27.         Rgb->green =         (unsigned char)((C16&0x07e0)>>3);
  28.         Rgb->blue  =     (unsigned char)((C16&0x001f)<<3);
  29. }



  30. //RGB转HSL
  31. static void RGBtoHSL(const COLOR_RGB *Rgb, COLOR_HSL *Hsl)
  32. {
  33.     int h,s,l,maxVal,minVal,difVal;
  34.         int r  = Rgb->red;
  35.         int g  = Rgb->green;
  36.     int b  = Rgb->blue;
  37.         
  38.         maxVal = max3v(r, g, b);
  39.         minVal = min3v(r, g, b);
  40.         
  41.         difVal = maxVal-minVal;
  42.         
  43.         //计算亮度
  44.     l = (maxVal+minVal)*240/255/2;
  45.         
  46.         if(maxVal == minVal)//若r=g=b
  47.         {
  48.                 h = 0;
  49.                 s = 0;
  50.         }
  51.         else
  52.         {
  53.                 //计算色调
  54.                 if(maxVal==r)
  55.                 {
  56.                         if(g>=b)
  57.                                 h = 40*(g-b)/(difVal);
  58.                         else
  59.                                 h = 40*(g-b)/(difVal) + 240;
  60.                 }
  61.                 else if(maxVal==g)
  62.                         h = 40*(b-r)/(difVal) + 80;
  63.                 else if(maxVal==b)
  64.                         h = 40*(r-g)/(difVal) + 160;
  65.                 //计算饱和度
  66.                 if(l == 0)
  67.                         s = 0;
  68.                 else if(l<=120)
  69.                         s = (difVal)*240/(maxVal+minVal);
  70.                 else
  71.                         s = (difVal)*240/(480 - (maxVal+minVal));
  72.         }
  73.     Hsl->hue =        (unsigned char)(((h>240)? 240 : ((h<0)?0:h)));
  74.     Hsl->saturation = (unsigned char)(((s>240)? 240 : ((s<0)?0:s)));
  75.     Hsl->luminance =  (unsigned char)(((l>240)? 240 : ((l<0)?0:l)));
  76. }

  77. //匹配颜色
  78. static int ColorMatch(const COLOR_HSL *Hsl,const TARGET_CONDI *Condition)
  79. {
  80.         if(
  81.                 Hsl->hue                >        Condition->H_MIN &&
  82.                 Hsl->hue                <        Condition->H_MAX &&
  83.                 Hsl->saturation        >        Condition->S_MIN &&
  84.                 Hsl->saturation        <   Condition->S_MAX &&
  85.                 Hsl->luminance        >        Condition->L_MIN &&
  86.                 Hsl->luminance        <   Condition->L_MAX
  87.     )
  88.                 return 1;
  89.         else
  90.                 return 0;
  91. }

  92. //搜索腐蚀中心
  93. static int SearchCentre(unsigned int *x,unsigned int *y,const TARGET_CONDI *Condition,const SEARCH_AREA *Area)
  94. {
  95.         unsigned int SpaceX,SpaceY,i,j,k,FailCount=0;
  96.         COLOR_RGB Rgb;
  97.         COLOR_HSL Hsl;
  98.         
  99.         SpaceX = Condition->WIDTH_MIN/3;
  100.         SpaceY = Condition->HIGHT_MIN/3;

  101.         for(i=Area->Y_Start;i<Area->Y_End;i+=SpaceY)
  102.         {
  103.                 for(j=Area->X_Start;j<Area->X_End;j+=SpaceX)
  104.                 {
  105.                         FailCount=0;
  106.                         for(k=0;k<SpaceX+SpaceY;k++)
  107.                         {
  108.                                 if(k<SpaceX)
  109.                                         ReadColor(j+k,i+SpaceY/2,&Rgb);
  110.                                 else
  111.                                         ReadColor(j+SpaceX/2,i+(k-SpaceX),&Rgb);
  112.                                 RGBtoHSL(&Rgb,&Hsl);
  113.                                 
  114.                                 if(!ColorMatch(&Hsl,Condition))
  115.                                         FailCount++;
  116.                                 if(FailCount>((SpaceX+SpaceY)>>ALLOW_FAIL_PER))
  117.                                         break;
  118.                         }
  119.                         if(k==SpaceX+SpaceY)
  120.                         {
  121.                                 *x = j+SpaceX/2;
  122.                                 *y = i+SpaceY/2;
  123.                                 return 1;
  124.                         }
  125.                 }
  126.         }
  127.         return 0;
  128. }

  129. //从腐蚀中心向外腐蚀,得到新的腐蚀中心
  130. static int Corrode(unsigned int oldx,unsigned int oldy,const TARGET_CONDI *Condition,RESULT *Resu)
  131. {
  132.         unsigned int Xmin,Xmax,Ymin,Ymax,i,FailCount=0;
  133.         COLOR_RGB Rgb;
  134.         COLOR_HSL Hsl;
  135.         
  136.         for(i=oldx;i>IMG_X;i--)
  137.         {
  138.                 ReadColor(i,oldy,&Rgb);
  139.                 RGBtoHSL(&Rgb,&Hsl);
  140.                 if(!ColorMatch(&Hsl,Condition))
  141.                         FailCount++;
  142.                 if(FailCount>(((Condition->WIDTH_MIN+Condition->WIDTH_MAX)>>2)>>ALLOW_FAIL_PER))
  143.                         break;        
  144.         }
  145.         Xmin=i;
  146.         FailCount=0;
  147.         
  148.         for(i=oldx;i<IMG_X+IMG_W;i++)
  149.         {
  150.                 ReadColor(i,oldy,&Rgb);
  151.                 RGBtoHSL(&Rgb,&Hsl);
  152.                 if(!ColorMatch(&Hsl,Condition))
  153.                         FailCount++;
  154.                 if(FailCount>(((Condition->WIDTH_MIN+Condition->WIDTH_MAX)>>2)>>ALLOW_FAIL_PER))
  155.                         break;        
  156.         }
  157.         Xmax=i;
  158.         FailCount=0;
  159.         
  160.         for(i=oldy;i>IMG_Y;i--)
  161.         {
  162.                 ReadColor(oldx,i,&Rgb);
  163.                 RGBtoHSL(&Rgb,&Hsl);
  164.                 if(!ColorMatch(&Hsl,Condition))
  165.                         FailCount++;
  166.                 if(FailCount>(((Condition->HIGHT_MIN+Condition->HIGHT_MAX)>>2)>>ALLOW_FAIL_PER))
  167.                         break;        
  168.         }
  169.         Ymin=i;
  170.         FailCount=0;
  171.         
  172.         for(i=oldy;i<IMG_Y+IMG_H;i++)
  173.         {
  174.                 ReadColor(oldx,i,&Rgb);
  175.                 RGBtoHSL(&Rgb,&Hsl);
  176.                 if(!ColorMatch(&Hsl,Condition))
  177.                         FailCount++;
  178.                 if(FailCount>(((Condition->HIGHT_MIN+Condition->HIGHT_MAX)>>2)>>ALLOW_FAIL_PER))
  179.                         break;        
  180.         }
  181.         Ymax=i;
  182.         FailCount=0;
  183.         
  184.         Resu->x        = (Xmin+Xmax)/2;
  185.         Resu->y        = (Ymin+Ymax)/2;
  186.         Resu->w        = Xmax-Xmin;
  187.         Resu->h        = Ymax-Ymin;

  188.         if(((Xmax-Xmin)>(Condition->WIDTH_MIN)) && ((Ymax-Ymin)>(Condition->HIGHT_MIN)) &&\
  189.            ((Xmax-Xmin)<(Condition->WIDTH_MAX)) && ((Ymax-Ymin)<(Condition->HIGHT_MAX)) )
  190.                 return 1;        
  191.         else
  192.                 return 0;        
  193. }

  194. //唯一的API,用户将识别条件写入Condition指向的结构体中,该函数将返回目标的x,y坐标和长宽
  195. //返回1识别成功,返回1识别失败
  196. int Trace(const TARGET_CONDI *Condition,RESULT *Resu)
  197. {
  198.         unsigned int i;
  199.         static unsigned int x0,y0,flag=0;
  200.         static SEARCH_AREA Area={IMG_X,IMG_X+IMG_W,IMG_Y,IMG_Y+IMG_H};
  201.         RESULT Result;        
  202.         

  203.         if(flag==0)
  204.         {
  205.                 if(SearchCentre(&x0,&y0,Condition,&Area))
  206.                         flag=1;
  207.                 else
  208.                 {
  209.                         Area.X_Start= IMG_X        ;
  210.                         Area.X_End  = IMG_X+IMG_W  ;
  211.                         Area.Y_Start= IMG_Y                ;
  212.                         Area.Y_End  = IMG_Y+IMG_H;

  213.                         if(SearchCentre(&x0,&y0,Condition,&Area))        
  214.                         {
  215.                                 flag=0;
  216.                                 return 0;
  217.                         }        
  218.                 }
  219.         }
  220.         Result.x = x0;
  221.         Result.y = y0;
  222.         
  223.         for(i=0;i<ITERATE_NUM;i++)
  224.                 Corrode(Result.x,Result.y,Condition,&Result);
  225.                
  226.         if(Corrode(Result.x,Result.y,Condition,&Result))
  227.         {
  228.                 x0=Result.x;
  229.                 y0=Result.y;
  230.                 Resu->x=Result.x;
  231.                 Resu->y=Result.y;
  232.                 Resu->w=Result.w;
  233.                 Resu->h=Result.h;
  234.                 flag=1;

  235.                 Area.X_Start= Result.x - ((Result.w)>>1);
  236.                 Area.X_End  = Result.x + ((Result.w)>>1);
  237.                 Area.Y_Start= Result.y - ((Result.h)>>1);
  238.                 Area.Y_End  = Result.y + ((Result.h)>>1);


  239.                 return 1;
  240.         }
  241.         else
  242.         {
  243.                 flag=0;
  244.                 return 0;
  245.         }

  246. }
复制代码

所有资料51hei提供下载:
EasyTrace32.rar (2.83 KB, 下载次数: 49)




评分

参与人数 1黑币 +30 收起 理由
zhangshanqiao + 30 很给力!高手。

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:337808 发表于 2019-1-3 23:09 | 只看该作者
高手。
回复

使用道具 举报

板凳
ID:138247 发表于 2019-4-14 08:28 | 只看该作者

感谢分享。。。
回复

使用道具 举报

地板
ID:491531 发表于 2019-11-8 14:39 | 只看该作者
麻烦问一下 更改识别颜色在哪里
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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