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

opencv实现图像旋转

2014-05-31 17:22 453 查看
转自/article/7812049.html

1.旋转后图像变大,但是原图像部分保持不变

法1:

[cpp] view
plaincopy

#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:

[cpp] view
plaincopy

#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:

[cpp] view
plaincopy

<span style="color:#000000;">#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);

}</span>

法2:

[cpp] view
plaincopy

#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.图像大小不变,原图像内容也均保留,但是是由缩放所达到的

[cpp] view
plaincopy

#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;

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