📄 facesearch.cpp
字号:
atLocalMax = false;
}
else
atLocalMax = false;
if(atLocalMax)
return diff;
else
{
if(px.x < 4 || px.y < 4 ||
pROIStart->xhi + px.x - pROIStart->xlo >= imgSz.w-4 ||
pROIStart->yhi + px.y - pROIStart->ylo >= imgSz.h-4 )
{ return diff; }
pROIStart->xhi += px.x - pROIStart->xlo;
pROIStart->yhi += px.y - pROIStart->ylo;
pROIStart->xlo = px.x;
pROIStart->ylo = px.y;
return refineLoc(pROIStart, dipoleVect, extents);
}
}
double FaceSearch::getTotDiff
(Pixel_t & px, vector<CascadeDipole_t *> & dipoleVect)
{
double totDiff = 0;
ImgROI_t lightRoi, darkRoi;
for(int i=0; i<dipoleVect.size(); i++)
{
CascadeDipole_t feat = *(dipoleVect[i]);
feat.locateLightROI(px, lightRoi);
feat.locateDarkROI(px,darkRoi);
double width = 1+darkRoi.xhi-darkRoi.xlo;
double height = 1+darkRoi.yhi-darkRoi.ylo;
double areaDk = width*height;
double light = feat.areaRatio * pIntegralImg->getRectValue(lightRoi);
double dark = pIntegralImg->getRectValue(darkRoi);
totDiff += (light - dark) / areaDk;
}
return totDiff;
}
void FaceSearch::setDistance(Match_t * pMatch)
{
BinLoc_t binArr[9];
setBinCoords(pMatch, binArr);
double roiWidth = 1+pMatch->roi.xhi-pMatch->roi.xlo;
double roiHeight = 1+pMatch->roi.yhi-pMatch->roi.ylo;
pMatch->dist = 0;
for(int i=0; i<pMatch->pScaleData->spVect.size(); i++)
{
SpData_t * pSp = pMatch->pScaleData->spVect[i];
int xmin = binArr[pSp->bin].xMin;
int xmax = binArr[pSp->bin].xMax;
int ymin = binArr[pSp->bin].yMin;
int ymax = binArr[pSp->bin].yMax;
if(xmin < 2+pSp->hw) xmin = 2+pSp->hw;
if(xmax > imgSz.w - 1 - pSp->hw)
xmax = imgSz.w - 1 - pSp->hw;
if(ymin < 2+pSp->hh) ymin = 2+pSp->hh;
if(ymax > imgSz.h - 1 - pSp->hh)
ymax = imgSz.h - 1 - pSp->hh;
ImgROI_t imgRoi;
ImgROI_t subROI[4];
double minDist = 1e6;
int bestX, bestY;
for(int y=ymin; y<=ymax; y++)
{
imgRoi.ylo = y-pSp->hh; imgRoi.yhi = y+pSp->hh;
for(int x=xmin; x<=xmax; x++)
{
imgRoi.xlo = x-pSp->hw; imgRoi.xhi = x+pSp->hw;
subROI[0].xlo = subROI[3].xlo = subROI[1].xhi = subROI[2].xhi = x;
subROI[0].ylo = subROI[1].ylo = subROI[2].yhi = subROI[3].yhi = y;
subROI[0].xhi = subROI[3].xhi = imgRoi.xhi;
subROI[1].xlo = subROI[2].xlo = imgRoi.xlo;
subROI[0].yhi = subROI[1].yhi = imgRoi.yhi;
subROI[2].ylo = subROI[3].ylo = imgRoi.ylo;
double d = 0;
for(int j=0; j<4; j++)
{
GradHisto2_t imgHist;
if( (112 == x && 153 == y) || (113 == x && 154 == y) )
int xccxv = 0;
pGradHistIntegral->getGradHist(subROI[j], imgHist);
d += pSp->hist[j].distSq(imgHist);
}
if(d < minDist)
{
minDist = d;
bestX = x; bestY = y;
}
}
}
double deltaX = pSp->dx - (bestX-pMatch->roi.xlo);
if(deltaX < 0) deltaX = -deltaX;
double deltaY = pSp->dy - (bestY-pMatch->roi.ylo);
if(deltaY < 0) deltaY = -deltaY;
pMatch->dist += deltaX/roiWidth;
pMatch->dist += deltaY/roiHeight;
}
}
void FaceSearch::setBinCoords(Match_t * pMatch, BinLoc_t * binArr)
{
double width = 1 + pMatch->roi.xhi - pMatch->roi.xlo;
double height = 1 + pMatch->roi.yhi - pMatch->roi.ylo;
binArr[0].xMin = (double)pMatch->roi.xlo + width/3.0;
binArr[0].xMax = (double)pMatch->roi.xhi - width/3.0;
binArr[0].yMin = (double)pMatch->roi.ylo + height/3.0;
binArr[0].yMax = (double)pMatch->roi.yhi - height/3.0;
binArr[1].xMin = (double)pMatch->roi.xhi - width/3.0;
binArr[1].xMax = (double)pMatch->roi.xhi;
binArr[1].yMin = (double)pMatch->roi.ylo + height/3.0;
binArr[1].yMax = (double)pMatch->roi.yhi - height/3.0;
binArr[2].xMin = (double)pMatch->roi.xhi - width/3.0;
binArr[2].xMax = (double)pMatch->roi.xhi;
binArr[2].yMin = (double)pMatch->roi.yhi - height/3.0;
binArr[2].yMax = (double)pMatch->roi.yhi;
binArr[3].xMin = (double)pMatch->roi.xlo + width/3.0;
binArr[3].xMax = (double)pMatch->roi.xhi - width/3.0;
binArr[3].yMin = (double)pMatch->roi.yhi - height/3.0;
binArr[3].yMax = (double)pMatch->roi.yhi;
binArr[4].xMin = (double)pMatch->roi.xlo;
binArr[4].xMax = (double)pMatch->roi.xlo + width/3.0;
binArr[4].yMin = (double)pMatch->roi.yhi - height/3.0;
binArr[4].yMax = (double)pMatch->roi.ylo + height;
binArr[5].xMin = (double)pMatch->roi.xlo;
binArr[5].xMax = (double)pMatch->roi.xlo + width/3.0;
binArr[5].yMin = (double)pMatch->roi.ylo + height/3.0;
binArr[5].yMax = (double)pMatch->roi.yhi - height/3.0;
binArr[6].xMin = (double)pMatch->roi.xlo;
binArr[6].xMax = (double)pMatch->roi.xlo + width/3.0;
binArr[6].yMin = (double)pMatch->roi.ylo;
binArr[6].yMax = (double)pMatch->roi.ylo + height/3.0;
binArr[7].xMin = (double)pMatch->roi.xlo + width/3.0;
binArr[7].xMax = (double)pMatch->roi.xhi - width/3.0;
binArr[7].yMin = (double)pMatch->roi.ylo;
binArr[7].yMax = (double)pMatch->roi.ylo + height/3.0;
binArr[8].xMin = (double)pMatch->roi.xhi - width/3.0;
binArr[8].xMax = (double)pMatch->roi.xhi;
binArr[8].yMin = (double)pMatch->roi.ylo;
binArr[8].yMax = (double)pMatch->roi.ylo + height/3.0;
}
void FaceSearch::loadCascade(string & cascadeFile) throw(MVErr)
{
// open the cascade file
ifstream fin(cascadeFile.c_str());
if( !fin.is_open() )
throw MVErr("Can\'t open the cascade file: " + cascadeFile);
// read in the search-scale factors
fin >> nScales;
scaleArr = new double[nScales];
cascadeArr = new FaceSearch::Cascade_t[nScales];
for(int i=0; i<nScales; i++)
{
fin >> scaleArr[i];
fin >> cascadeArr[i].nFineScales;
cascadeArr[i].fineScaleArr = new FineScale_t[cascadeArr[i].nFineScales];
for(int ii=0; ii<cascadeArr[i].nFineScales; ii++)
fin >> cascadeArr[i].fineScaleArr[ii].scaleFactor;
}
/*cout << "scales:\n";
for(i=0; i<nScales; i++)
{
cout << scaleArr[i] << endl;
for(int ii=0; ii<cascadeArr[i].nFineScales; ii++)
{
cout << "\t" << cascadeArr[i].fineScaleArr[ii].scaleFactor << endl;
}
cout << "\n";
}*/
// read in the base size
fin >> objSz.w >> objSz.h;
// set the object size for each scale factor
for(i=0; i<nScales; i++)
{
cascadeArr[i].sz.w = (int)(0.5 + scaleArr[i]*(double)objSz.w);
cascadeArr[i].sz.h = (int)(0.5 + scaleArr[i]*(double)objSz.h);
for(int ii=0; ii<cascadeArr[i].nFineScales; ii++)
{
double scaleFactor = cascadeArr[i].fineScaleArr[ii].scaleFactor;
cascadeArr[i].fineScaleArr[ii].sz.w =
(int)(0.5 + scaleFactor*(double)objSz.w);
cascadeArr[i].fineScaleArr[ii].sz.h =
(int)(0.5 + scaleFactor*(double)objSz.h);
}
}
// read in the number of cascade levels
int nLevels;
fin >> nLevels;
// read in the cascade
CascadeLevel_t ** currLevelArr = new CascadeLevel_t *[nScales];
for(int iL=0; iL<nLevels; iL++)
{
int nFeat, nRequired;
fin >> nRequired >> nFeat;
for(i=0; i<nScales; i++)
{
currLevelArr[i] = new CascadeLevel_t;
currLevelArr[i]->nRequired = nRequired;
cascadeArr[i].cascade.push_back(currLevelArr[i]);
}
for(int iF=0; iF<nFeat; iF++)
{
NormDipole_t normDipole;
// read in normalized dipole
fin >> normDipole.normCascThresh >> normDipole.areaRatio
>> normDipole.normDXLoLight >> normDipole.normDYLoLight
>> normDipole.normDXHiLight >> normDipole.normDYHiLight
>> normDipole.normDXLoDark >> normDipole.normDYLoDark
>> normDipole.normDXHiDark >> normDipole.normDYHiDark;
for(i=0; i<nScales; i++)
{
CascadeDipole_t * pCascDipole = new CascadeDipole_t;
normDipole.cascDipoleData(cascadeArr[i].sz, *pCascDipole);
currLevelArr[i]->featVect.push_back(pCascDipole);
for(int ii=0; ii<cascadeArr[i].nFineScales; ii++)
{
// store dipoles for each fine-grained scale
ImgSize_t sz2 = cascadeArr[i].fineScaleArr[ii].sz;
CascadeDipole_t * pCascDipole2 = new CascadeDipole_t;
normDipole.cascDipoleData(sz2, *pCascDipole2);
cascadeArr[i].fineScaleArr[ii].
dipoleVect.push_back(pCascDipole2);
}
}
}
}
delete[] currLevelArr;
// read in the max width and height for a pixel region
// associated with a cascade match
double normMaxWidth, normMaxHeight;
fin >> normMaxWidth >> normMaxHeight;
for(i=0; i<nScales; i++)
{
cascadeArr[i].maxRegWidth =
(int)(0.5 + normMaxWidth * cascadeArr[i].sz.w);
cascadeArr[i].maxRegHeight =
(int)(0.5 + normMaxHeight * cascadeArr[i].sz.h);
}
fin.close();
}
void FaceSearch::loadFeatures(string & featFile) throw(MVErr)
{
// open the features file
ifstream fin(featFile.c_str());
if( !fin.is_open() )
throw MVErr("Can\'t open the feature file: " + featFile);
int nSps = 0;
fin >> nSps;
//cout << "nSps = " << nSps << endl;
for(int i=0; i<nSps; i++)
{
SpData_t sp;
double unused1, unused2;
fin >> sp.dx >> sp.dy >> sp.bin >> sp.hw >> sp.hh;
for(int j=0; j<4; j++)
fin >> sp.hist[j].e >> sp.hist[j].ne
>> sp.hist[j].n >> sp.hist[j].nw
>> sp.hist[j].w >> sp.hist[j].sw
>> sp.hist[j].s >> sp.hist[j].se;
fin >> unused1 >> unused2;
//cout << sp.dx << " " << sp.dy << " "
// << sp.bin << " " << sp.hw << " " << sp.hh << " ";
//cout << sp.hist[0].e << endl;
addSp(sp);
}
fin.close();
}
void FaceSearch::addSp(SpData_t & sp)
{
for(int i=0; i<nScales; i++)
{
for(int ii=0; ii<cascadeArr[i].nFineScales; ii++)
{
SpData_t * pSp = new SpData_t;
double scaleFactor = cascadeArr[i].fineScaleArr[ii].scaleFactor;
pSp->dx = (0.5 + scaleFactor*(double)sp.dx);
pSp->dy = (0.5 + scaleFactor*(double)sp.dy);
pSp->hw = (0.5 + scaleFactor*(double)sp.hw);
pSp->hh = (0.5 + scaleFactor*(double)sp.hh);
pSp->bin = sp.bin;
for(int j=0; j<4; j++)
{
pSp->hist[j].e = scaleFactor * sp.hist[j].e;
pSp->hist[j].ne = scaleFactor * sp.hist[j].ne;
pSp->hist[j].n = scaleFactor * sp.hist[j].n;
pSp->hist[j].nw = scaleFactor * sp.hist[j].nw;
pSp->hist[j].w = scaleFactor * sp.hist[j].w;
pSp->hist[j].sw = scaleFactor * sp.hist[j].sw;
pSp->hist[j].s = scaleFactor * sp.hist[j].s;
pSp->hist[j].se = scaleFactor * sp.hist[j].se;
}
cascadeArr[i].fineScaleArr[ii].spVect.push_back(pSp);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this
// license. If you do not agree to this license, do not download, install, copy or
// use the software.
//
//
// Mavis License Agreement
//
// Copyright (c) 2004-2005, Robin Hewitt (http://www.robin-hewitt.com).
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// This software is provided "as is" and any express or implied warranties, including,
// but not limited to, the implied warranties of merchantability and fitness for a
// particular purpose are disclaimed. In no event shall the authors or contributors be
// liable for any direct, indirect, incidental, special, exemplary, or consequential
// damages (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused and on any
// theory of liability, whether in contract, strict liability, or tort (including
// negligence or otherwise) arising in any way out of the use of this software, even
// if advised of the possibility of such damage.
///////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -