📄 centroid.cpp
字号:
#include <stdafx.h>
#include <math.h>
#include "segment.h"
#include "label.h"
#include "common.h"
#include "basic.h"
#include "centroid.h"
DynamicInfo XYQueue[QueueSize];
int QueueIndex=0;
void DetectTarget(unsigned char **oriimg,int row,int col,FRAME *SearchWin,int h)
{
int i,j,k,l;
int max_i,max_j,max_grey,grey;
double aver_grey,aver;
int temp_h = 20;
max_grey = 0;
for(i=h+temp_h; i<row-h-temp_h; i++)
for(j=h+temp_h; j<col-h-temp_h; j++)
{
grey = 0;
for(k=0; k<h; k++)
for(l=0; l<h; l++) grey += oriimg[i+k][j+l];
if(max_grey<grey)
{
max_i = i + h/2;
max_j = j + h/2;
max_grey = grey;
}
}
aver_grey = (double)max_grey/h/h;
SearchWin->left = max_j - h/2;
SearchWin->up = max_i - h/2;
SearchWin->right= SearchWin->left + h;
SearchWin->down = SearchWin->up + h;
//boundary detection
SearchWin->up = SearchWin->up<0 ? 0 : SearchWin->up;
SearchWin->down = SearchWin->down>=row ? row-1 : SearchWin->down;
SearchWin->left = SearchWin->left<0 ? 0 : SearchWin->left;
SearchWin->right = SearchWin->right>=col ? col-1 : SearchWin->right;
// while(aver>aver_grey*0.6)
do {
SearchWin->left -= 2;
SearchWin->right += 2;
SearchWin->up -= 2;
SearchWin->down += 2;
aver = 0.0;
for(i=SearchWin->up; i<SearchWin->down; i++)
for(j=SearchWin->left; j<SearchWin->right; j++)
aver += oriimg[i][j];
aver /= (SearchWin->right-SearchWin->left)*(SearchWin->down-SearchWin->up);
}while(aver>aver_grey*0.8);
}
/* extract the target from the manually selected window */
void GetInitialTemplate(unsigned char **oriimg,int row,int col,FRAME SearchWin,RegionInfo *target)
{
int threshold;
int i,j,k;
int labelnum;
unsigned char **segimg;
int SearchWinRow,SearchWinCol;
RegionInfo region[10];
SearchWinRow = SearchWin.down - SearchWin.up;
SearchWinCol = SearchWin.right - SearchWin.left;
// threshold = NonlineOtsu(oriimg,SearchWin.up,SearchWin.left,SearchWinRow,SearchWinCol,0.1);
threshold = Otsu1(oriimg,SearchWin.up,SearchWin.left,SearchWinRow,SearchWinCol);
// threshold = GrdientSeg(oriimg,SearchWin.up,SearchWin.left,SearchWinRow,SearchWinCol);
segimg = (unsigned char **)fspace_2d(SearchWinRow,SearchWinCol,sizeof(unsigned char));
if(!segimg) return ;
/* segment the selected window */
for(i=0; i<SearchWinRow; i++)
for(j=0; j<SearchWinCol; j++)
if(oriimg[i+SearchWin.up][j+SearchWin.left]>threshold) segimg[i][j] = 255;
/* label the segmented image */
labelnum = Label(segimg,SearchWinRow,SearchWinCol,LABELMODE_1,4);
/* get the region information */
for(k=0; k<labelnum; k++)
{
region[k].left = SearchWinCol;
region[k].up = SearchWinRow;
region[k].right = 0;
region[k].down = 0;
region[k].mean = 0;
region[k].aera = 0;
region[k].centroidr = 0;
region[k].centroidc = 0;
region[k].distance = 0;
}
for(i=0; i<SearchWinRow; i++)
for(j=0; j<SearchWinCol; j++)
{
if(segimg[i][j])
{
k = segimg[i][j];
if(i<region[255-k].up) region[255-k].up = i;
if(i>region[255-k].down) region[255-k].down = i;
if(j<region[255-k].left) region[255-k].left = j;
if(j>region[255-k].right) region[255-k].right = j;
region[255-k].aera += 1;
region[255-k].mean += oriimg[i+SearchWinRow][j+SearchWinCol];
region[255-k].centroidr += i*oriimg[i+SearchWinRow][j+SearchWinCol];
region[255-k].centroidc += j*oriimg[i+SearchWinRow][j+SearchWinCol];
}
}
for(k=0; k<labelnum; k++)
{
region[k].left += SearchWin.left;
region[k].up += SearchWin.up;
region[k].right += SearchWin.left;
region[k].down += SearchWin.up;
region[k].centroidr = region[k].centroidr/region[k].mean + SearchWin.up;
region[k].centroidc = region[k].centroidc/region[k].mean + SearchWin.left;
region[k].mean /= region[k].aera;
}
/* search the region with the largest aera */
target->left = region[0].left;
target->up = region[0].up;
target->right = region[0].right;
target->down = region[0].down;
target->centroidr = region[0].centroidr;
target->centroidc = region[0].centroidc;
target->mean = region[0].mean;
target->aera = region[0].aera;
target->distance = region[0].distance;
for(k=0; k<labelnum; k++)
{
if(region[k].aera>target->aera)
{
target->left = region[k].left;
target->up = region[k].up;
target->right = region[k].right;
target->down = region[k].down;
target->centroidr = region[k].centroidr;
target->centroidc = region[k].centroidc;
target->mean = region[k].mean;
target->aera = region[k].aera;
target->distance = region[k].distance;
}
}
ffree_2d((void **)segimg,SearchWinRow);
//draw the frame on the target
for(i=target->up; i<=target->down; i++)
{
oriimg[i][target->left] = 255;
oriimg[i][target->right] = 255;
}
for(j=target->left; j<target->right; j++)
{
oriimg[target->down][j] = 255;
oriimg[target->up][j] = 255;
}
return;
}
int CentroidTrack(unsigned char **oriimg,int row,int col,RegionInfo *target)
{
FRAME SearchWin;
int dr,dc; /* */
double ratio; /* expended ratio */
int threshold;
int SearchWinRow,SearchWinCol;
int labelnum; /* label region number */
unsigned char **segimg;
RegionInfo region[10],temp;
double aera_ratio;
double mean_ratio;
int i,j,k;
ratio = 1.0;
dr = (int)((target->down - target->up)*ratio);
dc = (int)((target->right - target->left)*ratio);
if(dr<8) dr = 8;
if(dc<8) dc = 8;
/* define the search window */
SearchWin.up = target->up - dr;
SearchWin.down = target->down + dr;
SearchWin.left = target->left - dc;
SearchWin.right = target->right + dc;
//boundary detection
SearchWin.up = SearchWin.up<0 ? 0 : SearchWin.up;
SearchWin.down = SearchWin.down>=row ? row-1 : SearchWin.down;
SearchWin.left = SearchWin.left<0 ? 0 : SearchWin.left;
SearchWin.right = SearchWin.right>=col ? col-1 : SearchWin.right;
SearchWinRow = SearchWin.down - SearchWin.up;
SearchWinCol = SearchWin.right - SearchWin.left;
/* get the segmented threshold */
// threshold = NonlineOtsu(oriimg,SearchWin.up,SearchWin.left,SearchWinRow,SearchWinCol,0.1);
threshold = Otsu1(oriimg,SearchWin.up,SearchWin.left,SearchWinRow,SearchWinCol);
// threshold = GrdientSeg(oriimg,SearchWin.up,SearchWin.left,SearchWinRow,SearchWinCol);
segimg = (unsigned char **)fspace_2d(SearchWinRow,SearchWinCol,sizeof(unsigned char));
// segimg = fspace_2d1(SearchWinRow,SearchWinCol,sizeof(unsigned char));
if(!segimg) return 0;
/* segment the selected window */
for(i=0; i<SearchWinRow; i++)
for(j=0; j<SearchWinCol; j++)
if(oriimg[i+SearchWin.up][j+SearchWin.left]>threshold) segimg[i][j] = oriimg[i+SearchWin.up][j+SearchWin.left];
threshold = Otsu1(segimg,0,0,SearchWinRow,SearchWinCol);
for(i=0; i<SearchWinRow; i++)
for(j=0; j<SearchWinCol; j++)
if(segimg[i][j]>threshold) segimg[i][j] = 255;
else segimg[i][j] = 0;
/* label the segmented image */
labelnum = Label(segimg,SearchWinRow,SearchWinCol,LABELMODE_1,4);
/* get the segmented region's information,including aera,mean,range,centroid,etc. */
for(k=0; k<labelnum; k++)
{
region[k].left = SearchWinCol;
region[k].up = SearchWinRow;
region[k].right = 0;
region[k].down = 0;
region[k].mean = 0;
region[k].aera = 0;
region[k].centroidr = 0;
region[k].centroidc = 0;
region[k].distance = 0;
region[k].aera = 0;
region[k].mean = 0;
}
for(i=0; i<SearchWinRow; i++)
for(j=0; j<SearchWinCol; j++)
{
if(segimg[i][j])
{
k = segimg[i][j];
if(i<region[255-k].up) region[255-k].up = i;
if(i>region[255-k].down) region[255-k].down = i;
if(j<region[255-k].left) region[255-k].left = j;
if(j>region[255-k].right) region[255-k].right = j;
region[255-k].aera += 1;
region[255-k].mean += oriimg[i+SearchWin.up][j+SearchWin.left];
region[255-k].centroidr += i*oriimg[i+SearchWin.up][j+SearchWin.left];
region[255-k].centroidc += j*oriimg[i+SearchWin.up][j+SearchWin.left];
}
}
for(k=0; k<labelnum; k++)
{
region[k].centroidr = region[k].centroidr/region[k].mean;
region[k].centroidc = region[k].centroidc/region[k].mean;
region[k].mean /= region[k].aera;
region[k].distance = sqrt((region[k].centroidr+SearchWin.up-target->centroidr)*(region[k].centroidr+SearchWin.up-target->centroidr)
+ (region[k].centroidc+SearchWin.left-target->centroidc)*(region[k].centroidc+SearchWin.left-target->centroidc));
}
/* sort region according the distance */
for(i=0; i<labelnum; i++)
for(j=i+1; j<labelnum; j++)
{
if(region[j].distance<region[i].distance)
{
temp.aera = region[i].aera;
temp.mean = region[i].mean;
temp.distance = region[i].distance;
temp.left = region[i].left;
temp.up = region[i].up;
temp.right = region[i].right;
temp.down = region[i].down;
temp.centroidr = region[i].centroidr;
temp.centroidc = region[i].centroidc;
region[i].aera = region[j].aera;
region[i].mean = region[j].mean;
region[i].distance = region[j].distance;
region[i].left = region[j].left;
region[i].up = region[j].up;
region[i].right = region[j].right;
region[i].down = region[j].down;
region[i].centroidr = region[j].centroidr;
region[i].centroidc = region[j].centroidc;
region[j].aera = temp.aera;
region[j].mean = temp.mean;
region[j].distance = temp.distance;
region[j].left = temp.left;
region[j].up = temp.up;
region[j].right = temp.right;
region[j].down = temp.down;
region[j].centroidr = temp.centroidr;
region[j].centroidc = temp.centroidc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -