在用ov7670做颜色识别的时候遇到一些问题,查阅很多资料才弄明白,遂整理一下。
一.腐蚀中心
int SearchCenter(uint16_t* x, uint16_t* y, const TARGET_CONDITION_t* condition, SEARCH_AREA_t* area )
{
uint16_t i, j, k;
uint16_t FailCount=0; //失败计数
uint16_t SpaceX, SpaceY;
COLOR_RGB_t rgb;
COLOR_HLS_t hls;
SpaceX = condition->WIDTH_MIN / 3;
SpaceY = condition->HEIGHT_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++)
{
x2=j;
y2=i;
kk=k;
if(k<SpaceX)
ReadColor( j+k, i+SpaceY/2, &rgb ); //查询色块中间一横的颜色
else
{
x3= j+SpaceX/2; y3=i+k-SpaceX;
ReadColor( j+SpaceX/2, i+k-SpaceX, &rgb ); //查询色块中间一竖的颜色 //frist into j=13 j+spaceX/2=19
}
RGB2HSL( &rgb, &hls );
if(!ColorMatch( &hls, condition ))
FailCount++; //颜色不匹配 失败计数+1
if(FailCount>6) //失败计数大于6 13次循环大于6次没有识别得到的话就break
break; //失败次数太多 退出
}
if(k == SpaceX+SpaceY) //k=13+13,,也就是说能横和竖都能识别完的话说明这个色块是识别成功了的
{
*x = j + SpaceX / 2;
*y = i + SpaceY / 2;
return 1; //记录到第一个腐蚀中心后退出函数
}
}
}
return 0;
}
这个函数是? 先以一个小的色块为单位
SpaceX = condition->WIDTH_MIN / 3;???
SpaceY = condition->HEIGHT_MIN / 3;??
一个40/3=13? 13*13大小的色块为单位进行识别,每次只读取这色块的以y的2/1? 为点(也就是这个13*13色块y轴为中心点) x轴向右开始查询识别颜色? 如识别失败个数大于6次 则认为这一个13*13的色块无效 跳出循环 继续查询下一个13*13的色块。
成功识别第一个13*13色块后,取外围第四个点分析,识别形状。
?
如果失败次数少于6次则改变查询方向 查询这色块的以X/2 为点?
对y轴进行查询方法同上 ,如果y轴有6次失败则,退出循环不认同这个色块合格(因为太小了,失败次数又多),但如果少于六次失败,则认为这个色块识别成功 ,并记录下这个色块的中心点,然后在显示屏上显示采集到的数据。 如果失败次数少于6次则改变查询方向,查询这色块的以X/2 为点,?对y轴进行查询方法同上 ,如果y轴有6次失败则退出循环,不认同这个色块合格(因为太小了,失败次数又多),但如果少于六次失败,则认为这个色块识别成功 ,并记录下这个色块的中心点,然后在显示屏上显示采集到的数据。
?
|