您的位置:首页 > 运维架构

opencv实现图像旋转

2012-03-21 22:11 357 查看
1.旋转后图像变大,但是原图像部分保持不变

法1:

#include "cv.h"
#include "highgui.h"

int main()
{
double degree = 30; // rotate 30 degree
double angle = degree  * CV_PI / 180.; // angle in radian
double a = sin(angle), b = cos(angle); // sine and cosine of angle

// Load source image as you wish
IplImage *imgSrc = cvLoadImage("l:\\test\\5.jpg");
int w_src = imgSrc->width;
int h_src = imgSrc->height;
cvNamedWindow ("src", 1);
cvShowImage ("src", imgSrc);
// Make w_dst and h_dst to fit the output image
int w_dst = int(h_src * fabs(a) + w_src * fabs(b));
int h_dst = int(w_src * fabs(a) + h_src * fabs(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(w_src / 2, h_src / 2);
cv2DRotationMatrix(pt, degree, 1.0, &map_matrix);

// Adjust rotation center to dst's center,
// otherwise you will get only part of the result
map[2] += (w_dst - w_src) / 2;
map[5] += (h_dst - h_src) / 2;

// We need a destination image

IplImage *imgDst = cvCreateImage(cvSize(w_dst, h_dst), 8, 3);
cvWarpAffine(
imgSrc,
imgDst,
&map_matrix,
CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS,
cvScalarAll(0)
);

// Don't forget to release imgSrc and imgDst if you no longer need them
cvNamedWindow( "dst_big", 1 );
cvShowImage( "dst_big", imgDst);
cvWaitKey(0);
cvReleaseImage(&imgSrc);
cvReleaseImage(&imgDst);
return 0;
}


法2:

#include "cv.h"
#include "highgui.h"
#include "math.h"

// clockwise 为true则顺时针旋转,否则为逆时针旋转
IplImage* rotateImage(IplImage* src, int angle, bool clockwise)
{
angle = abs(angle) % 180;
if (angle > 90)
{
angle = 90 - (angle % 90);
}
IplImage* dst = NULL;
int width =
(double)(src->height * sin(angle * CV_PI / 180.0)) +
(double)(src->width * cos(angle * CV_PI / 180.0 )) + 1;
int height =
(double)(src->height * cos(angle * CV_PI / 180.0)) +
(double)(src->width * sin(angle * CV_PI / 180.0 )) + 1;
int tempLength = sqrt((double)src->width * src->width + src->height * src->height) + 10;
int tempX = (tempLength + 1) / 2 - src->width / 2;
int tempY = (tempLength + 1) / 2 - src->height / 2;
int flag = -1;

dst = cvCreateImage(cvSize(width, height), src->depth, src->nChannels);
cvZero(dst);
IplImage* temp = cvCreateImage(cvSize(tempLength, tempLength), src->depth, src->nChannels);
cvZero(temp);

cvSetImageROI(temp, cvRect(tempX, tempY, src->width, src->height));
cvCopy(src, temp, NULL);
cvResetImageROI(temp);

if (clockwise)
flag = 1;

float m[6];
int w = temp->width;
int h = temp->height;
m[0] = (float) cos(flag * angle * CV_PI / 180.);
m[1] = (float) sin(flag * angle * CV_PI / 180.);
m[3] = -m[1];
m[4] = m[0];
// 将旋转中心移至图像中间
m[2] = w * 0.5f;
m[5] = h * 0.5f;
//
CvMat M = cvMat(2, 3, CV_32F, m);
cvGetQuadrangleSubPix(temp, dst, &M);
cvReleaseImage(&temp);
return dst;
}

int main(int argc, char **argv)
{
IplImage *src = 0;
IplImage *dst = 0;

int angle = 75;

src = cvLoadImage("L:\\Test\\6.JPG");

dst = rotateImage(src, angle, false);
cvNamedWindow("dst", 1);
cvShowImage("dst", dst);
cvWaitKey(0);

cvReleaseImage(&src);
cvReleaseImage(&dst);
return 0;
}


2.图像大小始终不变,实现裁剪

法1:

#include "cv.h"
#include "highgui.h"
#include "math.h"
void main( )
{
IplImage *Img_old=cvLoadImage("L:\\Test\\6.JPG");
IplImage* Img_tmp =cvCloneImage( Img_old);

int angle=45;
float m[6];
CvMat M = cvMat( 2, 3, CV_32F, m );
CvPoint2D32f center;
center.x=float (Img_old->width/2.0+0.5);
center.y=float (Img_old->height/2.0+0.5);
cv2DRotationMatrix( center, angle,1, &M);

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

cvNamedWindow ("src", 1);
cvShowImage ("src", Img_old);
cvNamedWindow( "dst", 1 );
cvShowImage( "dst", Img_tmp );

cvWaitKey(0);
cvReleaseImage(&Img_old);
cvReleaseImage(&Img_tmp);
}


法2:

#include "cv.h"
#include "highgui.h"
#include "math.h"
void main( )
{
IplImage *Img_old=cvLoadImage("L:\\Test\\6.JPG");
IplImage* Img_tmp = NULL;

int angle=45;
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);

//对图像进行扩展
//只能一定角度以内 不同象限的不同对待
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
}
}//这里去掉就不行了

float m[6];
CvMat M = cvMat( 2, 3, CV_32F, m );
CvPoint2D32f center;
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 );

cvNamedWindow ("src", 1);
cvShowImage ("src", Img_old);
cvNamedWindow( "dst", 1 );
cvShowImage( "dst", Img_tmp );
cvWaitKey(0);
cvReleaseImage(&Img_old);
cvReleaseImage(&Img_tmp);
}


3.图像大小不变,原图像内容也均保留,但是是由缩放所达到的

#include "cv.h"
#include "highgui.h"

int _tmain(int argc, _TCHAR* argv[])
{
CvPoint2D32f srcTri[3],dstTri[3];
CvMat* rot_mat=cvCreateMat(2,3,CV_32FC1);
CvMat* warp_mat=cvCreateMat(2,3,CV_32FC1);
IplImage *src,*dst;

if(argc==2 && ((src=cvLoadImage(argv[1],1))!=0))
{
dst=cvCloneImage(src);
dst->origin =src->origin ;
cvZero(dst);
//compute warp matrix
srcTri[0].x =0;                            //src top left
srcTri[0].y=0;
srcTri[1].x =src->width -1;         //src top right
srcTri[1].y=0;
srcTri[2].x=0;                            //src bottom left offset
srcTri[2].y=src->height -1;
dstTri[0].x=src->width *0.0;       //dst top left
dstTri[0].y=src->height *0.33;
dstTri[1].x=src->width *0.85;     //dst top right
dstTri[1].y=src->height *0.25;
dstTri[2].x=src->width *0.15;     //dst bottom left offset
dstTri[2].y=src->height *0.7;
cvGetAffineTransform(srcTri,dstTri,warp_mat);
cvWarpAffine(src,dst,warp_mat);
cvCopy(dst,src);
//compute rotation matrix
CvPoint2D32f center=cvPoint2D32f(src->width /2,src->height /2);
double angle=-50.0;
double scale=0.6;
cv2DRotationMatrix(center,angle,scale,rot_mat);
//do the transformation
cvWarpAffine(src,dst,rot_mat);
cvNamedWindow("Affine_Transform",1);
cvShowImage("Affine_Transform",dst);
cvWaitKey();
}

cvReleaseImage(&dst);
cvReleaseMat(&rot_mat);
cvReleaseMat(&warp_mat);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: