⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 facesearch.cpp

📁 机器人程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			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 + -