亚像素图像图像平移

图像平移是最基本的图像几何变换,楼主采用双线性插值算法实现级的图像平移。

void TranslateTransform(Mat& src, Mat& dst, double dx, double dy, uchar FillValue = 0)  ///图像的平移变换
{
    CV_Assert(src.depth() == CV_8U);
    const int Rows = src.rows;
    const int Cols = src.cols;
    dst.create(Rows, Cols, src.type());
	int tempj = 0, tempy = 0;
///////--------像素级平移-----------------
	if ((dx - (int)dx) == 0 && (dy - (int)dy)== 0 )   
	{  
		int y,x;
		for (int i = 0; i < Rows; i++)
		{ 
			x = i - dx;               ///平移后坐标映射到原图像,x行
			if (x >= 0 && x < Rows)   ///保证映射后的坐标在原图像行范围内       
			{
				uchar* srcdata = src.ptr(x);
				uchar* dstdata = dst.ptr(i);
				for (int j = 0; j < Cols; j++)
				{
					y = j - dy;     //平移后坐标映射到原图像,y列
					tempj = 3 * j;   ////彩色图像横坐标的位置
					tempy = 3 * y;
					if ( y >= 0 &&  y < Cols)   ///保证映射后的坐标在原图像列范围内
					{  
						dstdata[tempj] = srcdata[tempy];
						dstdata[tempj + 1] = srcdata[tempy + 1];
						dstdata[tempj + 2] = srcdata[tempy + 2];
					}
					else
					{   ////列平移出去的区域用0或255填充                    
						dstdata[tempj] = FillValue;
						dstdata[tempj + 1] = FillValue;
						dstdata[tempj + 2] = FillValue;
					}
				}
			}
			else
			{    ////行平移出图像的区域用0填充
				uchar* dstdata = dst.ptr(i);
				for (int j = 0; j < Cols; j++)
				{
					tempj = 3 * j;   
					dstdata[tempj] = FillValue;
					dstdata[tempj + 1] = FillValue;
					dstdata[tempj + 2] = FillValue;
				}
			}
		}
	}
/////------亚像素级平移,用双线性插值算法---------
	if ((dx - (int)dx) != 0 || (dy - (int)dy)!= 0 )  
	{
		int y,x;
		double u,v;
		for (int i = 0; i < Rows; i++)
		{ 
			x = i - dx;               ///平移后坐标映射到原图像,x行,
			u = i - dx - x;           ///行平移的小数部分  
			if (x >= 0 && x < Rows - 1)   ///保证映射后的坐标在原图像范围内       
			{
				uchar* srcdata = src.ptr(x);
				uchar* srcdata1 = src.ptr(x + 1);
				uchar* dstdata = dst.ptr(i);
				for (int j = 0; j < Cols; j++)
				{ 
					y = j - dy;      //平移后坐标映射到原图像,y列
					v = j - dy - y;  ///列平移的小数部分  
					tempj = 3 * j;   ////彩色图像横坐标的位置
					tempy = 3 * y;
					if ( y >= 0 &&  y < Cols - 1)   ///保证映射后的坐标在原图像范围内
					{     ///////双线性插值法
						dstdata[tempj] = (1 - u) * (1 - v) * srcdata[tempy] + (1 - u) * v * srcdata[tempy + 3] 
						                 + u * (1 - v) * srcdata1[tempy] + u * v * srcdata1[tempy + 3];

						dstdata[tempj + 1] = (1 - u) * (1 - v) * srcdata[tempy + 1] + (1 - u) * v * srcdata[tempy + 4] 
						                 + u * (1 - v) * srcdata1[tempy + 1] + u * v * srcdata1[tempy + 4];

						dstdata[tempj + 2] = (1 - u) * (1 - v) * srcdata[tempy + 2] + (1 - u) * v * srcdata[tempy + 5] 
						                 + u * (1 - v) * srcdata1[tempy + 2] + u * v * srcdata1[tempy + 5];;
					}
					else
					{   ////列平移出去的区域用0或255填充                    
						dstdata[tempj] = FillValue;
						dstdata[tempj + 1] = FillValue;
						dstdata[tempj + 2] = FillValue;
					}
				}
			}
			else
			{    ////行平移出图像的区域用0或255填充
				uchar* dstdata = dst.ptr(i);
				for (int j = 0; j < Cols; j++)
				{
					tempj = 3 * j;   
					dstdata[tempj] = FillValue;
					dstdata[tempj + 1] = FillValue;
					dstdata[tempj + 2] = FillValue;
				}
			}
		}
		
	}
}



你可能感兴趣的:(亚像素图像图像平移)