单区域的跟踪前面已经讲过,但是对于图片中存在多个分离的物体进行那个跟踪前面的算法就不能够胜任。而且单区域的跟踪对于孔的检测也不能完成。
多区域跟踪有很多种做法,下面是我参考一些资料写的代码,自己觉得处理过程过去繁琐,虽然得到了结果,算法还没有得到完全的优化。
总体思想:
1.判断背景的色彩,这是因为我在做单区域跟踪的时候,对阈值的处理是默认为低于某个阈值来作为边界的。所以在这里要做背景颜色的检测,然后对于背景是黑色的直接做反二值化处理 2.二值化,虽然不用阈值化,在后面的代码中我也做了与阈值的处理。 3.寻找第一个边界点,默认小于某个阈值为边界点 4.对单个区域进行跟踪,得到边界的链码表 5.下面可以对检测到的边界进行处理 这里我把链码表转换为线段表,然后求得检测到区域的中心 6.将刚才检测到的区域涂成背景颜色,这样在下面对处理中就不会重复 7.重复3~6,直到检测不到边界为止如果你大概算一下算法的复杂度就会发现,算法的时间复杂度是平方关系,在每个步骤里面至少对图像遍历一次,将链码表转换为线段表各要进行三次,可想而知,对于一个有N个特征点的图片,算法的复杂度 N*(N+N+3N+N+N) = 7N^2
下面是一些多区域跟踪的一些资料
一种基于区域生长的多个形变目标跟踪方法.pdf
基于多区域的人体运动跟踪研究与应用.pdf
下面是我的代码:
/*************************************************************************************
寻找所有的LED中心,该函数只对LED有效
过程:
判断图像的背景,二值化,寻找第边界点,跟踪得到链码表,将链码表转换为线段表,求取重心并存储
把刚才的背景涂为背景颜色
重复上面的步骤,直到找不到边界点
对上面的边界点进行排序
/////
得到的链码以及线段表存储在文档中
/////
默认是向右看齐
/////
参数:
图像信息头
图像数据
LED中心数据数组
返回检测到的led数目
///////////////////////////////////////////////////
int ImgMutiTrace(BITMAPINFO* pbmpinfo,BYTE* pbmpdata,ImgDot *CenterDot)
{
ImgDot curr_dot={0,0};
BOOL IS_OVER = TRUE; //判断是否检测完毕
int code[1024]={0};
ImgDot LineCode[1024]={{0,0}};
int Line_num=0;
int centerdot_num =0;
int background = 255;
//FILE *fp;
//fp = fopen("中间数据.txt","w+");
//if (fp==NULL)
//{
// AfxMessageBox("文件打开失败!");
// return -1;
//}
//判断背景的颜色
if (ImgGetPixel(pbmpinfo,pbmpdata,curr_dot) < 100 )
{
ImgThreshold(pbmpinfo,pbmpdata,100,255,IMG_THRESHOLD_BINARY_INV); //二值化
}
else
{
ImgThreshold(pbmpinfo,pbmpdata,100,255,IMG_THRESHOLD_BINARY); //二值化
}
//寻找第一个边界点
while (IS_OVER)
{
curr_dot = ImgFindFirstDot(pbmpinfo,pbmpdata,100);
if (curr_dot.cx == -1 || curr_dot.cy == -1 ) //检测不到边界点的话,检测结束
{
IS_OVER = FALSE;
break;
}
int num=ImgSingleTrace(pbmpinfo,pbmpdata,&curr_dot,4,code,IMG_CHAIN_8,IMG_SEARCH_DIR_RIGHT);
if (num == -1) //边界跟踪,返回边界点数
{
AfxMessageBox("孤立点!");
return -1;
}
Line_num=ImgCode2Line(code,LineCode); //得到线段表,返回端点的数目
CenterDot[centerdot_num++] = ImgCenterGravity(LineCode,Line_num); //计算重心
ImgFillArea(pbmpinfo,pbmpdata,LineCode,Line_num,background); //将区域染成背景的颜色
}
centerdot_num = centerdot_num;
//排序
if (IS_OVER == FALSE)
{
return centerdot_num;
}
return -1;
}
文章评论(0条评论)
登录后参与讨论