📄 main.c
字号:
gRectCurrent.bottom = gaClickPoint[2].y;
dis_ShowImgCurrent();
return 2;
}
//Read next frame from file
iio_ReadFileByIndex(nextFrameNo);
//if no new frame, return
if (gcImgCurrent==iio_GetInputImage() || iio_GetInputImage()==NULL){
giPlayFlag=0;
return 0;
}
//update image sequence info.
gcImgCurrent = iio_GetInputImage();
cvResize(gcImgCurrent, gcImgCurrentHalf, CV_INTER_LINEAR);
//if not in initialized, return
if (gbClickInitFlag==FALSE || gbTrackMood==FALSE){
//display current image and rect
dis_ShowImgCurrent();
return 0;
}
//klt tracker
if (gbKltFlag==TRUE){
klt_TrackNextFrame(gcImgCurrentHalf, gAffineMatrix);
//get zoom scale factor from affine matrix
zoom = (float)sqrt(fn_Abs(gAffineMatrix[0]*gAffineMatrix[4] - gAffineMatrix[1]*gAffineMatrix[3]));
//if zoom scale is not 1 (different above threshold), accumulate zoom change.
if (fabs(zoom-1)>0.002){
gZoomAccum = gZoomAccum*zoom;
}
//change size if not in predict mood
if (gbPredictFlag==FALSE)
{
//change rect size based on scale factor accumulation
gBlobWidth = (int)fn_Round(gBlobWidthInit * gZoomAccum);
gBlobHeight = (int)fn_Round(gBlobHeightInit * gZoomAccum);
//adjust the current Blob size
utl_RectSizeAdjust(&gRectCurrentHalf, gBlobWidth, gBlobHeight, ImageMaxX/2, ImageMaxY/2);
}
}
else{
for (i=0;i<6;i++){
gAffineMatrix[i] = 0;
}
}
//runing tracker on this frame
switch(gTrackerIndex) {
case 1:
//HistogramShift - Enhanced meanshift by Foreground/Bkground
his_TrackNextFrame(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 2:
//Meanshift tracker
msw_TrackNextFrame(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 3:
//template matching tracker with Correlation
temp_TrackNextFrame_Coeff(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 4:
//feature shift
feat_TrackNextFrame(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 5:
//feature shift adaptive
feat_TrackNextFrame_Adapt(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 6:
//Peak Diff feature shift adaptive
feat_TrackNextFrame_PeakDiff(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 7:
//Peak Diff feature shift adaptive
feat_TrackNextFrame_PeakDiff_Adapt(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 8:
//GraphCut Tracker
graph_TrackNextFrame(gcImgCurrentHalf, gRectCurrentHalf, &gTkResult);
break;
case 9:
//particle filter tracker
particle_TrackNextFrame(gcImgCurrent, gRectCurrent, &gTkResult);
break;
//default:
}
gRectCurrentHalf = gTkResult.targetBox;
utl_RectCheckBound(&gRectCurrentHalf, ImageMaxX/2, ImageMaxY/2);
//get foreground image/bitmap for report purpose
//imgForeground = gTkResult.FGImage;
imgForeground = gTkResult.FGMask;
cvSetZero(gImgBitMap);
//cvResize(imgForeground, gImgBitMap, CV_INTER_LINEAR);
if (imgForeground != NULL){
cvResize(imgForeground, gImgBitMap, CV_INTER_NN);
}
//if occluded, predict motion
gTrackCount++;
if (gbAutoPredictFlag==TRUE){
if (gbPredictFlag==FALSE && gTkResult.occlusion==TRUE && gTrackCount>=3){
gTrackCount = 0;
gbPredictFlag=TRUE;
}
else if(gbPredictFlag==TRUE && gTkResult.occlusion==FALSE && gTrackCount>=3){
gTrackCount = 0;
gbPredictFlag=FALSE;
}
}
//predict motion on current frame
if(gbKltFlag==TRUE){
//update the Blob Position array to current camera coordinate, and shift one position in array
for (i=POSNUM-1;i>0;i--){
//affine transform
gPosPredict[i].x = 2*klt_CalcAffineX(gPosPredict[i-1].x/2, gPosPredict[i-1].y/2);
gPosPredict[i].y = 2*klt_CalcAffineY(gPosPredict[i-1].x/2, gPosPredict[i-1].y/2);
utl_PixelCheckBound_Float(&gPosPredict[i].x, &gPosPredict[i].y, ImageMaxX, ImageMaxY);
}
//get effective position count
gPosCount = min(gPosCount++, POSNUM);
//predict the blob position and get gAvgDx, gAvgDy;
predictReady = img_PredictMotion();
}
//shift the blob based on prediction if flag is on
if (gbPredictFlag==TRUE && predictReady==1)
{
//Since recent frames are occluded, rePredict position in gPosPredict[0]-[4] based on 5 frames earlier
for(i=gIgnoreFrameNum-1;i>=0;i--){
gPosPredict[i].x = gPosPredict[gIgnoreFrameNum].x+ gAvgDx*(gIgnoreFrameNum-i);
gPosPredict[i].y = gPosPredict[gIgnoreFrameNum].y+ gAvgDy*(gIgnoreFrameNum-i);
utl_PixelCheckBound_Float(&gPosPredict[i].x, &gPosPredict[i].y, ImageMaxX, ImageMaxY);
}
//reset target rect based on prediction
gRectCurrentHalf.left = (long)fn_Round(gPosPredict[0].x/2 - gBlobWidth/2);
gRectCurrentHalf.right = (long)fn_Round(gPosPredict[0].x/2 + gBlobWidth/2);
gRectCurrentHalf.top = (long)fn_Round(gPosPredict[0].y/2 - gBlobHeight/2);
gRectCurrentHalf.bottom = (long)fn_Round(gPosPredict[0].y/2 + gBlobHeight/2);
utl_RectCheckBound(&gRectCurrentHalf, ImageMaxX/2, ImageMaxY/2);
}
else{
//merge predict position with actual tracked position
gPosPredict[0].x = (float)gRectCurrentHalf.left+gRectCurrentHalf.right;
gPosPredict[0].y = (float)gRectCurrentHalf.top+gRectCurrentHalf.bottom;
}
//update full size RECT for display and Log report purpose
gRectCurrent.left = gRectCurrentHalf.left*2;
gRectCurrent.top = gRectCurrentHalf.top*2;
gRectCurrent.right = gRectCurrentHalf.right*2;
gRectCurrent.bottom = gRectCurrentHalf.bottom*2;
//print track report
if (gbLogFlag == TRUE){
tReport.time = iio_GetFrameNo();
tReport.framePath = iio_GetFilePath();
tReport.boxX = gRectCurrent.left;
tReport.boxY = ImageMaxY-1 - gRectCurrent.bottom;
tReport.boxWid = abs(gRectCurrent.right - gRectCurrent.left+1);
tReport.boxHgt = abs(gRectCurrent.bottom - gRectCurrent.top+1);
tReport.imgWidth = ImageMaxX;
tReport.imgHeight = ImageMaxY;
switch(gLogVersion) {
case 1:
//CMU version 1
io_PrintReport();
break;
case 2:
//CID version 0.9
io_PrintReport_CID09();
break;
case 3:
//CID version 1.0
io_PrintReport_CID10();
break;
case 4:
//CMU version 2.0
io_PrintReport_V20();
break;
case 5:
//CMU version 2.1
io_PrintReport_V21();
break;
}
}
//flip the points for draw purpose on screen window
for (i=0;i<gPosCount;i++){
gPosDraw[i].x = (long)gPosPredict[i].x;
gPosDraw[i].y = ImageMaxY-1 + ButtonHeight - (long)gPosPredict[i].y;
}
//display current image and rect
dis_ShowImgCurrent();
return 1;
}
///////////////////////////////////////////////////////////////////////////////
void AppSetDisplay()
//set display window and related parameters based on ImageMaxX/ImageMaxY
{
int left;
int top;
int screenx = GetSystemMetrics(SM_CXSCREEN);
int screeny = GetSystemMetrics(SM_CYSCREEN);
ReleaseBuffer();
SetBitMapHead();
AllocBuffer();
GetGlobals(hwndCtl,0);
MoveWindow(hwndCtl,0,0,WindowX,WindowY,1);
//MoveWindow(hwndCtl,screenx-WindowX,screeny-35-WindowY,WindowX,WindowY,1);
InvalidateRect(hwndCtl, NULL, TRUE);
DrawButtons(hwndCtl, 0, FALSE); //resize buttons
//debug windows
left = min(WindowX,screenx-WindowX);
top = (left>=WindowX-20?0:min(WindowY, screeny-30-WindowY));
left = max(left,0);
top = max(top,0);
MoveWindow(hwndCtl2,left,top,WindowX,WindowY,TRUE);
//MoveWindow(hwndCtl2,0,0,WindowX,WindowY,TRUE);
InvalidateRect(hwndCtl2, NULL, TRUE);
DrawButtons2(hwndCtl2, 0, FALSE); //resize buttons
SetActiveWindow(hwndCtl);
}
///////////////////////////////////////////////////////////////////////////////
void dis_ShowImgCurrent()
//copy current image into main window buffer
{
//if batch mood, return
//if (gBatchFlag==TRUE) return;
//if no image, return
if (gcImgCurrent==NULL) return;
cvCopy(gcImgCurrent, gImgDisplayMain, NULL);
//paint image
AppPaint(hwndCtl, GetDC(hwndCtl));
AppPaint2(hwndCtl2, GetDC(hwndCtl2));
//display debug image
dis_ShowImgDebug();
//print title
dis_PrintMessage();
}
///////////////////////////////////////////////////////////////////////////////
void dis_ShowImgDebug()
//copy current image into main window buffer
{
CvRect roi;
IplImage* imgDisplay;
//if replay, no debug display
if (gbReplayFlag==TRUE) return;
memset(gpBits2, 0, ImageMaxX*ImageMaxY*3);
//display particles for particle filter
if (gTrackerIndex==9) {
imgDisplay = particle_GetParticleImg();
if (imgDisplay!=NULL){
cvCopy(imgDisplay, gImgDisplayDebug, NULL);
}
return;
}
//display half image
if (gbClickInitFlag==TRUE && gcImgCurrentHalf!=NULL){
roi.x = 0;
roi.y = ImageMaxY/2;
roi.width = gcImgCurrentHalf->width;
roi.height = gcImgCurrentHalf->height;
cvSetImageROI(gImgDisplayDebug, roi);
cvCopy(gcImgCurrentHalf, gImgDisplayDebug, NULL);
cvResetImageROI(gImgDisplayDebug);
}
//display klt features image
if (gbKltFlag==TRUE)
{
IplImage *imgFeature = klt_GetFeatureImage();
if (gbClickInitFlag==TRUE && gbTrackMood==TRUE && imgFeature!=NULL){
roi.x = ImageMaxX/2;
roi.y = ImageMaxY/2;
roi.width = gcImgCurrentHalf->width;
roi.height = gcImgCurrentHalf->height;
cvSetImageROI(gImgDisplayDebug, roi);
cvCopy(imgFeature, gImgDisplayDebug, NULL);
cvResetImageROI(gImgDisplayDebug);
}
}
//display foreground image
{
IplImage *imgForeground = gTkResult.FGImage;
//if (gbClickInitFlag==TRUE && gbTrackMood==TRUE && imgForeground!=NULL){
if (gbClickInitFlag==TRUE && imgForeground!=NULL){
roi.x = 0;
roi.y = 0;
roi.width = gcImgCurrentHalf->width;
roi.height = gcImgCurrentHalf->height;
cvSetImageROI(gImgDisplayDebug, roi);
cvSetImageCOI(gImgDisplayDebug, 2);
cvCopy(imgForeground, gImgDisplayDebug, NULL);
cvSetImageCOI(gImgDisplayDebug, 0);
cvResetImageROI(gImgDisplayDebug);
}
}
//display obj mask image
{
//IplImage *imgObjMask = gTkResult.ObjMask;//objMask is 3 channels
IplImage *imgObjMask = gTkResult.FGMask; //Fgmask is 1 channel
//if (gbClickInitFlag==TRUE && gbTrackMood==TRUE && imgForeground!=NULL){
if (gbClickInitFlag==TRUE && imgObjMask!=NULL){
roi.x = ImageMaxX/2;
roi.y = 0;
roi.width = gcImgCurrentHalf->width;
roi.height = gcImgCurrentHalf->height;
cvSetImageROI(gImgDisplayDebug, roi);
//cvCopy(imgObjMask, gImgDisplayDebug, NULL);
cvSetImageCOI(gImgDisplayDebug, 1);
cvCopy(imgObjMask, gImgDisplayDebug, NULL);
cvSetImageCOI(gImgDisplayDebug, 2);
cvCopy(imgObjMask, gImgDisplayDebug, NULL);
cvSetImageCOI(gImgDisplayDebug, 3);
cvCopy(imgObjMask, gImgDisplayDebug, NULL);
cvSetImageCOI(gImgDisplayDebug, 0);
cvResetImageROI(gImgDisplayDebug);
}
}
//paint image
AppPaint2(hwndCtl2, GetDC(hwndCtl2));
}
///////////////////////////////////////////////////////////////////////////////
void dis_DrawRect(HWND hwnd, RECT rect)
//display current rect in main window
{
HDC hdc;
// LOGBRUSH lb;
HPEN hPen, hPenOld;
//display rect track window
if (gbClickInitFlag==FALSE) return;
hdc = GetDC(hwnd);
// // Initialize the pen's brush.
// lb.lbStyle = BS_SOLID;
// lb.lbColor = RGB(255,0,0);
// lb.lbHatch = 0;
// define new pen
//hPen = ExtCreatePen(PS_COSMETIC | PS_SOLID, 1, &lb, 0, NULL);
hPen = CreatePen(PS_SOLID, giPenWidth, crPenColor);
hPenOld = SelectObject(hdc, hPen);
//flip back rect for display purpose
rect.top = ImageMaxY + ButtonHeight - rect.top;
rect.bottom = ImageMaxY + ButtonHeight - rect.bottom;
//if the rect buttom is in Button Area, ignore it.
if(rect.bottom<=ButtonHeight) rect.bottom = ButtonHeight+1;
//draw rect
MoveToEx(hdc, rect.left, rect.top, NULL);
LineTo(hdc, rect.right, rect.top);
LineTo(hdc, rect.right, rect.bottom);
LineTo(hdc, rect.left, rect.bottom);
LineTo(hdc, rect.left, rect.top);
//recover old pen
SelectObject(hdc, hPenOld);
DeleteObject(hPen);
//release Device Context
ReleaseDC(hwnd, hdc);
}
///////////////////////////////////////////////////////////////////////////////
void dis_DrawTraceLine(HWND hwnd, FPOINT* pts, int ptCount, int penStyle, int penWidth, COLORREF penColor)
//display current rect in main window
{
HDC hdc;
// LOGBRUSH lb;
HPEN hPen, hPenOld;
int i;
POINT predictPt;
int frameNum=(int)(gEffectNum*0.6); //predict ahead number of frames;
//display rect track window
if (gbClickInitFlag==FALSE) return;
hdc = GetDC(hwnd);
// define new pen
//hPen = ExtCreatePen(PS_COSMETIC | PS_SOLID, 1, &lb, 0, NULL);
hPen = CreatePen(penStyle, penWidth, penColor);
hPenOld = SelectObject(hdc, hPen);
//draw history line in red
MoveToEx(hdc, gPosDraw[0].x, gPosDraw[0].y, NULL);
for (i=1;i<ptCount;i++){
LineTo(hdc, gPosDraw[i].x, gPosDraw[i].y);
}
if (gbPredictFlag==TRUE)
{
//display predict mood
RECT promptArea;
promptArea.left = 30;
promptArea.top = ButtonHeight+20;
promptArea.right = promptArea.left + 100;
promptArea.bottom = promptArea.top + 100;
DrawText(hdc, "Predict Motion", 14, &promptArea, DT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -