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

📄 geooperator.cpp

📁 VS2005图像处理程序的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			// 距离当前点最近的四个点坐标
			int	x1, x2, y1, y2;
			x1 = (int)x;
			x2 = x1 + 1;
			y1 = (int)y;
			y2 = y1 + 1;
			// 对应四个坐标像素的取值
			BYTE clr1, clr2, clr3, clr4;
			double u, v;
			u = x - x1;
			v = y - y1;
			// 对于32位真彩色需要分别计算三原色
			for (int k = 0; k < 3; k++)
			{
				// 如果坐标在图像的右下角
				if ( (x >= width - 1) && (y >= height - 1) )
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					objPixel[k] = clr1; 
				}
				// 如果图像在最后一列外侧
				else if ( x >= width - 1 )
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					clr3 = pixel[(y2 * width + x1) * 4 + k];	// (x1, y2)
					objPixel[k] = (BYTE)(clr1 * (1 - v) + clr3 * v); 
				}			
				// 如果图像在最后一行外侧
				else if ( y >= height - 1 )
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					clr2 = pixel[(y1 * width + x2) * 4 + k];	// (x2, y1)
					objPixel[k] = (BYTE)(clr1 * (1 - u) + clr2 * u);
				}
				else
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					clr2 = pixel[(y1 * width + x2) * 4 + k];	// (x2, y1)
					clr3 = pixel[(y2 * width + x1) * 4 + k];	// (x1, y2)
					clr4 = pixel[(y2 * width + x2) * 4 + k];	// (x2, y2)

					double f1, f2;

					f1 = clr1 * (1 - u) + clr2 * u;
					f2 = clr3 * (1 - u) + clr4 * u;
					objPixel[k] = (BYTE)(f1 * (1 - v) + f2 * v);
				}
			}
		}
	}
}

/******************************************************************************
*	作用:			图像的旋转函数(最临近插值法)
*	参数:		
*		pixel		原始像素数组
*		tempPixel	保存变换后图像的像素数组
*		width		原始图像宽度
*		height		原始图像高度
*		outWidth	[out]输出图像的宽度
*		outHeight	[out]输出图像的高度
*		angle		旋转度数,以弧度表示
******************************************************************************/
void RotateNormal(BYTE* pixel, BYTE*& tempPixel, int width, int height, 
				  UINT& outWidth, UINT& outHeight, double angle)
{
	// 原始图像四个角的坐标
	int srcX1, srcX2, srcX3, srcX4;
	int srcY1, srcY2, srcY3, srcY4;
	srcX1 = 0;
	srcY1 = 0;
	srcX2 = width - 1;
	srcY2 = 0;
	srcX3 = 0;
	srcY3 = height - 1;
	srcX4 = width - 1;
	srcY4 = height - 1;
	// 计算旋转角度的正弦和余弦值
	double fSin = sin(angle);
	double fCos = cos(angle);
	// 图像经过旋转后四个角的坐标
	double tranX1, tranX2, tranX3, tranX4;
	double tranY1, tranY2, tranY3, tranY4;
	tranX1 = fCos * srcX1 + fSin * srcY1;
	tranY1 = -fSin * srcX1 + fCos * srcY1;
	tranX2 = fCos * srcX2 + fSin * srcY2;
	tranY2 = -fSin * srcX2 + fCos * srcY2;
	tranX3 = fCos * srcX3 + fSin * srcY3;
	tranY3 = -fSin * srcX3 + fCos * srcY3;
	tranX4 = fCos * srcX4 + fSin * srcY4;
	tranY4 = -fSin * srcX4 + fCos * srcY3;
	// 计算旋转后图像的大小
	outWidth = (UINT)( max( fabs(tranX4-tranX1), fabs(tranX3-tranX2) ) + 1.5 );
	outHeight = (UINT)( max( fabs(tranY4-tranY1), fabs(tranY3-tranY2) ) + 1.5 );
	tempPixel = new BYTE[outWidth * outHeight * 4];
	memset(tempPixel, 255, outWidth * outHeight * 4);
	// 计算两个常量
	double num1 = -0.5*outWidth*fCos - 0.5*outHeight*fSin + 0.5*width;
	double num2 = 0.5*outWidth*fSin - 0.5*outHeight*fCos + 0.5*height;
	BYTE*	copyPixel = NULL;	// 指向原始图像中需要拷贝像素的起始位置
	BYTE*	objPixel = NULL;	// 指向被复制像素的起始位置
	int		x = 0;				// 变换后的像素横坐标
	int		y = 0;				// 变换后的像素纵坐标
	for (long j = 0; j < (long)outHeight; j++)
	{
		for (long i = 0; i < (long)outWidth; i++) 
		{
			x = (int)(i * fCos + j * fSin + num1 + 0.5);
			y = (int)(-i * fSin + j * fCos + num2 + 0.5);

			// 修正坐标
			if (x == width)
				x--;
			if (y == height)
				y--;
			copyPixel = pixel + y * width * 4 + x * 4;
			objPixel = tempPixel + j * outWidth * 4 + i * 4;
			if (x >= 0 && x < width && y >= 0 && y < height)
				memcpy(objPixel, copyPixel, 4);
		}
	}
}

/******************************************************************************
*	作用:			图像的旋转函数(双线性插值法)
*	参数:		
*		pixel		原始像素数组
*		tempPixel	保存变换后图像的像素数组
*		width		原始图像宽度
*		height		原始图像高度
*		outWidth	[out]输出图像的宽度
*		outHeight	[out]输出图像的高度
*		angle		旋转度数,以弧度表示
******************************************************************************/
void RotateInterpolation(BYTE* pixel, BYTE*& tempPixel, int width, int height, 
						 UINT& outWidth, UINT& outHeight, double angle)
{
	// 原始图像四个角的坐标
	int srcX1, srcX2, srcX3, srcX4;
	int srcY1, srcY2, srcY3, srcY4;
	srcX1 = 0;
	srcY1 = 0;
	srcX2 = width - 1;
	srcY2 = 0;
	srcX3 = 0;
	srcY3 = height - 1;
	srcX4 = width - 1;
	srcY4 = height - 1;
	// 计算旋转角度的正弦和余弦值
	double fSin = sin(angle);
	double fCos = cos(angle);
	// 图像经过旋转后四个角的坐标
	double tranX1, tranX2, tranX3, tranX4;
	double tranY1, tranY2, tranY3, tranY4;
	tranX1 = fCos * srcX1 + fSin * srcY1;
	tranY1 = -fSin * srcX1 + fCos * srcY1;
	tranX2 = fCos * srcX2 + fSin * srcY2;
	tranY2 = -fSin * srcX2 + fCos * srcY2;
	tranX3 = fCos * srcX3 + fSin * srcY3;
	tranY3 = -fSin * srcX3 + fCos * srcY3;
	tranX4 = fCos * srcX4 + fSin * srcY4;
	tranY4 = -fSin * srcX4 + fCos * srcY3;
	// 计算旋转后图像的大小
	outWidth = (UINT)( max( fabs(tranX4-tranX1), fabs(tranX3-tranX2) ) + 1.5 );
	outHeight = (UINT)( max( fabs(tranY4-tranY1), fabs(tranY3-tranY2) ) + 1.5 );
	tempPixel = new BYTE[outWidth * outHeight * 4];
	memset(tempPixel, 255, outWidth * outHeight * 4);
	//计算矩阵(2.9)中的两个常数,这样不用以后每次都计算了
	double num1 = -0.5*outWidth*fCos - 0.5*outHeight*fSin + 0.5*width;
	double num2 = 0.5*outWidth*fSin - 0.5*outHeight*fCos + 0.5*height;
	BYTE*	copyPixel = NULL;	// 指向原始图像中需要拷贝像素的起始位置
	BYTE*	objPixel = NULL;	// 指向被复制像素的起始位置
	double	x = 0.0;			// 变换后的像素横坐标
	double	y = 0.0;			// 变换后的像素纵坐标
	long	tempJ = 0;			// 存储中间值,提高函数速度
	for (long j = 0; j < (long)outHeight; j++)
	{
		tempJ = j * outWidth * 4;
		for (long i = 0; i < (long)outWidth; i++) 
		{
			x = i * fCos + j * fSin + num1;
			y = -i * fSin + j * fCos + num2;
			// 超界则计算下一个像素
			if (x > width || x < 0 || y > height || y < 0)
				continue;
			objPixel = tempPixel + tempJ + i * 4;
			// 距离当前点最近的四个点坐标
			int	x1, x2, y1, y2;
			x1 = (int)x;
			x2 = x1 + 1;
			y1 = (int)y;
			y2 = y1 + 1;
			// 对应四个坐标像素的取值
			BYTE clr1, clr2, clr3, clr4;
			double u, v;
			u = x - x1;
			v = y - y1;
			// 对于32位真彩色需要分别计算三原色
			for (int k = 0; k < 3; k++)
			{
				// 如果坐标在图像的右下角
				if ( (x >= width - 1) && (y >= height - 1) )
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					objPixel[k] = clr1; 
				}
				// 如果图像在最后一列外侧
				else if ( x >= width - 1 )
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					clr3 = pixel[(y2 * width + x1) * 4 + k];	// (x1, y2)
					objPixel[k] = (BYTE)(clr1 * (1 - v) + clr3 * v); 
				}			
				// 如果图像在最后一行外侧
				else if ( y >= height - 1 )
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					clr2 = pixel[(y1 * width + x2) * 4 + k];	// (x2, y1)
					objPixel[k] = (BYTE)(clr1 * (1 - u) + clr2 * u);
				}
				else
				{
					clr1 = pixel[(y1 * width + x1) * 4 + k];	// (x1, y1)
					clr2 = pixel[(y1 * width + x2) * 4 + k];	// (x2, y1)
					clr3 = pixel[(y2 * width + x1) * 4 + k];	// (x1, y2)
					clr4 = pixel[(y2 * width + x2) * 4 + k];	// (x2, y2)

					double f1, f2;

					f1 = clr1 * (1 - u) + clr2 * u;
					f2 = clr3 * (1 - u) + clr4 * u;
					objPixel[k] = (BYTE)(f1 * (1 - v) + f2 * v);
				}
			}
		}
	}
}

⌨️ 快捷键说明

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