1.图像旋转
如图所示
点(x1,y1)顺时针旋转a角度得到点(x2,y2),两点之间的关系可以很容易的出来。
同理,将图像整个顺时针旋转a角度,只要将旋转之后图像每个点对应到原图中,将像素值赋值过去,可以得到旋转之后的图像。
但我们会注意到原图像旋转后会超出图像边界,需要重新定义图像大小,同时将坐标系向左平移。(x1,y1)为坐标系下的点,(x2,y2)为旋转后新的坐标系下对应的点。
他们之间的关系如下所示:
根据以上公式编写程序,将原图坐标点映射到旋转后的图像中,并赋值对应像素点
原图------->>旋转图 主要程序如下:
void rotate(IplImage* pic1,IplImage** pic0,double degree) { double angle=degree*CV_PI/180; //转化弧度制 double a=fabs(sin(angle)),b=fabs(cos(angle)); int width_1=pic1->width; int height_1=pic1->height; int width_2=int(width_1*b+height_1*a); int heihgt_2=int(width_1*a+height_1*b); IplImage* pic2=cvCreateImage(cvSize(width_2,heihgt_2),8,1); int i,j,k; for (i=0;i<height_1;i++) //坐标变换 { uchar* ptr1=(uchar*)(pic1->imageData+i*pic1->widthStep); for (j=0;j<width_1;j++) { int x= int (i*b-j*a+height_1*a); int y= int (i*a+j*b); uchar* ptr2=(uchar*)(pic2->imageData+x*pic2->widthStep); if (x>0&&y>0) { ptr2[y]=ptr1[j]; } } } *pic0=pic2; }
运行后效果如下:
发现旋转后的图中有白色的小点,分析得知是因为取整时舍去了这些点。
反过来遍历旋转之后的图去找原图,程序如下所示:
旋转图 ------->> 原图
void rota(IplImage* pic1,IplImage** pic0,double degree){ double angle=degree*CV_PI/180; //转化弧度制 double a=fabs(sin(angle)),b=fabs(cos(angle)); int width_1=pic1->width; int height_1=pic1->height; int width_2=int(width_1*b+height_1*a); int heihgt_2=int(width_1*a+height_1*b); IplImage* pic2=cvCreateImage(cvSize(width_2,heihgt_2),8,1); int i,j,k; for (i=0;i<heihgt_2;i++) //坐标变换 { uchar* ptr2=(uchar*)(pic2->imageData+i*pic2->widthStep); for (j=0;j<width_2;j++) { k=i-height_1*a; int x= int (k*b+j*a); int y= int (-k*a+j*b); uchar* ptr1=(uchar*)(pic1->imageData+x*pic1->widthStep); if (x>0&&y>0) { //if(x<width_1+16&&y<=height_1+16) ptr2[j]=ptr1[y]; } } } *pic0=pic2; }
程序并未对四块边角做出剔除,可以看到多余部分也会有图像。