以前在做图像处理的时候用到了图像的旋转,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) );
}