图像的几何平移包括水平平移和垂直平移,这里实现的是水平与垂直两个方向都进行平移,其原理是:x和y分别是图像的横坐标与纵坐标,(x1,y1)是变换前的图像坐标,(x,y)是变换后的坐标,设dx是水平偏移量,dy是垂直偏移量,它们的关系是,
x=x1+dx
y=y1+dy //实际所变换的并不是坐标,而是坐标点的RGB值
这个关系式的含义是,将点(x,y)的RGB值替换为点(x1,y1)的RGB值,对于超出图像显示区域的点采用直接丢弃的办法,x<dx或y<dy的点RGB值置0。
完整代码:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat image=imread("T1.jpg");
namedWindow("image");
imshow("image",image); //显示原图
waitKey(0);
Point pt;
pt.x=image.cols-1; //最后一个像素点横坐标
pt.y=image.rows-1; //最后一个像素点纵坐标
for (;pt.x>=0;pt.x--)
{
for (pt.y=image.rows-1;pt.y>=0;pt.y--)
{
if (pt.x-50>=0 && pt.y-50>=0) //偏移量是50
{
image.at<Vec3b>(pt.y,pt.x)=image.at<Vec3b>(pt.y-50,pt.x-50);
//image.at<Vec3b>(Point(pt.x,pt.y))=image.at<Vec3b>(Point(pt.x-50,pt.y-50));
}
else
{
image.at<Vec3b>(pt.y,pt.x)=0;
//image.at<Vec3b>(Point(pt.x,pt.y))=0;
}
}
}
namedWindow("Pingyi");
imshow("Pingyi",image);
waitKey(0);
//cout<<image.at<Vec3b>(681,69)<<endl; //输出像素点的RGB值
//cout<<image.at<Vec3b>(Point(69,681))<<endl;
system("pause");
return 0;
}
需要注意的是,在使用Mat::at<_TP>()函数访问像素点时,Mat::at<_TP>(x,y)访问的是第x行第y列位置的像素点,并不是访问坐标为(x,y)的点,而是坐标为(y,x)的点,即横坐标值为y,纵坐标值为x的点,
图像的坐标系是原点在左上角,x轴为横向向右,y轴是垂直向下,点的坐标表示是(x,y),这都跟我们平时接触的坐标系中坐标表示相差无几。只是在使用Mat::at<_TP>()函数时要注意一下,如果我们想访问点(x,y),可以这样Mat::at<_TP>(y,x)或Mat::at<_TP>(Point(x,y)),二者是等价的。可以在上面的程序的最后用两种方法输出指定点的RGB值试验一下。
在程序中,进行像素点RGB值变换使用的是按列变换,内层for循环执行的是从一列最下面的点开始变换,要注意一下点的坐标范围。
实验结果,