以前在做图像处理的时候用到了图像的旋转,opencv自带的flip函数只能180度,因为需要旋转任意角度,顺时针和逆时针的情况,所以去找了些效果比较好的函数来实现。网上有的旋转函数有内存泄露的现象,现在把修改过我用过的无内存泄露的函数分享一下:
一:
void cvRotate(IplImage* src,int angle) { IplImage * dst = 0; dst = cvCloneImage (src); double delte = 1.0; double factor = 1.0; float m[6]; CvMat M = cvMat( 2, 3, CV_32F, m ); int w = src->width; int h = src->height; m[0] = (float)(factor*cos(-angle*2*CV_PI/180.)); m[1] = (float)(factor*sin(-angle*2*CV_PI/180.)); m[2] = w*0.5f; m[3] = -m[1]; m[4] = m[0]; m[5] = h*0.5f; cvZero (dst); cvGetQuadrangleSubPix( src, dst, &M); *src = *dst; }
二:
IplImage* cvRotate2(IplImage* src,IplImage * dst ) { double delte = 1.0; double factor =1.0; float m[6]; int angle =90; int tempLength = (int)sqrt(float(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; IplImage* temp = cvCreateImage(cvSize(src->width,src->height), src->depth, src->nChannels); cvZero(temp); cvCopy(src, temp, NULL); int w = temp->width; int h = temp->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; CvMat M = cvMat(2, 3, CV_32F, m); cvGetQuadrangleSubPix( temp,dst, &M); cvReleaseImage(&temp); return dst; }
三:
IplImage *cvRotate(IplImage *imgSrc) { double degree = 270; // rotate 30 degree double angle = degree * CV_PI / 180.; // angle in radian double a = sin(angle), b = cos(angle); // sine and cosine of angle int w_src = imgSrc->width; int h_src = imgSrc->height; 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) ); return imgDst; }
四:
cvTranspose( const CvArr* src, CvArr* dst );的使用
五:推荐
void cvRotate(IplImage* img,IplImage *img_rotate,int degree) { //旋转中心为图像中心 CvPoint2D32f center; center.x=float (img->width/2.0+0.5); center.y=float (img->height/2.0+0.5); //计算二维旋转的仿射变换矩阵 float m[6]; CvMat M = cvMat( 2, 3, CV_32F, m ); cv2DRotationMatrix( center, degree,1, &M); //变换图像,并用黑色填充其余值 cvWarpAffine(img,img_rotate, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) ); }