更正一處bug:easytrace.c文件中第81行修改為s = (difVal)*240/(511 - (maxVal+minVal));
單片機源程序如下:
- #include "EasyTracer.h"
- #define min3v(v1, v2, v3) ((v1)>(v2)? ((v2)>(v3)?(v3):(v2)):((v1)>(v3)?(v3):(v1)))
- #define max3v(v1, v2, v3) ((v1)<(v2)? ((v2)<(v3)?(v3):(v2)):((v1)<(v3)?(v3):(v1)))
- typedef struct{
- unsigned char red; // [0,255]
- unsigned char green; // [0,255]
- unsigned char blue; // [0,255]
- }COLOR_RGB;//RGB格式顏色
- typedef struct{
- unsigned char hue; // [0,240]
- unsigned char saturation; // [0,240]
- unsigned char luminance; // [0,240]
- }COLOR_HSL;//HSL格式顏色
- typedef struct{
- unsigned int X_Start;
- unsigned int X_End;
- unsigned int Y_Start;
- unsigned int Y_End;
- }SEARCH_AREA;//區域
- //讀取RBG格式顏色,唯一需要移植的函數
- extern unsigned short GUI_ReadBit16Point(unsigned short x,unsigned short y);
- static void ReadColor(unsigned int x,unsigned int y,COLOR_RGB *Rgb)
- {
- unsigned short C16;
- C16 = GUI_ReadBit16Point(x,y);
- Rgb->red = (unsigned char)((C16&0xf800)>>8);
- Rgb->green = (unsigned char)((C16&0x07e0)>>3);
- Rgb->blue = (unsigned char)((C16&0x001f)<<3);
- }
- //RGB轉HSL
- static void RGBtoHSL(const COLOR_RGB *Rgb, COLOR_HSL *Hsl)
- {
- int h,s,l,maxVal,minVal,difVal;
- int r = Rgb->red;
- int g = Rgb->green;
- int b = Rgb->blue;
-
- maxVal = max3v(r, g, b);
- minVal = min3v(r, g, b);
-
- difVal = maxVal-minVal;
-
- //計算亮度
- l = (maxVal+minVal)*240/255/2;
-
- if(maxVal == minVal)//若r=g=b
- {
- h = 0;
- s = 0;
- }
- else
- {
- //計算色調
- if(maxVal==r)
- {
- if(g>=b)
- h = 40*(g-b)/(difVal);
- else
- h = 40*(g-b)/(difVal) + 240;
- }
- else if(maxVal==g)
- h = 40*(b-r)/(difVal) + 80;
- else if(maxVal==b)
- h = 40*(r-g)/(difVal) + 160;
- //計算飽和度
- if(l == 0)
- s = 0;
- else if(l<=120)
- s = (difVal)*240/(maxVal+minVal);
- else
- s = (difVal)*240/(480 - (maxVal+minVal));
- }
- Hsl->hue = (unsigned char)(((h>240)? 240 : ((h<0)?0:h)));
- Hsl->saturation = (unsigned char)(((s>240)? 240 : ((s<0)?0:s)));
- Hsl->luminance = (unsigned char)(((l>240)? 240 : ((l<0)?0:l)));
- }
- //匹配顏色
- static int ColorMatch(const COLOR_HSL *Hsl,const TARGET_CONDI *Condition)
- {
- if(
- Hsl->hue > Condition->H_MIN &&
- Hsl->hue < Condition->H_MAX &&
- Hsl->saturation > Condition->S_MIN &&
- Hsl->saturation < Condition->S_MAX &&
- Hsl->luminance > Condition->L_MIN &&
- Hsl->luminance < Condition->L_MAX
- )
- return 1;
- else
- return 0;
- }
- //搜索腐蝕中心
- static int SearchCentre(unsigned int *x,unsigned int *y,const TARGET_CONDI *Condition,const SEARCH_AREA *Area)
- {
- unsigned int SpaceX,SpaceY,i,j,k,FailCount=0;
- COLOR_RGB Rgb;
- COLOR_HSL Hsl;
-
- SpaceX = Condition->WIDTH_MIN/3;
- SpaceY = Condition->HIGHT_MIN/3;
- for(i=Area->Y_Start;i<Area->Y_End;i+=SpaceY)
- {
- for(j=Area->X_Start;j<Area->X_End;j+=SpaceX)
- {
- FailCount=0;
- for(k=0;k<SpaceX+SpaceY;k++)
- {
- if(k<SpaceX)
- ReadColor(j+k,i+SpaceY/2,&Rgb);
- else
- ReadColor(j+SpaceX/2,i+(k-SpaceX),&Rgb);
- RGBtoHSL(&Rgb,&Hsl);
-
- if(!ColorMatch(&Hsl,Condition))
- FailCount++;
- if(FailCount>((SpaceX+SpaceY)>>ALLOW_FAIL_PER))
- break;
- }
- if(k==SpaceX+SpaceY)
- {
- *x = j+SpaceX/2;
- *y = i+SpaceY/2;
- return 1;
- }
- }
- }
- return 0;
- }
- //從腐蝕中心向外腐蝕,得到新的腐蝕中心
- static int Corrode(unsigned int oldx,unsigned int oldy,const TARGET_CONDI *Condition,RESULT *Resu)
- {
- unsigned int Xmin,Xmax,Ymin,Ymax,i,FailCount=0;
- COLOR_RGB Rgb;
- COLOR_HSL Hsl;
-
- for(i=oldx;i>IMG_X;i--)
- {
- ReadColor(i,oldy,&Rgb);
- RGBtoHSL(&Rgb,&Hsl);
- if(!ColorMatch(&Hsl,Condition))
- FailCount++;
- if(FailCount>(((Condition->WIDTH_MIN+Condition->WIDTH_MAX)>>2)>>ALLOW_FAIL_PER))
- break;
- }
- Xmin=i;
- FailCount=0;
-
- for(i=oldx;i<IMG_X+IMG_W;i++)
- {
- ReadColor(i,oldy,&Rgb);
- RGBtoHSL(&Rgb,&Hsl);
- if(!ColorMatch(&Hsl,Condition))
- FailCount++;
- if(FailCount>(((Condition->WIDTH_MIN+Condition->WIDTH_MAX)>>2)>>ALLOW_FAIL_PER))
- break;
- }
- Xmax=i;
- FailCount=0;
-
- for(i=oldy;i>IMG_Y;i--)
- {
- ReadColor(oldx,i,&Rgb);
- RGBtoHSL(&Rgb,&Hsl);
- if(!ColorMatch(&Hsl,Condition))
- FailCount++;
- if(FailCount>(((Condition->HIGHT_MIN+Condition->HIGHT_MAX)>>2)>>ALLOW_FAIL_PER))
- break;
- }
- Ymin=i;
- FailCount=0;
-
- for(i=oldy;i<IMG_Y+IMG_H;i++)
- {
- ReadColor(oldx,i,&Rgb);
- RGBtoHSL(&Rgb,&Hsl);
- if(!ColorMatch(&Hsl,Condition))
- FailCount++;
- if(FailCount>(((Condition->HIGHT_MIN+Condition->HIGHT_MAX)>>2)>>ALLOW_FAIL_PER))
- break;
- }
- Ymax=i;
- FailCount=0;
-
- Resu->x = (Xmin+Xmax)/2;
- Resu->y = (Ymin+Ymax)/2;
- Resu->w = Xmax-Xmin;
- Resu->h = Ymax-Ymin;
- if(((Xmax-Xmin)>(Condition->WIDTH_MIN)) && ((Ymax-Ymin)>(Condition->HIGHT_MIN)) &&\
- ((Xmax-Xmin)<(Condition->WIDTH_MAX)) && ((Ymax-Ymin)<(Condition->HIGHT_MAX)) )
- return 1;
- else
- return 0;
- }
- //唯一的API,用戶將識別條件寫入Condition指向的結構體中,該函數將返回目標的x,y坐標和長寬
- //返回1識別成功,返回1識別失敗
- int Trace(const TARGET_CONDI *Condition,RESULT *Resu)
- {
- unsigned int i;
- static unsigned int x0,y0,flag=0;
- static SEARCH_AREA Area={IMG_X,IMG_X+IMG_W,IMG_Y,IMG_Y+IMG_H};
- RESULT Result;
-
- if(flag==0)
- {
- if(SearchCentre(&x0,&y0,Condition,&Area))
- flag=1;
- else
- {
- Area.X_Start= IMG_X ;
- Area.X_End = IMG_X+IMG_W ;
- Area.Y_Start= IMG_Y ;
- Area.Y_End = IMG_Y+IMG_H;
- if(SearchCentre(&x0,&y0,Condition,&Area))
- {
- flag=0;
- return 0;
- }
- }
- }
- Result.x = x0;
- Result.y = y0;
-
- for(i=0;i<ITERATE_NUM;i++)
- Corrode(Result.x,Result.y,Condition,&Result);
-
- if(Corrode(Result.x,Result.y,Condition,&Result))
- {
- x0=Result.x;
- y0=Result.y;
- Resu->x=Result.x;
- Resu->y=Result.y;
- Resu->w=Result.w;
- Resu->h=Result.h;
- flag=1;
- Area.X_Start= Result.x - ((Result.w)>>1);
- Area.X_End = Result.x + ((Result.w)>>1);
- Area.Y_Start= Result.y - ((Result.h)>>1);
- Area.Y_End = Result.y + ((Result.h)>>1);
- return 1;
- }
- else
- {
- flag=0;
- return 0;
- }
- }
復制代碼
所有資料51hei提供下載:
EasyTrace32.rar
(2.83 KB, 下載次數: 49)
2018-8-24 15:00 上傳
點擊文件名下載附件
|