http://blog.csdn.net/kezunhai
图像的几何变换又称为空间变换,它研究的是图像中的点与点直接的空间映射关系。几何变换包括平移、缩放、裁剪、旋转、翻转、转置、倾斜等。本文将介绍图像的平移。图像平移(Translate)是将图像中的所有点都按照指定的水平和垂直方向进行移动。
如下图所示:
将图像中的一点(x0,y0)沿水平平移tx,沿垂直方向平移ty到(x1, y1),用公式表示如下:
这样,平移后的图像上的没一点都可以在原图上找到对应的点,如对于(0,0)处的点,则对应于原图的(-tx, -ty),如果tx或ty大于0,则该点不在原图上。对于不在原图的点,可以将其统一设置为0或255;同样,若有点不在原图上,则说明原图中有点被移除显示区域,可以通过对新图的宽和高进行扩大,以确保原图数据不被丢失。
实现代码:
// 移除的区域填充255
// tx: X方向的平移量
// ty: Y方向的平移量
// flagWiden,是否扩大图像, -1:不扩大, 1:扩大
void PhotoShop::Translate(Mat& img, Mat& dst, int tx, int ty, int flagWiden)
{
if ( flagWiden == 1) // 扩大
{
if ( dst.empty())
dst.create(img.rows+abs(ty), img.cols+abs(tx), img.type());
}
else // 不扩大
{
if ( dst.empty())
dst.create(img.rows, img.cols, img.type());
}
int height = dst.rows;
int width = dst.cols;
int chns = dst.channels();
if ( flagWiden == -1)
{
if ( tx< -width || tx>width || ty<-height || ty> height) // 整个移出图像区域则直接返回
{
dst = cv::Scalar::all(0);
return;
}
}
int i, j;
int i0, j0;
for ( i=0; i<height; ++i)
{
i0 = i - ty;
if ( i0>=0 && i0<height)
{
unsigned char* srcData = (unsigned char*)img.data + img.step* i0;
unsigned char* dstData = (unsigned char*)dst.data + dst.step* i;
for ( j =0; j<width; ++j)
{
j0 = j - tx;
if ( j0>=0 && j0<width && i0>=0 && i0<height)
{
dstData[j*chns] = srcData[j0*chns];
dstData[j*chns+1] = srcData[j0*chns+1];
dstData[j*chns+2] = srcData[j0*chns+2];
}
else
{
dstData[j*chns] = dstData[j*chns+1] = dstData[j*chns+2] = 255;
}
}
}
else
{
unsigned char* dstData = (unsigned char*)dst.data + dst.step* i;
for ( j =0; j<width; ++j)
{
dstData[j*chns] = dstData[j*chns+1] = dstData[j*chns+2] = 255;
}
} // else
}// for i
}
不放大的效果:
当然,对于移除的区域还有很多其他的处理方法,如下面介绍的处理方法,有兴趣的朋友可以自己实践。
作者:kezunhai 出处:http://blog.csdn.net/kezunhai 欢迎转载或分享,但请务必声明文章出处。