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