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

📄 imshape.cpp

📁 这是个人脸识别程序
💻 CPP
字号:
// $masm\imshape.cpp 1.5 milbo$ routines for drawing shapes, profiles, and images// Warning: this is raw research code -- expect it to be quite messy.// milbo durban dec05//-----------------------------------------------------------------------------// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// A copy of the GNU General Public License is available at// http://www.r-project.org/Licenses///-----------------------------------------------------------------------------#include "all.hpp"//-----------------------------------------------------------------------------// If fTransparent is set then the point is the average of Red Green Blue and the underlying image pointvoid SetImagePoint (RgbImage &Img, unsigned Red, unsigned Green, unsigned Blue, int ix, int iy, bool fTransparent){int	width = Img.width, height = Img.height;ix += width / 2;iy += height / 2;int i =  ix + iy * width;if (i > 0 && i < width * height)	{	if (fTransparent)		{		Img(ix, iy).Red   = Img(ix, iy).Red/2   + Red/2;		Img(ix, iy).Green = Img(ix, iy).Green/2 + Green/2;		Img(ix, iy).Blue  = Img(ix, iy).Blue/2   + Blue/2;		}	else		{		Img(ix, iy).Red = Red;		Img(ix, iy).Green = Green;		Img(ix, iy).Blue = Blue;		}	}}//-----------------------------------------------------------------------------// This function uses a Bresenham-like algorithm to draw a line from x0,y0 to x1,y1//// Based on "Bresenham-based supercover line algorithm" by// Eugen.Dedu www.ese-metz.fr/~dedu/projects/bresenhamvoid BresenhamDrawLine (RgbImage &Img, unsigned Red, unsigned Green, unsigned Blue, int x0, int y0, int x1, int y1, bool fTransparent){int i;               // loop counterint yStep, xStep;    // the step on y and x axisint Error;           // the error accumulated during the incrementint ddy, ddx;int x = x0, y = y0;int dx = x1 - x0;int dy = y1 - y0;SetImagePoint(Img, Red, Green, Blue, x, y, fTransparent); 		// first pointif (dy < 0)	{	yStep = -1;	dy = -dy;	}else	yStep = 1;if (dx < 0)	{	xStep = -1;	dx = -dx;	}else	xStep = 1;ddy = 2 * dy;ddx = 2 * dx;if (ddx >= ddy)	 				// first octant (0 <= slope <= 1)	{	Error = dx;					// start in the middle of the square	for (i = 0; i < dx; i++)	// do not use the first point (already done)		{		x += xStep;		Error += ddy;		if (Error > ddx)		// increment y if AFTER the middle (>)			{			y += yStep;			Error -= ddx;			}		SetImagePoint(Img, Red, Green, Blue, x, y, fTransparent);		}	}else	{	Error = dy;	for (i = 0; i < dy; i++)		{		y += yStep;		Error += ddx;		if (Error > ddy)			{			x += xStep;			Error -= ddy;			}		SetImagePoint(Img, Red, Green, Blue, x, y, fTransparent);		}	}}//-----------------------------------------------------------------------------void ImageWhiskers (RgbImage &Img, const SHAPE &Shape, unsigned Color, double Scale, double ProfAngle,							bool fTransparent, unsigned ProfType, 							const tLand Lands[], const SHAPE *pAlignedAvShape){ASSERT(Lands);unsigned Blue  = Color & 0xff;unsigned Green = (Color >> 8) & 0xff;unsigned Red   = (Color >> 16) & 0xff;int nPoints = Shape.nrows();for (int iPoint = 0; iPoint < nPoints; iPoint++)	{	if (!fPointUsed(Shape, iPoint))		continue;	if ((ProfType & PROF_2d) == 0)		// 1D prof?		{		double DeltaX, DeltaY;		GetProfStepSize(&DeltaX, &DeltaY, Shape, iPoint, ProfAngle, Lands, *pAlignedAvShape);		int nProfWidthEachSide = 8;		// TODO this should actually be determined by the model		// We don't use the standard line drawing routine because I want to show exact posn of sampled points		// I've tried to make this match prof.cpp:PrepareProf1D() so we draw points in the exact same place		// as we sample them for 1D profiles.		for (int iSamplePoint = -nProfWidthEachSide; iSamplePoint <= nProfWidthEachSide; iSamplePoint++)			SetImagePoint(Img, Red, Green, Blue,				iRound(Scale * GetX(Shape(iPoint, VX), -iSamplePoint, 0, DeltaX, DeltaY)),				iRound(Scale * GetY(Shape(iPoint, VY), -iSamplePoint, 0, DeltaX, DeltaY)), fTransparent);		// draw single bright point to show start of whisker		int ix1 = iRound(Scale * GetX(Shape(iPoint, VX), -nProfWidthEachSide, 0, DeltaX, DeltaY));		int iy1 = iRound(Scale * GetY(Shape(iPoint, VY), -nProfWidthEachSide, 0, DeltaX, DeltaY));		unsigned Red1 = __min(Red*2, 255), Green1 = __min(Green*2, 255), Blue1 = __min(Blue*2, 255);		Red1 = 200; Green1 = 255; Blue1 = 200; //TODO makes point more visible than above colors		SetImagePoint(Img, Red1, Green1, Blue1,	ix1, iy1, IM_NO_TRANSPARENT);		}	else		// 2D prof		{		SHAPE SubShape(5, 2);		int x = Shape(iPoint, VX);		int y = Shape(iPoint, VY);		int nProfWidthEachSide = 5;		// TODO this should actually be determined by the model		nProfWidthEachSide += 1;		// add 1 so square profile is contained in the outline		SubShape(0, VX) = x - nProfWidthEachSide; SubShape(0, VY) = y - nProfWidthEachSide;		SubShape(1, VX) = x - nProfWidthEachSide; SubShape(1, VY) = y + nProfWidthEachSide;		SubShape(2, VX) = x + nProfWidthEachSide; SubShape(2, VY) = y + nProfWidthEachSide;		SubShape(3, VX) = x + nProfWidthEachSide; SubShape(3, VY) = y - nProfWidthEachSide;		SubShape(4, VX) = x - nProfWidthEachSide; SubShape(4, VY) = y - nProfWidthEachSide;		// connect back to first vertex		DrawShape(Img, SubShape, Color, Scale, IM_CONNECT_DOTS, IM_NO_ANNOTATE, IM_NO_WHISKERS, 0, fTransparent);		}	}}//-----------------------------------------------------------------------------// Draw Shape in the image Img in the specified Color// Lands and AlignedAvShape are only used if fWhiskers is true// fAnnotate is ignored if image is too small for letteringvoid DrawShape (RgbImage &Img, 																// io					const SHAPE &Shape, unsigned Color, double Scale,					 		// in					bool fConnectTheDots, bool fAnnotate, 										// in					bool fWhiskers, unsigned ProfType, bool fTransparent,						// in: ProfType determines what type of "whisker" to draw					const tLand Lands[], const SHAPE *pAlignedAvShape,							// in					bool fDrawCircleAtLandmark,													// in: current implementation is very slow					unsigned ConnectDotsColor)													// in: color used to connect dots, -1 to use same as dot color{unsigned Red   = (Color >> 16) & 0xff;unsigned Green = (Color >> 8) & 0xff;unsigned Blue  = Color & 0xff;int iFirstPoint = -1, iPoint1 = 0;int nPoints = Shape.nrows();for (int iPoint = 0; iPoint < nPoints; iPoint++)	{	if (!fPointUsed(Shape, iPoint))		continue;	if (iFirstPoint == -1)		iFirstPoint = iPoint;	if (iPoint < nPoints-1)		iPoint1 = iPoint + 1;	while (iPoint1 < nPoints && !fPointUsed(Shape, iPoint1))		iPoint1++;#if 1	// july 2007: fixes bug which was a fencepost error when coord changes sign	int ix = iRound(Scale * Shape(iPoint, VX));	int iy = iRound(Scale * Shape(iPoint, VY));#else	// TODO old code	int ix = int(Scale * Shape(iPoint, VX) + 0.5);	int iy = int(Scale * Shape(iPoint, VY) + 0.5);#endif	if (fConnectTheDots && iPoint1 < nPoints &&		 (CONF_fSkipExtraEyeLinesInDisplayedShape || iPoint1 < MLEye0 || iPoint1 > MREye7))		{		unsigned Red1   = Red;		unsigned Green1 = Green;		unsigned Blue1  = Blue;		bool fTransparent1 = false;		if (ConnectDotsColor != -1)			{			Red1   = (ConnectDotsColor >> 16) & 0xff;			Green1 = (ConnectDotsColor >> 8) & 0xff;			Blue1  = ConnectDotsColor & 0xff;			fTransparent1 = true;			}		BresenhamDrawLine(Img, Red1, Green1, Blue1,						  ix, iy, iRound(Scale * Shape(iPoint1, VX)), iRound(Scale * Shape(iPoint1, VY)), fTransparent1);		}#if 0	// connect first and last point	BresenhamDrawLine(Img, Red, Green, Blue,		iRound(Scale * Shape(nPoints-1, VX)), iRound(Scale * Shape(nPoints-1, VY)), 		iRound(Scale * Shape(0, VX)), iRound(Scale * Shape(0, VY)), fTransparent);#endif	SetImagePoint(Img, Red, Green, Blue, ix, iy, FALSE);#if 0	//TODO different color i.e. green for extra eye landmarks	if (iPoint > 67)		SetImagePoint(Img, 0, 255, 0, ix, iy, FALSE);#endif	if (fDrawCircleAtLandmark)													// in		{		// draw circle at landmark (current implementation is very slow)		int ix1 = ix + Img.width / 2;		int iy1 = Img.height / 2 - iy;		RgbEllipse(Img, ix1-3, iy1-3, ix1+3, iy1+3, Red, Green, Blue);		}	if (fAnnotate)		{		double xExtent = xShapeExtent(Shape);		int iFontSize;		if (xExtent > 100)			iFontSize = 200;		if (xExtent > 50)			iFontSize = 100;		else			iFontSize = 60;		RgbPrintf(Img, Img.width/2 + ix + 2, Img.height/2 - iy, Color, iFontSize, "%d", iPoint);		}	}if (fWhiskers)	ImageWhiskers(Img, Shape, C_GREEN, Scale, 0, fTransparent, ProfType, Lands, pAlignedAvShape);}//-----------------------------------------------------------------------------// Like DrawShape but accepts a grayscale image and returns the color image// and even more horrid number of parametersvoid DrawShape1 (RgbImage &Img, 																					// out					const Image &InImg, const SHAPE &Shape1, const SHAPE *pShape2, unsigned Color, double Scale, 	// in					bool fConnectTheDots, bool fAnnotate, 															// in					bool fWhiskers, unsigned ProfType, bool fTransparent, bool fCropToFace,							// in					const tLand Lands[], const SHAPE *pAlignedAvShape,	bool fDrawCircleAtLandmark)					// in{ConvertGrayImageToRgb(Img, InImg);if (Scale != 1.0)	ScaleRgbImage(Img, Img.width * Scale, Img.height * Scale);DrawShape(Img, Shape1, Color, Scale, fConnectTheDots, fAnnotate, fWhiskers, ProfType, fTransparent, Lands, pAlignedAvShape, fDrawCircleAtLandmark);if (pShape2)	// optional extra shape, dots not connected	DrawShape(Img, *pShape2, C_YELLOW, Scale, IM_NO_CONNECT_DOTS, IM_NO_ANNOTATE, IM_NO_WHISKERS, 0, IM_TRANSPARENT);if (fCropToFace)	{	DASSERT(pAlignedAvShape);	CropImageToFace(Img, *pAlignedAvShape, Scale);	}}//-----------------------------------------------------------------------------// If you want high resolution images, set Scale to something bigger than 1 like 2.// If you want to see the exact original image, use Scale=1//// If Scale>1, the image doesn't really have a higher resolution, because we are // simply scaling up, not adding information.  But it has a bigger width and height// and the drawn landmark mesh is correspondingly finer, which can be useful.void ImageAllShapes (const SHAPE aShapes[], Image aImages[],					 char *saTags[], int nShapes, double Scale, bool fCropToFace,					 const SHAPE &AvShape, const tLand Lands[]){lprintf("   Writing images and shapes ");InitPacifyUser(nShapes);for (int iShape = 0; iShape < nShapes; iShape++)	{	PacifyUser(iShape);	// show AlignedAvShape as well -- to do this get AvShape and align it to this shape	SHAPE AlignedAvShape(AvShape);	AlignShape(AlignedAvShape, aShapes[iShape]);	RgbImage Img;	DrawShape1(Img, aImages[iShape], aShapes[iShape], &AlignedAvShape, 		C_DRED, Scale, IM_CONNECT_DOTS, IM_ANNOTATE, IM_WHISKERS, 0, IM_TRANSPARENT, IM_CROP_TO_FACE, 		Lands, &AlignedAvShape);	char sPath[SLEN]; sprintf(sPath, "%s/_%s", CONF_sOutDir, &saTags[iShape][FNAME_OFFSET]);	WriteBmp(Img, sPath);	}lprintf("0\n");}//-----------------------------------------------------------------------------static void DrawGridPoint (tRGB *p, int iRow, int iProf, int ncols1, int ncols){if (ncols1 > 1 && (iRow == ncols1/2 || iRow == ncols1/2+1))		// center row?	{ p->Red = 0; p->Green = 0; p->Blue = 0; }					// blackelse if (ncols > 1 && (iProf == ncols/2 || iProf == ncols/2+1))	// center col?	{ p->Red = 0; p->Green = 0; p->Blue = 0; }					// blackelse	{ p->Red = 42; p->Green = 137; p->Blue = 38; }				// green}//-----------------------------------------------------------------------------// Crop the image so face fills whole imagevoid CropImageToFace (RgbImage &Img, 											// io						const SHAPE &Shape, double Scale, bool fWideMargins)	// in{// We can only crop the image to the face if certain face points are present// to tell us where the face is.  So check first with this if statement.int nrows = Shape.nrows();if (nrows >= MLInnerTopEyeBrow 	// prevent index range error	 && iTranslatedPoint(MLInnerTopEyeBrow) < nrows	 && iTranslatedPoint(MTipOfChin) < nrows	 && iTranslatedPoint(MLJaw1) < nrows	 && iTranslatedPoint(MRJaw1) < nrows	 && fPointUsed(Shape, iTranslatedPoint(MLInnerTopEyeBrow))	 && fPointUsed(Shape, iTranslatedPoint(MTipOfChin))	 && fPointUsed(Shape, iTranslatedPoint(MLJaw1))	 && fPointUsed(Shape, iTranslatedPoint(MRJaw1)))	{	int	width = Img.width, height = Img.height;			double Margin = 20, BottomMargin = 50;				// magic 20 and 50 provide additional offset, values found empirically	if (fWideMargins)		{		Margin *= 3;		BottomMargin *= 3;		}	int iTopCrop 	= __max(height/2 - Scale * Shape(iTranslatedPoint(MLInnerTopEyeBrow), VY) - Margin, 0);	int iBottomCrop = __max(height/2 + Scale * Shape(iTranslatedPoint(MTipOfChin), VY)        - BottomMargin, 0);	int iLeftCrop   = __max(width/2  + Scale * Shape(iTranslatedPoint(MLJaw1), VX) 		   - Margin, 0);	int iRightCrop  = __max(width/2  - Scale * Shape(iTranslatedPoint(MRJaw1), VX) 		   - Margin, 0);	CropRgbImage(Img, iTopCrop, iBottomCrop, iLeftCrop, iRightCrop, QUIET, IM_WIDTH_DIVISIBLE_BY_4);	}}//-----------------------------------------------------------------------------// crop the image so the shape fills the whole imagevoidCropImageToShape (RgbImage &Img,        // io                 const SHAPE &Shape)    // in{// increase the following margins if you want more room around the shapedouble xMargin = 20, yMargin = 30;#define MAX(x,y) (((x) > (y)) ? (x) : (y))int nLeftCrop   = int(MAX(0, Img.width/2  + Shape.col(VX).minElem() - xMargin)); int nRightCrop  = int(MAX(0, Img.width/2  - Shape.col(VX).maxElem() - xMargin)); int nTopCrop    = int(MAX(0, Img.height/2 - Shape.col(VY).maxElem() - yMargin)); int nBottomCrop = int(MAX(0, Img.height/2 + Shape.col(VY).minElem() - yMargin)); CropRgbImage(Img, nTopCrop, nBottomCrop, nLeftCrop, nRightCrop, QUIET, IM_WIDTH_DIVISIBLE_BY_4);}//-----------------------------------------------------------------------------// Get font size appropriate for image sizeint iGetFontSize (unsigned ImageBits){if (ImageBits & IM_DoubleScale)	return 240;else if (ImageBits & IM_FullScale)	return 160;else	return 80;}//-----------------------------------------------------------------------------// Get output image scale based on ImageBitsdouble GetScaleOut (unsigned ImageBits, int iLev){if (ImageBits & IM_DoubleScale)	return 2 * pow(2, iLev);else if (ImageBits & IM_FullScale)	return pow(2, iLev);else	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -