您的位置:首页 > 编程语言 > C语言/C++

全局Haar-Like特征图像识别的C++实现

2006-06-29 19:29 316 查看
cvdirectcascade.h:


#include "cv.h"




struct TWeakClassifier




...{


CvRect Rectangles[2];


};




struct PtrWeakClassifier




...{


long *tl0, *tr0, *bl0, *br0;


long *tl1, *tr1, *bl1, *br1;


int offset, size0, size1;


int Threshold;


};




struct ListObjectType




...{


int x, y, width, height;


int w;


bool use;


ListObjectType *next;


};




struct TLearnedObject




...{


TWeakClassifier *Classifiers;


PtrWeakClassifier *ScaleClassifiers;


int ObjectWidth, ObjectHeight;


int NClassifiers;


};




struct TDetectSettings




...{


double ScaleRatio, OffsetX, OffsetY;


int Ignore, MinW;


int StartSubWindow, EndSubWindow;


};




bool LoadDefaultSetting(char *FileName, TDetectSettings &DS);


void LearnClassifiers(unsigned char *IptImage, TLearnedObject &target, int IptWidth, int IptHeight);


int DetectObject(TLearnedObject &target, unsigned char *FrameImage, int Width, int Height, TDetectSettings &DS, CvRect *&Objects);

cvdirectcascade.cpp:


#include <iostream.h>


#include <stdio.h>


#include <math.h>


#include <string.h>


#include <ctype.h>


#include <stdlib.h>




#include "cv.h"


#include "cvdirectcascade.h"




bool Overlapped(ListObjectType *obj1, ListObjectType *obj2)




...{


int cx = obj1->x + obj1->width / 2;


int cy = obj1->y + obj1->height / 2;


if ((cx > obj2->x) && (cx < obj2->x + obj2->width) && (cy > obj2->y) && (cy < obj2->y + obj2->height))


return true;


cx = obj2->x + obj2->width / 2;


cy = obj2->y + obj2->height / 2;


if ((cx > obj1->x) && (cx < obj1->x + obj1->width) && (cy > obj1->y) && (cy < obj1->y + obj1->height))


return true;


return false;


}




void RestoreImage(unsigned char *IptImage, long *&IntegralImage, int IptWidth, int IptHeight)




...{


IntegralImage = new long [(IptWidth + 1) * (IptHeight + 1)];




long *pic = IntegralImage;


for (int i = 0; i < IptWidth + 1; i++)




...{


*pic = 0; pic++;


}


for (int j = 0; j < IptHeight; j++)




...{


*pic = 0; pic+=IptWidth + 1;


}




unsigned char *pc = IptImage;


long *picx, *picy, *picxy;


picxy = IntegralImage;


pic = picxy + IptWidth + 2;


picx = picxy + IptWidth + 1;


picy = picxy + 1;


for (i = 0; i < IptHeight; i++)




...{


for (j = 0; j < IptWidth; j++)




...{


*pic = *pc + *picx + *picy - *picxy;


pic++; picx++; picy++; picxy++;


pc++;


}


pic++; picx++; picy++; picxy++;


}


}




int CalculateXBoundary(unsigned char *IptImage, int IptWidth, int IptHeight, int x, int y, int width, int height)




...{


int T, NewT = width / 2, C1 = 0, C2 = 0, D1 = 0, D2 = 0;


unsigned char *ptr, *oldptr;


oldptr = IptImage + IptWidth * y + x;


int step = IptWidth - width;




do...{


T = NewT;


C1 = 0; C2 = 0; D1 = 0; D2 = 0;


ptr = oldptr;


for (int j = y; j < y + height; j++)




...{


for (int i = x; i < x + T; i++)




...{


C1 += (i - x) * *ptr;


D1 += *ptr;


ptr++;


}


for (i = x + T; i < x + width; i++)




...{


C2 += (i - x) * *ptr;


D2 += *ptr;


ptr++;


}


ptr+=step;


}


C1 = C1 / D1; C2 = C2 / D2;


NewT = (C1 + C2) / 2;


}while (NewT != T);


return T;


}




int CalculateYBoundary(unsigned char *IptImage, int IptWidth, int IptHeight, int x, int y, int width, int height)




...{


int T, NewT = height / 2, C1 = 0, C2 = 0, D1 = 0, D2 = 0;


unsigned char *ptr, *oldptr;


oldptr = IptImage + IptWidth * y + x;


int step = IptWidth - width;




do...{


T = NewT;


C1 = 0; C2 = 0; D1 = 0; D2 = 0;


ptr = oldptr;


for (int j = y; j < y + T; j++)




...{


for (int i = x; i < x + width; i++)




...{


C1 += (j - y) * *ptr;


D1 += *ptr;


ptr++;


}


ptr+=step;


}


for (j = y + T; j < y + height; j++)




...{


for (int i = x; i < x + width; i++)




...{


C2 += (j - y) * *ptr;


D2 += *ptr;


ptr++;


}


ptr+=step;


}


C1 = C1 / D1; C2 = C2 / D2;


NewT = (C1 + C2) / 2;


}while (NewT != T);


return T;


}




void LearnClassifiers(unsigned char *IptImage, TLearnedObject &target, int IptWidth, int IptHeight)




...{


long *IntegralImage = NULL;




target.ObjectWidth = IptWidth; target.ObjectHeight = IptHeight;


RestoreImage(IptImage, IntegralImage, IptWidth, IptHeight);


CvRect *close, *open, *record;




record = new CvRect [target.NClassifiers * 2];




TWeakClassifier *cptr;


cptr = target.Classifiers; int NowClassifiers = 0;


close = record; open = record;


record->x = 0; record->y = 0;


record->width = IptWidth; record->height = IptHeight;




do...{


int T;


if (close->width > 1)




...{


T = CalculateXBoundary(IptImage, IptWidth, IptHeight, close->x, close->y, close->width, close->height);


if ((T > 0) && (T < close->width))




...{


cptr->Rectangles[0].x = close->x;


cptr->Rectangles[0].y = close->y;


cptr->Rectangles[0].width = T;


cptr->Rectangles[0].height = close->height;


cptr->Rectangles[1].x = close->x + T;


cptr->Rectangles[1].y = close->y;


cptr->Rectangles[1].width = close->width - T;


cptr->Rectangles[1].height = close->height;


NowClassifiers++; cptr++;


if (NowClassifiers >= target.NClassifiers) break;


open++;


open->x = close->x; open->y = close->y;


open->width = T; open->height = close->height;


open++;


open->x = close->x + T; open->y = close->y;


open->width = close->width - T; open->height = close->height;


}


}


if (close->height > 1)




...{


T = CalculateYBoundary(IptImage, IptWidth, IptHeight, close->x, close->y, close->width, close->height);


if ((T > 0) && (T < close->height))




...{


cptr->Rectangles[0].x = close->x;


cptr->Rectangles[0].y = close->y;


cptr->Rectangles[0].width = close->width;


cptr->Rectangles[0].height = T;


cptr->Rectangles[1].x = close->x;


cptr->Rectangles[1].y = close->y + T;


cptr->Rectangles[1].width = close->width;


cptr->Rectangles[1].height = close->height - T;


NowClassifiers++; cptr++;


if (NowClassifiers >= target.NClassifiers) break;


open++;


open->x = close->x; open->y = close->y;


open->width = close->width; open->height = T;


open++;


open->x = close->x; open->y = close->y + T;


open->width = close->width; open->height = close->height - T;


}


}


close++;


}while (close <= open);


delete [] record;




cptr = target.Classifiers;


PtrWeakClassifier *scptr;


scptr = target.ScaleClassifiers;


for (int i = 0; i < target.NClassifiers; i++)




...{


scptr->tl0 = IntegralImage + cptr->Rectangles[0].y * (IptWidth + 1) + cptr->Rectangles[0].x;


scptr->tr0 = scptr->tl0 + cptr->Rectangles[0].width;


scptr->bl0 = IntegralImage + (cptr->Rectangles[0].y + cptr->Rectangles[0].height) * (IptWidth + 1) + cptr->Rectangles[0].x;


scptr->br0 = scptr->bl0 + cptr->Rectangles[0].width;


scptr->size0 =cptr->Rectangles[0].width * cptr->Rectangles[0].height;


scptr->tl1 = IntegralImage + cptr->Rectangles[1].y * (IptWidth + 1) + cptr->Rectangles[1].x;


scptr->tr1 = scptr->tl1 + cptr->Rectangles[1].width;


scptr->bl1 = IntegralImage + (cptr->Rectangles[1].y + cptr->Rectangles[1].height) * (IptWidth + 1) + cptr->Rectangles[1].x;


scptr->br1 = scptr->bl1 + cptr->Rectangles[1].width;


scptr->size1 =cptr->Rectangles[1].width * cptr->Rectangles[1].height;


int gray = (*(scptr->br0) - *(scptr->bl0) - *(scptr->tr0) + *(scptr->tl0)) / scptr->size0;


gray -= (*(scptr->br1) - *(scptr->bl1) - *(scptr->tr1) + *(scptr->tl1)) / scptr->size1;


scptr->Threshold = gray;


scptr++; cptr++;


}




delete [] IntegralImage;


}




int DetectObject(TLearnedObject &target, unsigned char *FrameImage, int Width, int Height, TDetectSettings &DS, CvRect *&Objects)




...{


long *IntegralImage = NULL;


RestoreImage(FrameImage, IntegralImage, Width, Height);




bool smallenough = false;


int ObjectWindow;


if (target.ObjectWidth > target.ObjectHeight) ObjectWindow = target.ObjectWidth; else ObjectWindow = target.ObjectHeight;


double scale = (double)DS.StartSubWindow / (double)ObjectWindow;


double scale_ = 1 / scale, newscalex = scale * DS.OffsetX, newscaley = scale * DS.OffsetY;


int NewWidth = (int)(Width * scale_), NewHeight = (int)(Height * scale_);


int NOWidth = (int)(target.ObjectWidth * scale), NOHeight = (int)(target.ObjectHeight * scale);


int EndWidth, EndHeight;


//size definement


ListObjectType *ListObjects;


ListObjects = new ListObjectType;


ListObjectType *objptr, *oldptr;


objptr = ListObjects;


int ListCount = 0, Count = 0;


//object list


TWeakClassifier *cptr = NULL, *ocptr = target.Classifiers;


PtrWeakClassifier *scptr = NULL, *oscptr = target.ScaleClassifiers;


int Nc = target.NClassifiers;


int Ignore = DS.Ignore, MinW = DS.MinW;


//scaling && detecting




do...{


int x, y, swidth, sheight;


cptr = ocptr; scptr = oscptr;


for (int i = 0; i < Nc; i++)




...{


x = (int)(cptr->Rectangles[0].x * scale);


y = (int)(cptr->Rectangles[0].y * scale);


swidth = (int)(cptr->Rectangles[0].width * scale);


sheight = (int)(cptr->Rectangles[0].height * scale);


scptr->tl0 = IntegralImage + x + y * (Width + 1);


scptr->tr0 = scptr->tl0 + swidth;


scptr->bl0 = IntegralImage + x + (y + sheight) * (Width + 1);


scptr->br0 = scptr->bl0 + swidth;


scptr->size0 = sheight * swidth;


x = (int)(cptr->Rectangles[1].x * scale);


y = (int)(cptr->Rectangles[1].y * scale);


swidth = (int)(cptr->Rectangles[1].width * scale);


sheight = (int)(cptr->Rectangles[1].height * scale);


scptr->tl1 = IntegralImage + x + y * (Width + 1);


scptr->tr1 = scptr->tl1 + swidth;


scptr->bl1 = IntegralImage + x + (y + sheight) * (Width + 1);


scptr->br1 = scptr->bl1 + swidth;


scptr->size1 = sheight * swidth;


scptr->offset = 0;


scptr++; cptr++;


}


int oldy = 0, diffx = 0, diffy = 0;


double InvWindowArea = 1 / (double)(NOWidth * NOHeight);


if (scale < 1)




...{


EndWidth = (int)((Width - NOWidth) / DS.OffsetX);


EndHeight = (int)((Height - NOHeight) / DS.OffsetY);


newscalex = DS.OffsetX; newscaley = DS.OffsetY;


}


else




...{


EndWidth = (int)((NewWidth - target.ObjectWidth) / DS.OffsetX);


EndHeight = (int)((NewHeight - target.ObjectHeight) / DS.OffsetY);


newscalex = scale * DS.OffsetX; newscaley = scale * DS.OffsetY;


}


for (i = 0; i < EndHeight; i++)




...{


y = (int)(i * newscaley);


diffy = (y - oldy - 1) * (Width + 1); oldy = y;


if (diffy > 0)




...{


scptr = oscptr;


for (int k = 0; k < Nc; k++)




...{


scptr->tl0+=diffy; scptr->tr0+=diffy;


scptr->bl0+=diffy; scptr->br0+=diffy;


scptr->tl1+=diffy; scptr->tr1+=diffy;


scptr->bl1+=diffy; scptr->br1+=diffy;


scptr++;


}


}


for (int j = 0; j < EndWidth; j++)




...{


x = (int)(j * newscalex);


bool Identify = true;


int w = 0;


scptr = oscptr;


for (int k = 0; k < Nc; k++)




...{


diffx = x - scptr->offset; scptr->offset = x;


scptr->tl0+=diffx; scptr->tr0+=diffx;


scptr->bl0+=diffx; scptr->br0+=diffx;


scptr->tl1+=diffx; scptr->tr1+=diffx;


scptr->bl1+=diffx; scptr->br1+=diffx;


int gray = (*(scptr->br0) - *(scptr->bl0) - *(scptr->tr0) + *(scptr->tl0)) / scptr->size0;


gray -= (*(scptr->br1) - *(scptr->bl1) - *(scptr->tr1) + *(scptr->tl1)) / scptr->size1;


if ((gray < scptr->Threshold - Ignore) || (gray > scptr->Threshold + Ignore))




...{


Identify = false;


break;


}


else


w += abs(scptr->Threshold - gray);


scptr++;


}


if (w > MinW) Identify = false;


if (Identify)




...{


objptr->next = new ListObjectType;


objptr = objptr->next;


objptr->x = x; objptr->y = y;


objptr->width = NOWidth; objptr->height = NOHeight;


objptr->w = w; objptr->use = true;


ListCount++;


}


}


x = Width + 1;


scptr = oscptr;


for (int k = 0; k < Nc; k++)




...{


diffx = x - scptr->offset; scptr->offset = 0;


scptr->tl0+=diffx; scptr->tr0+=diffx;


scptr->bl0+=diffx; scptr->br0+=diffx;


scptr->tl1+=diffx; scptr->tr1+=diffx;


scptr->bl1+=diffx; scptr->br1+=diffx;


scptr++;


}


}


scale *= DS.ScaleRatio;


scale_ = 1 / scale;


NewWidth = (int)(Width * scale_); NewHeight = (int)(Height * scale_);


NOWidth = (int)(target.ObjectWidth * scale); NOHeight = (int)(target.ObjectHeight * scale);


if ((NOWidth > DS.EndSubWindow) || (NOHeight > DS.EndSubWindow) || (NewWidth < target.ObjectWidth) || (NewHeight < target.ObjectHeight))


smallenough = true;


else


smallenough = false;


}while (!smallenough);




//merging


ListObjectType *objptr2;


objptr = ListObjects->next;


for (int i = 0; i < ListCount; i++)




...{


if (objptr->use)




...{


objptr2 = objptr->next;


for (int j = i + 1; j < ListCount; j++)




...{


if (objptr2->use)


if (Overlapped(objptr, objptr2))




...{


if (objptr2->w < objptr->w)


objptr->use = false;


else


objptr2->use = false;


}


objptr2 = objptr2->next;


}


}


objptr = objptr->next;


}


objptr = ListObjects->next; Count = 0;


for (i = 0; i < ListCount; i++)




...{


if (objptr->use)


Count++;


objptr = objptr->next;


}


Objects = new CvRect [Count];


CvRect *recptr;


objptr = ListObjects->next;


recptr = Objects;


for (i = 0; i < ListCount; i++)




...{


if (objptr->use)




...{


recptr->x = objptr->x; recptr->y = objptr->y;


recptr->width = objptr->width; recptr->height = objptr->height;


recptr++;


}


objptr = objptr->next;


}


oldptr = ListObjects; objptr = ListObjects->next;


for (i = 0; i < ListCount; i++)




...{


delete oldptr; oldptr = objptr;


objptr = objptr->next;


}


delete oldptr;




delete [] IntegralImage;




return Count;


}




bool LoadDefaultSetting(char *FileName, TDetectSettings &DS)




...{


FILE *dsf = fopen(FileName, "r");


if (NULL != dsf)




...{


fscanf(dsf, "%g", &DS.ScaleRatio);


fscanf(dsf, "%g %g", &DS.OffsetX, &DS.OffsetY);


fscanf(dsf, "%d %d", &DS.Ignore, &DS.MinW);


fscanf(dsf, "%d %d", &DS.StartSubWindow, &DS.EndSubWindow);


fclose(dsf);


return true;


}


else


return false;


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ struct delete null c math.h