#include "cv.h"
#include "highgui.h"
using namespace cv;
#define PI 3.1415926
#define RADIAN(angle) ((angle)*PI/180.0)
//平移
void Translate(Mat& image,int xOffset,int yOffset)
{
int M=image.rows;
int N=image.cols;
Mat temp=image.clone();
for(int i=0;i<M;i++)
{
uchar* p=image.ptr<uchar>(i);
memset(p,0,N);
}
for(int i=0;i<M;i++)
{
int newi=i-xOffset;
if(newi<0||newi>=M)
continue;
uchar* p=image.ptr<uchar>(i);
uchar* p1=temp.ptr<uchar>(newi);
int j=0;
while(j<M)
{
if(j-yOffset>=0)
{
memcpy(p+j,p1+j-yOffset,min(N-j,N-j+yOffset));
break;
}
j++;
}
}
}
//旋转
Mat Rotate(Mat& image,int angle)
{
int M=image.rows;
int N=image.cols;
//角度到弧度的转换
float rotateAngle=(float)RADIAN(angle);
float cosa=(float)cos((double)rotateAngle);
float sina=(float)sin((double)rotateAngle);
//原图四个角坐标
float srcX1=(float)(-0.5*N),srcY1=(float)(0.5*M);
float srcX2=(float)(0.5*N),srcY2=(float)(0.5*M);
float srcX3=(float)(-0.5*N),srcY3=(float)(-0.5*M);
float srcX4=(float)(0.5*N),srcY4=(float)(-0.5*M);
//新图四个角坐标
float dstX1=cosa*srcX1+sina*srcY1,dstY1=-sina*srcX1+cosa*srcY1;
float dstX2=cosa*srcX2+sina*srcY2,dstY2=-sina*srcX2+cosa*srcY2;
float dstX3=cosa*srcX3+sina*srcY3,dstY3=-sina*srcX3+cosa*srcY3;
float dstX4=cosa*srcX4+sina*srcY4,dstY4=-sina*srcX4+cosa*srcY4;
//计算新图的宽度和高度
int newN=(int)(max(fabs(dstX4-dstX1),fabs(dstX3-dstX2))+0.5);
int newM=(int)(max(fabs(dstY4-dstY1),fabs(dstY3-dstY2))+0.5);
float num1=(float)(-0.5*newN*cosa-0.5*newM*sina+0.5*N);
float num2=(float)(0.5*newN*sina-0.5*newM*cosa+0.5*M);
Mat ret(newM,newN,CV_8U);
for(int y1=0;y1<newM;y1++)
{
for(int x1=0;x1<newN;x1++)
{
int x0=(int)(x1*cosa+y1*sina+num1);
int y0=(int)(-1.0f*x1*sina+y1*cosa+num2);
if(x0>=0&&x0<N&&y0>=0&&y0<M)
{
uchar* p=ret.ptr<uchar>(y1);
uchar* p1=image.ptr<uchar>(y0);
p[x1]=p1[x0];
}
}
}
return ret;
}
//镜像
void Mirror(Mat& image,bool flag)
{
int M=image.rows;
int N=image.cols;
//水平
if(flag)
{
for(int i=0;i<M;i++)
{
uchar* p=image.ptr<uchar>(i);
for(int j=0;j<N/2;j++)
{
uchar temp=p[j];
p[j]=p[N-j-1];
p[N-j-1]=temp;
}
}
}
else//垂直
{
for(int j=0;j<N;j++)
{
for(int i=0;i<M/2;i++)
{
uchar temp=image.ptr<uchar>(i)[j];
image.ptr<uchar>(i)[j]=image.ptr<uchar>(M-i-1)[j];
image.ptr<uchar>(M-i-1)[j]=temp;
}
}
}
}
//转置
Mat Transpose(Mat& image)
{
int M=image.rows;
int N=image.cols;
Mat ret(N,M,CV_8U);
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
ret.ptr<uchar>(i)[j]=image.ptr<uchar>(j)[i];
return ret;
}
//缩放
Mat Zoom(Mat& image,float ratio)
{
int M=image.rows;
int N=image.cols;
int newM=(int)(M*ratio+0.5);
int newN=(int)(N*ratio+0.5);
Mat ret(newM,newN,CV_8U);
for(int i=0;i<newM;i++)
{
for(int j=0;j<newN;j++)
{
#if 0
int x=(int)(i/ratio);
int y=(int)(j/ratio);
if(x>=0&&x<M&&y>=0&&y<N)
{
ret.ptr<uchar>(i)[j]=image.ptr<uchar>(x)[y]; //找最临近点 最邻近插值
}
#else
float x=i/ratio;
float y=j/ratio;
if(x>=0&&x<M-1&&y>=0&&y<N-1)
{
//双线性插值
int x1=(int)floor(x),x2=x1+1;
int y1=(int)floor(y),y2=y1+1;
int g=(image.ptr<uchar>(x1)[y2]-image.ptr<uchar>(x1)[y1])*(x-x1)+image.ptr<uchar>(x1)[y1];
int h=(image.ptr<uchar>(x2)[y2]-image.ptr<uchar>(x2)[y1])*(x-x1)+image.ptr<uchar>(x2)[y1];
ret.ptr<uchar>(i)[j]=(uchar)((h-g)*(y-y1)+g);
}
#endif
}
}
return ret;
}
int main()
{
//读取图像
Mat image;
image=imread("a.jpg",CV_LOAD_IMAGE_GRAYSCALE);
int M=image.rows;
int N=image.cols;
//几何变换
Mat newImage=Zoom(image,4);
cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
imshow("test",newImage);
waitKey(0);
return 0;
}
图像处理之几何变换
最新推荐文章于 2023-06-16 11:33:55 发布