A
Anna Smidt
I have a function which will return a shape from an image everytime it's
called.
Since it's time consuming I would like it to run itself only once, and
at every subsequent calls it should return the shape it calculated the
first time.
In VB6 I would have used the key word "static" to preserve the results
from the first call. Is there an equivalent in C++?
---------------
In VB6 I would have simply said
function Foo(byref uSomething, byref uOutput) as boolean
static bWasRunBefore as boolean //This is a variable will be never get
out of scope
static nFirstTimeResult as something //This is a variable will be never
get out of scope
if not bWasRunBefore
//If it's the first time that this function is called
//do some heavy math stuff
uOutPut = nResult
nFirstTimeResult = nResult //Rember the first result for subsequent calls
bWasRunBefore = True //Remember that this function was called before
else
//Function was already called before, and we will return the old result
//return the return from the first time around
uOutput = nFirstTimeResult
end if
End function
-----------------
C++ code:
bool ViolaJonesFindFace(SHAPE &Shape, const IplImage* image,const char
sDataDir[])
{
if (!pgCascade) // first time?
OpenViolaJones(sDataDir);
Shape.dimClear(NBR_VIOLA_JONES_POINTS, 2);
IplImage* pWork = cvCreateImage
(cvSize(image->width/2, image->height/2), image->depth, image->nChannels);
cvPyrDown(image, pWork, CV_GAUSSIAN_5x5 );
CvSeq* pFaces = cvHaarDetectObjects(pWork, pgCascade, pgStorage,
SCALE_FACTOR, MIN_NEIGHBORS,CV_HAAR_DO_CANNY_PRUNING);
cvReleaseImage(&pWork);
if(0 == pFaces->total)//can't find a face
return false;
int iSelectedFace = 0;
// get most central face
double MaxOffset = 1e10;
// max abs dist from center of face to center of image
for (int iFace = 0; iFace < pFaces->total; iFace++)
{
CvRect* r = (CvRect*)cvGetSeqElem(pFaces, iFace);
double Offset = ABS(r->x*2.0 + r->width - image->width/2.0);
if (Offset < MaxOffset)
{
MaxOffset = Offset;
iSelectedFace = iFace;
}
}
// Write the global detector shape into Shape.
// We must convert the Viola Jones shape coords to our internal shape
coords.
CvRect* r = (CvRect*)cvGetSeqElem(pFaces, iSelectedFace);
int scale = 2;
CvPoint pt1, pt2;
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
Shape(DETECTOR_TopLeft, VX) = r->x*2 - image->width/2.0;
Shape(DETECTOR_TopLeft, VY) = image->height/2.0 - r->y*2;
Shape(DETECTOR_BotRight, VX) = Shape(DETECTOR_TopLeft, VX) + 2*r->width;
Shape(DETECTOR_BotRight, VY) = Shape(DETECTOR_TopLeft, VY) - 2*r->height;
return true;
}
called.
Since it's time consuming I would like it to run itself only once, and
at every subsequent calls it should return the shape it calculated the
first time.
In VB6 I would have used the key word "static" to preserve the results
from the first call. Is there an equivalent in C++?
---------------
In VB6 I would have simply said
function Foo(byref uSomething, byref uOutput) as boolean
static bWasRunBefore as boolean //This is a variable will be never get
out of scope
static nFirstTimeResult as something //This is a variable will be never
get out of scope
if not bWasRunBefore
//If it's the first time that this function is called
//do some heavy math stuff
uOutPut = nResult
nFirstTimeResult = nResult //Rember the first result for subsequent calls
bWasRunBefore = True //Remember that this function was called before
else
//Function was already called before, and we will return the old result
//return the return from the first time around
uOutput = nFirstTimeResult
end if
End function
-----------------
C++ code:
bool ViolaJonesFindFace(SHAPE &Shape, const IplImage* image,const char
sDataDir[])
{
if (!pgCascade) // first time?
OpenViolaJones(sDataDir);
Shape.dimClear(NBR_VIOLA_JONES_POINTS, 2);
IplImage* pWork = cvCreateImage
(cvSize(image->width/2, image->height/2), image->depth, image->nChannels);
cvPyrDown(image, pWork, CV_GAUSSIAN_5x5 );
CvSeq* pFaces = cvHaarDetectObjects(pWork, pgCascade, pgStorage,
SCALE_FACTOR, MIN_NEIGHBORS,CV_HAAR_DO_CANNY_PRUNING);
cvReleaseImage(&pWork);
if(0 == pFaces->total)//can't find a face
return false;
int iSelectedFace = 0;
// get most central face
double MaxOffset = 1e10;
// max abs dist from center of face to center of image
for (int iFace = 0; iFace < pFaces->total; iFace++)
{
CvRect* r = (CvRect*)cvGetSeqElem(pFaces, iFace);
double Offset = ABS(r->x*2.0 + r->width - image->width/2.0);
if (Offset < MaxOffset)
{
MaxOffset = Offset;
iSelectedFace = iFace;
}
}
// Write the global detector shape into Shape.
// We must convert the Viola Jones shape coords to our internal shape
coords.
CvRect* r = (CvRect*)cvGetSeqElem(pFaces, iSelectedFace);
int scale = 2;
CvPoint pt1, pt2;
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
Shape(DETECTOR_TopLeft, VX) = r->x*2 - image->width/2.0;
Shape(DETECTOR_TopLeft, VY) = image->height/2.0 - r->y*2;
Shape(DETECTOR_BotRight, VX) = Shape(DETECTOR_TopLeft, VX) + 2*r->width;
Shape(DETECTOR_BotRight, VY) = Shape(DETECTOR_TopLeft, VY) - 2*r->height;
return true;
}