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

📄 imutil.cpp

📁 这是个人脸识别程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// $image\imutil.cpp 1.5 milbo$ image utilities// Warning: this is raw research code -- expect it to be quite messy.// milbo durban dec05#include <windows.h>#include <io.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <signal.h>#include <float.h>#include <math.h>#include <new.h>#include <direct.h>#include <sys/stat.h>#include <fstream.h>#include <iostream.h>#include "mcommon.hpp"#include "mfile.hpp"#include "image.hpp"#include "imutil.hpp"#include "rgbimutil.hpp"#include "imfile.hpp"#include "jpegutil.hpp"//-----------------------------------------------------------------------------// What do we do with the empty space where we shifted the image?  Do this:// 	fExtend=false: use black (this is the default)// 	fExtend=true:  use the closest edge pixel, thus effectively extending //				   the edge of of the shifted imagevoid MoveImage (Image &Img, 											// io				int nxShift, int nyShift, bool fVerbose, bool fExtend)	// in{int width = Img.width;int height = Img.height;if (fVerbose)	{	if (nxShift)		lprintf("xShift %d ", nxShift);	if (nyShift)		lprintf("Shift %d ", nyShift);	}if (abs(nxShift) >= width)	Err("xShift %d is bigger than width %d", nxShift, width);if (abs(nyShift) >= height)	Err("yShift %d is bigger than height %d", nyShift, height);nyShift = -nyShift;Image OutImg(width, height, true);		// fills image with blackfor (int ix = 0; ix < width; ix++)	{	int ixOld = ix - nxShift;	for (int iy = 0; iy < height; iy++)		{		int iyOld = iy - nyShift;		if (ixOld < 0)			{			if (fExtend)				ixOld = 0;			else				continue;			}		else if (ixOld >= width)			{			if (fExtend)				ixOld = width-1;			else				continue;			}		if (iyOld < 0)			{			if (fExtend)				iyOld = 0;			else				continue;			}		else if (iyOld >= height)			{			if (fExtend)				iyOld = height-1;			else				continue;			}		OutImg(ix, iy) = Img(ixOld, iyOld);		}	}Img = OutImg;}//-----------------------------------------------------------------------------void CropImage (Image &Img,																		// io				int nTopCrop, int nBottomCrop, int nLeftCrop, int nRightCrop, bool fVerbose)	// in{int width = Img.width;int height = Img.height;if (fVerbose)	{	if (nTopCrop)		lprintf("CropTop %d ", nTopCrop);	if (nBottomCrop)		lprintf("CropBottom %d ", nBottomCrop);	if (nLeftCrop)		lprintf("CropLeft %d ", nLeftCrop);	if (nRightCrop)		lprintf("CropRight %d ", nRightCrop);	}int nNewWidth = Img.width - nLeftCrop - nRightCrop;int nNewHeight = Img.height - nTopCrop - nBottomCrop;if (nTopCrop < 0 || nBottomCrop < 0 || nLeftCrop < 0 || nRightCrop < 0)	Err("you can't specify a crop less than 0");if (nNewWidth <= 0)	Err("specified left or right crop would cause a width less than or equal to zero");if (nNewWidth > width)	Err("specified left or right crop would cause a width bigger than current width");if (nNewHeight <= 0)	Err("specified top or bottom crop would cause a height less than or equal to zero");if (nNewHeight > height)	Err("specified top or bottom crop would cause a height bigger than current height");Image OutImg(nNewWidth, nNewHeight);for (int iy = 0; iy < nNewHeight; iy++)	for (int ix = 0; ix < nNewWidth; ix++)		OutImg(ix, iy) = Img(ix + nLeftCrop, iy + nTopCrop);Img = OutImg;}//-----------------------------------------------------------------------------// Will flip horizontally, unless fVertical is true in which case it will flip verticallyvoid FlipImage (Image &Img,						// io				bool fVertical, bool fVerbose)	// in{if (fVerbose)	lprintf("Flip%s ", (fVertical? "Vertical": "Horizontal"));int width = Img.width;int height = Img.height;Image OutImg(width, height);if (fVertical)	{	for (int iy = 0; iy < height; iy++)		memcpy(OutImg.buf + iy * width, Img.buf + (height - 1 - iy) * width, width);	}else for (int iy = 0; iy < height; iy++)	{	int Width1 = iy * width;	int ix1 = width;	for (int ix = 0; ix < width; ix++)		OutImg(ix + Width1) = Img(--ix1 + Width1);	}Img = OutImg;}//-----------------------------------------------------------------------------// Helper function for ScaleImage.  Actually a macro, for speed.static int ig_Pos, ig_Pos1; double g_Frac;#define _InterpolatePixel(pIn, ix, Scale, Max) 								\{ 																			\ig_Pos = (int)(ix * Scale); 												\ig_Pos1 = ig_Pos + 1; 														\if (ig_Pos1 >= Max) 														\	ig_Pos1 = Max-1; 														\g_Frac = (ix * Scale) - ig_Pos;												\g_Frac = (int)((1.0 - g_Frac) * pIn[ig_Pos] + g_Frac * pIn[ig_Pos1] + 0.5); \}//-----------------------------------------------------------------------------// Scale using two steps of linear interpolation: first in the X direction, // then in the Y direction//// If fBilinear is false we use the nearest pixel (usually a sharper image)//// TODO Is the following a bug? If size is reduced by more than 2, this ignores some // pixels in the input image, even when fBilinear is true -- because we look// a max of 2 pixels when doing bilinear interpretation.  // Use ReduceRgbImage if this matters to you.//// I lifted the original version of this from Henry Rowley img.cc:ReduceSize()void ScaleImage (Image &Img, 																				// io					const int nNewWidth, const int nNewHeight, const bool fVerbose, const bool fBilinear)	// in{int   ix, iy;const int width = Img.width;const int height = Img.height;const double scaleX = (double)width /nNewWidth;const double scaleY = (double)height/nNewHeight;if (fVerbose)	{	if (scaleX > 1)		lprintf("ScaleDown %.2g ", 1/scaleX);	else if (scaleX < 1)		lprintf("ScaleUp %.2g ", 1/scaleX);	else		lprintf("Scale %.2g ", 1/scaleX);	}if (width != nNewWidth || height != nNewHeight)	{	if (fBilinear)		{		// scale horizontally		Image Out1(nNewWidth, height);		byte *pIn = Img.buf;		for (iy = 0; iy < height; iy++)			{			for (ix = 0; ix < nNewWidth; ix++)				{				_InterpolatePixel(pIn, ix, scaleX, width);				Out1(iy + ix * height) = (byte)g_Frac;				}			pIn += width;			}		// scale vertically		Img.dim(nNewWidth, nNewHeight);		byte * const pOut = Img.buf;		pIn = Out1.buf;		for (iy = 0; iy < nNewWidth; iy++)			{			for (ix = 0; ix < nNewHeight; ix++)				{				_InterpolatePixel(pIn, ix, scaleY, height);				pOut[iy + ix * nNewWidth] = (byte)g_Frac;				}			pIn += height;			}		}	else	// nearest pixel		{		Image OutImg(nNewWidth, nNewHeight);		for (iy = 0; iy < nNewHeight; iy++)			{			int iy1 = (iy * height) / nNewHeight;			for (ix = 0; ix < nNewWidth; ix++)				OutImg(ix, iy) = Img((ix * width) / nNewWidth, iy1);			}		Img = OutImg;		}	}}//-----------------------------------------------------------------------------void ExtendImage (Image &Img, 													// io				  int nLeft, int nRight, int nTop, int nBottom, bool fVerbose)	// in{if (fVerbose)	{	if (nTop)		lprintf("AddTop %d ", nTop);	if (nBottom)		lprintf("AddBottom %d ", nBottom);	if (nLeft)		lprintf("AddLeft %d ", nLeft);	if (nRight)		lprintf("AddRight %d ", nRight);	}if (nTop < 0 || nBottom < 0 || nLeft < 0 || nRight < 0)	Err("you can't extend an image by less than 0");if (nTop != 0 || nBottom != 0 || nLeft != 0 || nRight != 0)	{	int width = Img.width;	int height = Img.height;	Image OutImg(width + nLeft + nRight, height + nTop + nBottom, true);	// init to 0	for (int ix = 0; ix < width; ix++)		for (int iy = 0; iy < height; iy++)			OutImg(ix + nLeft, iy + nBottom) = Img(ix, iy);	Img = OutImg;	}}//-----------------------------------------------------------------------------// If Scale is integral, this averages all pixels in the source area to make// a pixel in the reduced image.// If Scale is non-integral, it uses bilinear interpolation.void ReduceImage (Image &Img, 										// io					double Scale, int ReduceMethod, bool fVerbose)	// in{if (fVerbose)	lprintf("Reduce %g ", Scale);if (!fEqual(Scale, 1, 1e-3))	// only reduce if we have to	{	int iScale, ix, iy;	int nNewWidth = int(Img.width / Scale), nNewHeight = int(Img.height / Scale);	if (nNewWidth < 10 || nNewHeight < 10)	// 10 is rather arbitrary		SysErr("ReduceImageAssign: image too small, nNewWidth %d nNewHeight %d", nNewWidth, nNewHeight);	switch (ReduceMethod)		{		case IM_NEAREST_PIXEL:			ScaleImage(Img, nNewWidth, nNewHeight, fVerbose, IM_NEAREST_PIXEL);			break;		case IM_BILINEAR:			ScaleImage(Img, nNewWidth, nNewHeight, fVerbose, IM_BILINEAR);			break;		case IM_AVERAGE_ALL:			{			ASSERT(fEqual(floor(Scale), Scale, 1e-3));	// scale is an integer?			iScale = (int)Scale;							// for efficiency do calculations using ints not doubles			Image OutImg(nNewWidth, nNewHeight);			for (iy = 0; iy < nNewHeight; iy++)				for (ix = 0; ix < nNewWidth; ix++)					{					int Pixel = 0;					for (int j = 0; j < iScale; j++)						for (int i = 0; i < iScale; i++)							Pixel += Img((ix * iScale) + i, iy * iScale + j);					OutImg(ix, iy) = byte(Pixel / (iScale * iScale));					}			Img = OutImg;									// this does a memcpy			break;			}		default:			SysErr("CONF_ReduceMethod");			break;		}	}}//-----------------------------------------------------------------------------// Like ReduceImage but output image is same as input image -- this// is faster because we don't need to copy memory.

⌨️ 快捷键说明

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