📄 histogram.c.bak
字号:
fscanf(filein, "%s", &prompt);
fscanf(filein, "%d", &RBINS);
fscanf(filein, "%s", &prompt);
fscanf(filein, "%d", &GBINS);
fscanf(filein, "%s", &prompt);
fscanf(filein, "%d", &BBINS);
fclose(filein);
//in case of wrong setting
if(RBINS<=0)
RBINS = 10;
if(GBINS<=0)
GBINS = 10;
if(BBINS<=0)
BBINS = 10;
// //debug
// RBINS = 50;
// GBINS = 50;
// BBINS = 50;
}
/////////////////////////////////////////////////////////////////////////////////////////
void his_CheckBoxBound(RECT *inRect, int imgWidth, int imgHeight)
//check whether the box (left, right, top, bottm) is out of bound
{
inRect->left = max(inRect->left, 0);
inRect->right = min(inRect->right, imgWidth-1);
inRect->top = max(inRect->top, 0);
inRect->bottom = min(inRect->bottom, imgHeight-1);
inRect->right = (inRect->right>inRect->left? inRect->right: inRect->left);
inRect->bottom = (inRect->bottom>inRect->top? inRect->bottom: inRect->top);
}
///////////////////////////////////////////////////////////////////////////////
void his_CountBoxHistogram(IplImage* inImg, RECT inRect, CvHistogram *outHist)
//count histogram within a rect box
{
int row, col;
BYTE pixH, pixS, pixV;
int binH, binS, binV;
float *pix;
IplImage* h_plane = cvCreateImage(cvGetSize(inImg), 8, 1 );
IplImage* s_plane = cvCreateImage(cvGetSize(inImg), 8, 1 );
IplImage* v_plane = cvCreateImage(cvGetSize(inImg), 8, 1 );
//Divide image into planes
cvCvtPixToPlane(inImg, h_plane, s_plane, v_plane, 0 );
//count histogram
cvClearHist(outHist);
for (row=inRect.top;row<=inRect.bottom;row++){
for (col=inRect.left; col<=inRect.right; col++){
//calculate histogram
pixH = (BYTE)cvGetReal2D(h_plane,row,col);
pixS = (BYTE)cvGetReal2D(s_plane,row,col);
pixV = (BYTE)cvGetReal2D(v_plane,row,col);
binH = (int)(RBINS*pixH/256);
binS = (int)(GBINS*pixS/256);
binV = (int)(BBINS*pixV/256);
pix = cvGetHistValue_3D(outHist,binH,binS,binV);
(*pix)++;
}
}
cvReleaseImage( &h_plane);
cvReleaseImage( &s_plane);
cvReleaseImage( &v_plane);
}
/******************************************************************************/
void his_CalcGravityCenter2(IplImage* inImg, RECT blobBox, POINT *outCenter)
//get blob weight center
{
int row, col;
int border = 10;
BYTE pixel;
float sumRow, sumCol, sumPix;
POINT center;
int dx, dy;
//get outer ring box
center.x = (blobBox.left+blobBox.right)/2;
center.y = (blobBox.top+blobBox.bottom)/2;
sumRow = 0;
sumCol = 0;
sumPix = 0;
for (col=blobBox.left; col<blobBox.right; col++){
for (row=blobBox.top; row<blobBox.bottom; row++){
pixel = (BYTE)cvGetReal2D(inImg,row,col);
sumCol = sumCol + pixel*(col-center.x);
sumRow = sumRow + pixel*(row-center.y);
sumPix = sumPix + pixel;
}
}
dx = (int)fn_Round(sumCol/sumPix);
dy = (int)fn_Round(sumRow/sumPix);
//get weight center
outCenter->x = center.x + dx;
outCenter->y = center.y + dy;
}
/******************************************************************************/
void his_CalcGravityCenter(IplImage* inImg, POINT *outCenter)
//get blob weight center by moments
{
CvMoments moments;
cvMoments(inImg, &moments, 0);
outCenter->x = (int)fn_Round(moments.m10/moments.m00);
outCenter->y = (int)fn_Round(moments.m01/moments.m00);
}
///////////////////////////////////////////////////////////////////////////////
void his_BlobCenterShift(IplImage* inImg, RECT *inRect, int range)
//shift to track blob center movement
{
RECT shiftBox;
int row, col;
BYTE pixel;
float sumRow, sumCol, sumPix;
POINT center, inCenter;
//int halfWidth, halfHeight;
int dx, dy;
int loopCount;
//get outer ring box
shiftBox.left = inRect->left;
shiftBox.right = inRect->right;
shiftBox.top = inRect->top;
shiftBox.bottom = inRect->bottom;
his_CheckBoxBound(&shiftBox, inImg->width, inImg->height);
inCenter.x = (shiftBox.left+shiftBox.right)/2; //input Rect center
inCenter.y = (shiftBox.top+shiftBox.bottom)/2;
center.x = inCenter.x; //shift center
center.y = inCenter.y;
loopCount=0;
dx=1;
dy=1;
while (abs(dx)+abs(dy)>=1 && loopCount<10){
sumRow = 0;
sumCol = 0;
sumPix = 0;
for (col=shiftBox.left; col<shiftBox.right; col++){
for (row=shiftBox.top; row<shiftBox.bottom; row++){
pixel = (BYTE)cvGetReal2D(gImgBackProj,row,col);
sumCol = sumCol + pixel*(col-center.x);
sumRow = sumRow + pixel*(row-center.y);
sumPix = sumPix + pixel;
}
}
dx = (int)fn_Round(sumCol/sumPix);
dy = (int)fn_Round(sumRow/sumPix);
//move track box
shiftBox.left = shiftBox.left + dx;
shiftBox.right = shiftBox.right + dx;
shiftBox.top = shiftBox.top + dy;
shiftBox.bottom = shiftBox.bottom + dy;
his_CheckBoxBound(&shiftBox, inImg->width, inImg->height);
center.x = (shiftBox.left+shiftBox.right)/2;
center.y = (shiftBox.top+shiftBox.bottom)/2;
loopCount++;
}
//output shift result
dx = center.x - inCenter.x;
dy = center.y - inCenter.y;
if (dx<-range) dx = -range;
if (dx>range) dx = range;
if (dy<-range) dy = -range;
if (dy>range) dy = range;
inRect->left = inRect->left + dx;
inRect->right = inRect->right + dx;
inRect->top = inRect->top + dy;
inRect->bottom = inRect->bottom + dy;
}
///////////////////////////////////////////////////////////////////////////////
void his_TrackInit_Bins(IplImage *inImg, IplImage *inMask, RECT inRect, int nbins1, int nbins2, int nbins3)
//tracker init with RGB bins parameters
{
//set histogram bins
RBINS = nbins1;
GBINS = nbins2;
BBINS = nbins3;
//init tracker
his_TrackInit(inImg, inMask, inRect);
}
///////////////////////////////////////////////////////////////////////////////
void his_TrackInit(IplImage *inImg, IplImage *inMask, RECT inRect)
//tracker init with mask image
{
//histogram variable
float h_ranges[] = { 0, 255}; /* hue varies from 0 (~0皉ed) to 180 (~360皉ed again) */
float s_ranges[] = { 0, 255}; /* saturation varies from 0 (black-gray-white) to 255 (pure spectrum color) */
float v_ranges[] = { 0, 255};
int hist_size[] = {RBINS, GBINS, BBINS};
float max_value = 0;
float* ranges[] = { h_ranges, s_ranges, v_ranges};
int row, col;
BYTE pixR, pixG, pixB;
float *pix;
int binR, binG, binB;
BOOL bResult =0;
BYTE maskPix;
CvScalar pixel;
//check whether input is valid
if (inImg==NULL) return;
utl_RectCheckBound(&inRect, inImg->width, inImg->height);
//release memeory in case re-initialize
his_TrackCleanUp();
gHistInit = cvCreateHist(3, hist_size, CV_HIST_ARRAY, ranges, 1 );
gHistModel = cvCreateHist(3, hist_size, CV_HIST_ARRAY, ranges, 1 );
//create histogram
gImgBackProj = cvCreateImage(cvGetSize(inImg), 8, 1);
//clear histogram array
cvClearHist(gHistInit);
//count index image
gMaskPixCount = 0;
for (row=inRect.top;row<=inRect.bottom;row++){
for (col=inRect.left; col<=inRect.right; col++){
//bResult = PtInRegion(hRegion, col, row);
maskPix = (BYTE)cvGetReal2D(inMask, row, col);
if (maskPix>0){
gMaskPixCount++;
//calculate histogram
pixel = cvGet2D(inImg, row, col);
pixR = (BYTE)pixel.val[0];
pixG = (BYTE)pixel.val[1];
pixB = (BYTE)pixel.val[2];
binR = (int)(RBINS*pixR/256);
binG = (int)(GBINS*pixG/256);
binB = (int)(BBINS*pixB/256);
pix = cvGetHistValue_3D(gHistInit,binR,binG,binB);
(*pix)++;
}
}
}
gMaskFgRatio = (float)gMaskPixCount/((inRect.right-inRect.left)*(inRect.bottom-inRect.top));
//get outer box histogram
cvClearHist(gHistModel);
{
//outer ring Box
RECT outerBox;
//get outer ring box
outerBox.left = inRect.left-gBorder;
outerBox.right = inRect.right+gBorder;
outerBox.top = inRect.top-gBorder;
outerBox.bottom = inRect.bottom +gBorder;
his_CheckBoxBound(&outerBox, inImg->width, inImg->height);
//count index image
for (row=outerBox.top;row<=outerBox.bottom;row++){
for (col=outerBox.left; col<=outerBox.right; col++){
//calculate histogram
pixel = cvGet2D(inImg, row, col);
pixR = (BYTE)pixel.val[0];
pixG = (BYTE)pixel.val[1];
pixB = (BYTE)pixel.val[2];
binR = (int)(RBINS*pixR/256);
binG = (int)(GBINS*pixG/256);
binB = (int)(BBINS*pixB/256);
pix = cvGetHistValue_3D(gHistModel,binR,binG,binB);
(*pix)++;
}
}
}
//get back project image
{
CvRect trackRect;
//ratio histogram
//gHistRatio = his_HistogramRatio(gHistInit, gHistModel);
gHistRatio = his_HistogramDivide(gHistInit, gHistModel);
//debug - print out rst
// {
// _chdir(gExePath);
// his_PrintHistogram(gHistInit, "result/gHistInit.txt");
// his_PrintHistogram(gHistModel, "result/gHistModel.txt");
// his_PrintHistogram(gHistRatio, "result/gHistRatio.txt");
// }
//get foreground
trackRect.x = inRect.left;
trackRect.y = inRect.top;
trackRect.width = inRect.right - inRect.left;
trackRect.height = inRect.bottom - inRect.top;
his_CalcForeground2(inImg, gHistRatio, trackRect, gImgBackProj);
//get the foreground gravity center
//his_CalcGravityCenter(gImgBackProj, &gGravityCenter);
//release memory
cvReleaseHist(&gHistRatio);
}
}
///////////////////////////////////////////////////////////////////////////////
void his_TrackNextFrame(IplImage* inImg, RECT inRect, TkResult *outResult)
//move gravity center by histogram ratio
{
CvRect trackRect;
RECT outerBox;
float score=1;
//int countPix;
//check whether input is valid
if (inImg==NULL) return;
utl_RectCheckBound(&inRect, inImg->width, inImg->height);
trackRect.x = inRect.left;
trackRect.y = inRect.top;
trackRect.width = inRect.right - inRect.left;
trackRect.height = inRect.bottom - inRect.top;
//get outer ring box
outerBox.left = inRect.left-gBorder;
outerBox.right = inRect.right+gBorder;
outerBox.top = inRect.top-gBorder;
outerBox.bottom = inRect.bottom +gBorder;
his_CheckBoxBound(&outerBox, inImg->width, inImg->height);
//get histogram Model of outerBox
his_CountBoxHistogram(inImg, outerBox, gHistModel);
//get Histogram Ratio
gHistRatio = his_HistogramRatio(gHistInit, gHistModel);
gHistDivide = his_HistogramDivide(gHistInit, gHistModel);
//normalize histogram
//cvThreshHist(gHistRatio, 60);
//his_HistogramNormalize(gHistRatio);
//get back projection image based on ratio histogram
his_CalcForeground2(inImg, gHistDivide, trackRect, gImgBackProj);
//find blobCenter
his_BlobCenterShift(gImgBackProj, &inRect, 15);
//calculate tracking score
score = his_CountFGPixel(gImgBackProj, inRect);
//update foreground image for display purpose
his_CalcForeground2(inImg, gHistRatio, trackRect, gImgBackProj);
outResult->targetBox = inRect;
outResult->FGImage = gImgBackProj;
outResult->score = score;
outResult->occlusion = (score<0.5? TRUE:FALSE);
//clear histogram
cvReleaseHist(&gHistRatio);
cvReleaseHist(&gHistDivide);
}
///////////////////////////////////////////////////////////////////////////////
float his_CountFGPixel(IplImage *inImg, RECT inRect)
//cout foreground pixel number to find score
{
int pixCount;
float score;
CvRect crectRoi;
//count foreground points
crectRoi.x = inRect.left;
crectRoi.y = inRect.top;
crectRoi.width = inRect.right - inRect.left;
crectRoi.height = inRect.bottom - inRect.top;
cvSetImageROI(inImg, crectRoi);
pixCount = cvCountNonZero(inImg);
inImg->roi = NULL;
score = (float)pixCount/(crectRoi.width*crectRoi.height);
//score = (float)pixCount/gMaskPixCount;
score = score/gMaskFgRatio;
score = min(1, score);
return score;
}
///////////////////////////////////////////////////////////////////////////////
void his_TrackCleanUp()
//release memory
{
//clear histogram
cvReleaseHist(&gHistInit);
cvReleaseHist(&gHistModel);
cvReleaseHist(&gHistRatio);
cvReleaseHist(&gHistDivide);
//projection image
cvReleaseImage(&gImgBackProj);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -