opencv图像旋转

转自:http://download.youkuaiyun.com/source/2642701

/* 程序名:rotate.c
功能:读入图像文件,做图像旋转转,然后显示图像在屏幕上
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>

void myRotate(IplImage *img, int x, int y, float degree,int center[2]);


int main(int argc, char *argv[])
{
IplImage* img = 0;
int height,width,step,channels;
uchar *data;
int center[2]={0,0};
argv[1]="d://a_base_1.jpg";
//请自己添加图像文件路径

img=cvLoadImage(argv[1],1);
if(!img)
{
printf("Could not load image file: %s/n",argv[1]);
exit(0);
}
// 获取图像信息
height = img->height;
width = img->width;
step = img->widthStep;
channels = img->nChannels;
data = (uchar *)img->imageData;
printf("Processing a %dx%d image with %d channels/n",height,width,channels);

// 创建窗口
cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
cvMoveWindow("mainWin", 100, 100);

center[0]=width/2;//这两句可以设置旋转中心的坐标
center[1]=height/2;

// 反转图像
myRotate(img,0,0,-1,center);
// 显示图像
cvShowImage("mainWin", img );
cvWaitKey(0);
cvReleaseImage(&img );
return 0;
}

void myRotate(IplImage *img, int x, int y, float degree,int center[2])
{

double angle = degree * CV_PI / 180.; // angle in radian
double a = sin(angle), b = cos(angle); // sine and cosine of angle
IplImage* imgSrc=cvCloneImage(img);
int w_src = imgSrc->width;
int h_src = imgSrc->height;

// Make w_dst and h_dst to fit the output image
//int w_dst = int(h_src * a + w_src * b);
//int h_dst = int(w_src * a + h_src * b);
//int w_dst = int(h_src * abs(a) + w_src * abs(b));
// int h_dst = int(w_src * abs(a) + h_src * abs(b));

// map matrix for WarpAffine, stored in statck array
double map[6];
CvMat map_matrix = cvMat(2, 3, CV_64FC1, map);

// Rotation center needed for cv2DRotationMatrix
CvPoint2D32f pt = cvPoint2D32f(center[0], center[1]);
cv2DRotationMatrix(pt, degree, 1.0, &map_matrix);

// otherwise you will get only part of the result
map[2] +=x;
map[5] +=y;

// We need a destination image
cvWarpAffine(
imgSrc,
img,
&map_matrix,
CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS,
cvScalarAll(0)
);
}

转自:http://www.cnblogs.com/HappyXie/archive/2011/03/02/1969434.html

//OpenCV 4 下的图像任意角度的旋转

//需要inter公司的OpenCV的支持.

//OpenCV 4下的图像任意角度的旋转
//待旋转的图像IplImage* Img_old
//返回的旋转后图像 IplImage* Img_tmp.
//旋转的角度,单位度.
//三种不同的方法.其中方法二没有完全测试,方法一可以满足大部分需要
//Vastsky - Nercita 2005 6 12
//vastsky_sun#126.com
IplImage * CCropMeasureView::FitRotate (IplImage* Img_old, double angle,int method)

{

IplImage* Img_tmp = NULL;

double anglerad = (CV_PI* (angle/180)) ;
int newheight =int (fabs(( sin(anglerad)*Img_old->width )) + fabs(( cos(anglerad)*Img_old->height )) );
int newwidth =int (fabs(( sin(anglerad)*Img_old->height)) + fabs(( cos(anglerad)*Img_old->width)) );

Img_tmp = cvCreateImage(cvSize(newwidth,newheight), IPL_DEPTH_8U, 3);
cvFillImage(Img_tmp,0);//目的图像 使用扩展的大小

IplImage* dst = cvCloneImage( Img_old );//目的图像 与原图像等大


float m[6];
CvMat M = cvMat( 2, 3, CV_32F, m );


if(1==method)
{
//方法一 提取象素四边形,使用子象素精度

int w = Img_old->width;
int h = Img_old->height;

m[0] = (float)(cos(angle*CV_PI/180.));
m[1] = (float)(sin(angle*CV_PI/180.));
m[2] = w*0.5f;
m[3] = -m[1];
m[4] = m[0];
m[5] = h*0.5f;

cvGetQuadrangleSubPix( Img_old, dst, &M, 1, cvScalarAll(0));

cvGetQuadrangleSubPix( Img_old, Img_tmp, &M, CV_INTER_LINEAR, cvScalarAll(0));//+CV_WARP_FILL_OUTLIERS

//方法一 提取象素四边形,使用子象素精度
}

if(2==method)
{
//方法二 使用 二维旋转的仿射变换矩阵 存在问题 要求输入和输出图像一样大 旋转中心不对

CvPoint2D32f center;
center.x=float (Img_old->width/2.0+0.5);//float (Img_tmp->width/2.0+0.5);
center.y=float (Img_old->height/2.0+0.5);//float (Img_tmp->height/2.0+0.5);
cv2DRotationMatrix( center, angle,1, &M);

cvWarpAffine( Img_old, dst, &M,CV_INTER_LINEAR,cvScalarAll(0) );//小图
//小目标图像


//对图像进行扩展
// 只能一定角度以内 不同象限的不同对待
int dx=int((newwidth -Img_old->width )/2+0.5);
int dy=int((newheight-Img_old->height)/2+0.5);

uchar* old_ptr,*temp_ptr;

for( int y=0 ; y<Img_old->height; y++) //为了不越界
{
for (int x=0 ; x< Img_old->width; x++)
{
old_ptr = &((uchar*)(Img_old->imageData + Img_old->widthStep*y))[(x)*3];
temp_ptr = &((uchar*)(Img_tmp->imageData + Img_tmp->widthStep*(y+dy)))[(x+dx)*3];
temp_ptr[0]=old_ptr[0]; //green
temp_ptr[1]=old_ptr[1]; //blue
temp_ptr[2]=old_ptr[2]; //Red
}
}


center.x=float (Img_tmp->width/2.0+0.5);
center.y=float (Img_tmp->height/2.0+0.5);
cv2DRotationMatrix( center, angle,1, &M);

IplImage* temp = cvCloneImage( Img_tmp );//生成输出图像
cvWarpAffine( Img_tmp, temp , &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );//大图
Img_tmp=cvCloneImage( temp );

//问题
//cvWarpAffine( Img_tmp, Img_tmp, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );//大图

//方法二 使用 二维旋转的仿射变换矩阵
}

if(3==method)
{
//方法三 透视变换
CvPoint2D32f src_point[4];
CvPoint2D32f dst_point[4];

src_point[0].x=0.0; src_point[0].y=0.0;
src_point[1].x=0.0; src_point[1].y=(float) Img_old->height;
src_point[2].x=(float) Img_old->width; src_point[2].y=(float) Img_old->height;
src_point[3].x=(float) Img_old->width; src_point[3].y=0.0;


dst_point[0].x=0;
dst_point[0].y=(float) fabs(( sin(anglerad)*Img_old->width ));

dst_point[1].x=(float) fabs(( sin(anglerad)*Img_old->height));
dst_point[1].y=(float) fabs(( sin(anglerad)*Img_old->width ))+(float) fabs(( cos(anglerad)*Img_old->height));

dst_point[2].x=(float) fabs(( sin(anglerad)*Img_old->height))+(float) fabs(( cos(anglerad)*Img_old->width));
dst_point[2].y=(float) fabs(( cos(anglerad)*Img_old->height));

dst_point[3].x=(float) fabs(( cos(anglerad)*Img_old->width));
dst_point[3].y=0;


float newm[9];
CvMat newM = cvMat( 3, 3, CV_32F, newm );
cvWarpPerspectiveQMatrix(src_point,dst_point,&newM);

cvWarpPerspective(Img_old,dst,&newM,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0) );
cvWarpPerspective(Img_old,Img_tmp,&newM,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0) );

//方法三 透视变换
}


// cvNamedWindow( "dst_litter", 1 );
// cvShowImage( "dst_litter", dst );


// cvNamedWindow( "dst_big", 1 );
// cvShowImage( "dst_big", Img_tmp );

return Img_tmp;

}

其他参考博客:

1、 http://cau.anzhi.blog.163.com/blog/static/125775520084240205820/

2、 http://blog.youkuaiyun.com/hunnish/article/details/1370998

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值