📄 blobdetection_cc.c
字号:
if (startx>=0)
{
endx = xdown-1;
p1 = (seed*) malloc(sizeof(seed));
p1 ->x = startx;
p1 ->y = ydown;
p1->rightlen = endx-startx+1;
p1 ->next = head;
head = p1;
notshadowpos = ydown;
startx = -1;
}
}
cursrc++;
}
}
if (startx>=0)
{
endx = xright;
p1 = (seed*) malloc(sizeof(seed));
p1 ->x = startx;
p1 ->y = ydown;
p1->rightlen = endx-startx+1;
p1 ->next = head;
head = p1;
notshadowpos = ydown;
startx = -1;
}
if (box->bottom<notshadowpos) box->bottom = ydown;
}
box->top += 3;
box->bottom -= 3;
if (pnum<MIN_BLOB_SIZE) return pnum;
// determine blob type
if (pnum<1000) theft_thresh = 1.0f;
else if (pnum<10000) theft_thresh = 1.7f;
else theft_thresh = 2.5f;
if (theftpixnum>forepixnum*theft_thresh) box->evt = EMA_THEFT;
else box->evt = EMA_NOEVENT;
// shadow removal
for (x=box->left; x<box->right; x++)
if (g_iaBlobPixCountH[x]>maxheight)
{
maxheight = g_iaBlobPixCountH[x];
}
nl = box->left;
for (;;)
if (g_iaBlobPixCountH[nl]<maxheight*2/3)
nl++;
else
break;
while (box->left<=nl-maxheight/4)
if (g_iaBlobPixCountH[box->left]<maxheight/2)
box->left++;
else
break;
nr = box->right;
for (;;)
if (g_iaBlobPixCountH[nr]<maxheight*2/3)
nr--;
else
break;
while (box->right>=nr+maxheight/4)
if (g_iaBlobPixCountH[box->right]<maxheight/2)
box->right--;
else
break;
// remove blobs with very few foreground pixels in them
boxsize = (box->right-box->left)*(box->bottom-box->top);
pixnum = 0;
for (x=box->left; x<=box->right; x++)
pixnum += g_iaBlobPixCountH[x];
if (pixnum<200 && (pixnum+4)<boxsize/5)
return -pixnum;
if (pixnum<500 && pixnum<boxsize/6)
return -pixnum;
// region is surrounded by shadow pixels
if (shadowborder>totalborder*5/6 && pnum<200) return -1;
return pnum;
}
/** Compare two blobs
* @param rsmall the small rect
* @param rbig the big rect
* @return if rbig includes rsmall, return 1, else return 0
* @author Gengyu Ma
*/
BYTE Blob_Inside(EmaRect rsmall, EmaRect rbig)
{
INT l,r,t,b;
rsmall.left += 2;
rsmall.right -= 2;
rsmall.top += 2;
rsmall.bottom -= 2;
l = EMA_MAX(rsmall.left, rbig.left);
r = EMA_MIN(rsmall.right, rbig.right);
t = EMA_MAX(rsmall.top, rbig.top);
b = EMA_MIN(rsmall.bottom, rbig.bottom);
if (l>=r) return 0;
if (t>=b) return 0;
if ((r-l)*5<(rsmall.right-rsmall.left)*3) return 0;
if ((b-t)*5<(rsmall.bottom-rsmall.top)*3) return 0;
return 1;
}
/** Extract Blobs from label image
* @param img the label image
* @param emaRects the position and size of each region
* @param types the type of each region, FG or theft
* @param nBlobNum the number of blobs
* @param forenum the total number of FG and theft pixels
* @param noisenum the total number of noises, small regions
* @return void
* @author Gengyu Ma
*/
void Blob_Detection(BYTE* img, EmaRect* EmaRects, INT* nBlobNum, INT* forenum, INT* noisenum)
{
EmaRect blob;
BYTE newflag = 0;
USHORT maxblobsize = 0;
INT pnum;
USHORT x,y,i;
BYTE* srcaddr = img;
*nBlobNum = *forenum = *noisenum = 0;
for (y=0; y<g_iImageHeight; y++)
for (x=0; x<g_iImageWidth; x++)
{
if ( (*srcaddr == FOREPIXEL || *srcaddr==THEFTPIXEL) )// && *difaddr>DIFFERENCE_THRESH)
{
// pnum = Blob_ScanLineFill_Shadow(img, x,y, &blob);
pnum = Blob_ScanLineFill(img, x,y, &blob);
if ( pnum>=MIN_BLOB_SIZE && *nBlobNum<EMA_MAX_NUM_BLOB )
{
if (pnum>maxblobsize) maxblobsize = pnum;
newflag = 1;
(*forenum) += pnum;
for (i=0; i<*nBlobNum; i++)
{
if (Blob_Inside(blob, EmaRects[i]))
{
newflag = 0;
break;
}
if (Blob_Inside(EmaRects[i], blob))
{
EmaRects[i] = blob;
newflag = 0;
break;
}
}
if (newflag)
{
EmaRects[*nBlobNum] = blob;
(*nBlobNum) ++;
}
}
else if (pnum>4)
(*noisenum) += pnum;
else if (pnum<0)
(*noisenum) -= pnum;
}
srcaddr ++;
}
if (maxblobsize>THR_CLOSE)
ABS_SetParameters(SCENE_FAR_OR_NEAR, 1);
else
ABS_SetParameters(SCENE_FAR_OR_NEAR, 0);
ABS_SetParameters(SCENE_BLOB_SIZE, maxblobsize);
// remove all other unlabeled pixels, label them as shadow
}
/** Extract Blobs from label image
* @param img the label image
* @param emaRects the position and size of each region
* @param types the type of each region, FG or theft
* @param nBlobNum the number of blobs
* @return void
* @author Gengyu Ma
*/
void Blob_Detection_Again(BYTE* img, EmaRect* EmaRects, INT* nBlobNum)
{
EmaRect blob;
BYTE newflag = 0;
USHORT maxblobsize = 0;
INT pnum;
USHORT x,y,i;
BYTE* srcaddr = img;
*nBlobNum = 0;
for (y=0; y<g_iImageHeight; y++)
for (x=0; x<g_iImageWidth; x++)
{
if ( (*srcaddr == FOREPIXEL || *srcaddr==THEFTPIXEL) )// && *difaddr>DIFFERENCE_THRESH)
{
// pnum = Blob_ScanLineFill_Shadow(img, x,y, &blob, &blobtype);
pnum = Blob_ScanLineFill(img, x,y, &blob);
if ( pnum>=MIN_BLOB_SIZE && *nBlobNum<EMA_MAX_NUM_BLOB )
{
if (pnum>maxblobsize) maxblobsize = pnum;
newflag = 1;
for (i=0; i<*nBlobNum; i++)
{
if (Blob_Inside(blob, EmaRects[i]))
{
newflag = 0;
break;
}
if (Blob_Inside(EmaRects[i], blob))
{
EmaRects[i] = blob;
newflag = 0;
break;
}
}
if (newflag)
{
EmaRects[*nBlobNum] = blob;
(*nBlobNum) ++;
}
}
else if (pnum>4)
{
// Blob_ScanLineFill(img, x,y, blob, SMALLNOISE);
}
}
srcaddr ++;
}
// remove all other unlabeled pixels, label them as shadow
}
/** Extract Blobs from label image
* @param img the label image
* @param img the label image, FG and theft pixels are dilated to their surrounder
* @return void
* @author Gengyu Ma
*/
void Blob_Dilate_Fore_into_Shadow(BYTE* img)
{
USHORT w = g_iImageWidth;
USHORT h = g_iImageHeight;
USHORT wstep = g_iImageWStep;
USHORT x, y, y2;
BYTE* srhadd;
BYTE* filladd;
srhadd = img + wstep*3 + 1;
for (y=3; y<h-3; y++)
{
for (x=1; x<w-1; x++)
{
if (*srhadd>GAPFORE &&
( ( *(srhadd-wstep)<=GAPFORE )
|| ( *(srhadd+wstep)<=GAPFORE )
|| ( *(srhadd-1)<=GAPFORE )
|| ( *(srhadd+1)<=GAPFORE ) ) )
{
filladd = srhadd - 1 - wstep - wstep - wstep;
for (y2=0; y2<=6; y2++)
{
if (*filladd<=SHADOW) *filladd = GAPFORE;
filladd ++;
if (*filladd<=SHADOW) *filladd = GAPFORE;
filladd ++;
if (*filladd<=SHADOW) *filladd = GAPFORE;
filladd += g_iImageWStep - 2;
}
}
srhadd ++;
}
srhadd += 2;
}
}
/** determine whether a theft blob is theft or left baggage
* @param grayimg the captured gray image
* @param label label image
* @param blob the size and position of this region
* @return void
* @author Gengyu Ma
*/
void Blob_Theft_or_LeftBag(BYTE *grayimg, BYTE* label, EmaRect* blob)//, BYTE* type)
{
USHORT x,y;
BYTE *imgadd, *lbladd;
USHORT totalborder = 0, totalgrad = 0;
SHORT gradv, gradh;
//
for (y=blob->top; y<=blob->bottom; y++)
{
imgadd = grayimg + y*g_iImageWStep + blob->left;
lbladd = label + y*g_iImageWStep + blob->left;
for (x=blob->left; x<blob->right; x++)
{
if (x>1 && x<g_iImageWidth-2 && y>1 && y<g_iImageHeight-2)
{
if ((*lbladd)!=*(lbladd-1) || (*lbladd)!=*(lbladd+1)
|| (*lbladd)!=*(lbladd-g_iImageWStep) || (*lbladd)!=*(lbladd+g_iImageWStep) )
{
totalborder ++;
gradv = abs((SHORT)(*(imgadd+2)) - (SHORT)(*(imgadd-2)));
gradh = abs((SHORT)(*(imgadd+g_iImageWStep*2)) - (SHORT)(*(imgadd-g_iImageWStep*2)));
gradh = EMA_MAX(gradh, gradv);
totalgrad += EMA_MIN(gradh, 32);
}
}
}
imgadd ++;
lbladd ++;
}
// determine theft or left baggage
// 20071010 Taesuh
// [start]
if (totalgrad>totalborder*10)
blob->evt = EMA_LEFT; // left baggage
else
blob->evt = EMA_THEFT; // theft
// [end]
/*
if (totalgrad>totalborder*10)
*type = 2; // left baggage
else
*type = 1; // theft
*/
}
/** Reset label image to the state before blob detection
* @param img the label image
* @param img the label image
* @return void
* @author Gengyu Ma
*/
void Blob_ResetLabelImage(BYTE* lblimg)
{
INT x;
INT pnum = g_iImageHeight*g_iImageWStep;
BYTE* addr = lblimg;
for (x=0; x<pnum; x++)
{
if (*addr==FOREGROUND)
*addr = FOREPIXEL;
else if (*addr==THEFT)
*addr = THEFTPIXEL;
else if (*addr==GAPFORE-100) *addr = 0;
addr ++;
}
}
/** determine whether a blob is shadow or not, and remove shadow region
* @param label label image
* @param diffimg the difference between input and model
* @param blob the size and position of this region
* @return void
* @author Gengyu Ma
*/
void Blob_RemoveShadow( BYTE* label, BYTE *diffimg, EmaRect* blob )
{
BYTE* cur_diff, *cur_lbl;
BYTE* up_diff, *down_diff;
LONG displace;
SHORT x,y;
SHORT grad, g1, g2, g3, g4;
LONG grad_sum = 0;
SHORT blob_width = (blob->right-blob->left+1);
SHORT blob_height = (blob->bottom-blob->top+1);
LONG blob_area = blob_width * blob_height;
INT factor;
if (g_ABSSceneType & DARK_SCN) return ;
// count gradient
memset(g_iaBlobPixCountH, 0, g_iImageWidth*sizeof(LONG));
memset(g_iaBlobPixCountV, 0, g_iImageHeight*sizeof(LONG));
displace = blob->top * g_iImageWStep;
cur_diff = diffimg + displace;
up_diff = cur_diff - g_iImageWStep - g_iImageWStep;
down_diff = cur_diff + g_iImageWStep + g_iImageWStep;
for (y=blob->top; y<=blob->bottom; y++)
{
for (x=blob->left; x<=blob->right; x++)
{
if (cur_diff[x]>96) grad = 32;
else
{
grad = 0;
if (x>=2)
{ g1 = EMA_DIFF(cur_diff[x-2], cur_diff[x]); grad = EMA_MAX(grad, g1); }
if (x<g_iImageWidth-2)
{ g2 = EMA_DIFF(cur_diff[x+2], cur_diff[x]); grad = EMA_MAX(grad, g2); }
if (y>=2)
{ g3 = EMA_DIFF(up_diff[x], cur_diff[x]); grad = EMA_MAX(grad, g3); }
if (y<g_iImageHeight-2)
{ g4 = EMA_DIFF(down_diff[x], cur_diff[x]); grad = EMA_MAX(grad, g4); }
}
g_iaBlobPixCountH[x] += grad;
g_iaBlobPixCountV[y] += grad;
grad_sum += grad;
++ cur_diff;
++ up_diff;
++ down_diff;
}
cur_diff += g_iImageWStep - blob_width;
up_diff += g_iImageWStep - blob_width;
down_diff += g_iImageWStep - blob_width;
}
// remove shadow blob
if (blob_area<400) factor = 20;
else if (blob_area<1600) factor = 18;
else if (blob_area<4000) factor = 14;
else factor = 10;
if (grad_sum<blob_area*factor) { blob->evt = EMA_SHADOW; return; }
// resize blob
for (y=blob->top; y<=(blob->top+blob->bottom)>>1; y++)
if (g_iaBlobPixCountV[y]>blob_width*12) break;
blob->top = y;
for (y=blob->bottom; y>=(blob->top+blob->bottom)>>1; y--)
if (g_iaBlobPixCountV[y]>blob_width*12) break;
blob->bottom = y;
}
#ifdef __cplusplus
} // extern "C"
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -