OpenCV将图像旋转180度

OpenCV将图像旋转90度的倍数,如90度、180度、270度,一般有两种方式:(1) 使用transpose()和flip()两个函数的组合;(2) OpenCV3 以后可以使用rotate()函数实现图像旋转。

1. transpose() + flip()

transpose()实现矩阵的转置,定义如下:

void cv::transpose( InputArray _src, OutputArray _dst )

flip()实现图像的翻转,定义如下:

@param src input array.
@param dst output array of the same size and type as src.
@param flipCode a flag to specify how to flip the array; 0 means
flipping around the x-axis and positive value (for example, 1) means
flipping around y-axis. Negative value (for example, -1) means flipping
around both axes.
*/
CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);

代码中已经解释得非常清楚,根据参数flipCode的不同,实现不同方向的翻转:0 - 沿X轴翻转,正整数 - 沿Y轴翻转,负整数 - 沿X、Y轴翻转。flipCode为负数时,相当于将图像旋转180度。

接下来我们就用这两个函数的组合分别实现图像的90度、180度、270度旋转。

定义旋转函数rotateImage(),根据输入的旋转度数实现图像90度倍数的旋转。

void rotateImage(Mat &src_img, int degree, Mat &des_img)
{
	Mat img_transpose, img_flip;
	
	switch(degree)
	{
		case 90:
		{
			transpose(src_img, img_transpose);
			imshow("img_transpose", img_transpose);
			waitKey(0);
			flip(img_transpose, img_flip, 1);
			
			break;
		}
		case 180:
		{
			flip(src_img, img_flip, -1);
			
			break;
		}
		case 270:
		{
			transpose(src_img, img_transpose);
			flip(img_transpose, img_flip, 0);
			
			break;
		}
		default:
		{
			printf("The input degree is invalid. \n");
			
			img_flip = src_img;
			
			break;
		}	
	}
	
	img_flip.copyTo(des_img);

}

在主函数中调用该旋转函数,为了统计旋转算法的耗时,封装了一个计算时间的函数get_time_interval(),精确到毫秒。

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <ctime>
#include <opencv2/opencv.hpp>
#include <opencv2/video/video.hpp>
#include "opencv/cv.h"
#include "opencv/cxcore.h"

using namespace cv;
using namespace std;

// Calculate time interval between current and t_start
int64_t get_time_interval(struct timeval t_start)
{
	struct timeval t_curr;
	gettimeofday(&t_curr, NULL);
	return  (t_curr.tv_sec * 1000) + (t_curr.tv_usec / 1000) - ((t_start.tv_sec * 1000) + (t_start.tv_usec / 1000));
}


int main()
{
	Mat Img = imread("muyangnv.jpg");
	
	imshow("Img", Img);
	
	Mat outImg_90, outImg_180, outImg_270, outImg_other;
	
	struct timeval t_start;
	int64_t t_end;
	
	/********************************* 90 *****************************************/
	/* Test rotate 90 degree */
	gettimeofday(&t_start, NULL);
	
	rotateImage(Img, 90, outImg_90);
	
	t_end = get_time_interval(t_start);
	printf("Image rotate 90 degree uses %ld ms \n", t_end);
	
	/* Save to local storage */
	imwrite("outImg_90.bmp", outImg_90);
	
	
	/********************************* 180 *****************************************/
	/* Test rotate 180 degree */
	gettimeofday(&t_start, NULL);
	
	rotateImage(Img, 180, outImg_180);
	
	t_end = get_time_interval(t_start);
	printf("Image rotate 180 degree uses %ld ms \n", t_end);
	
	imwrite("outImg_180.bmp", outImg_180);
	
	
	/******************************** 270 ******************************************/
	/* Test rotate 270 degree */
	gettimeofday(&t_start, NULL);
	
	rotateImage(Img, 270, outImg_270);
	
	t_end = get_time_interval(t_start);
	printf("Image rotate 270 degree uses %ld ms \n", t_end);

	imwrite("outImg_270.bmp", outImg_270);
	
	
	/******************************** other ******************************************/
	/* Test rotate other degree */
	rotateImage(Img, 50, outImg_other);
		
	imwrite("outImg_other.bmp", outImg_other);
	
	return 0;
}

来来,用一张博主的私照来做个测试,时间统计结果为,每组旋转算法耗时均为1ms。

原图

 

旋转90度
旋转180度
旋转270度

 

2. rotate()

该函数在我使用OpenCV 3.4.7的时候存在,而在2.4.9上是没有的。函数相关的声明如下:

enum RotateFlags {
    ROTATE_90_CLOCKWISE = 0, //!<Rotate 90 degrees clockwise
    ROTATE_180 = 1, //!<Rotate 180 degrees clockwise
    ROTATE_90_COUNTERCLOCKWISE = 2, //!<Rotate 270 degrees clockwise
};

/** @brief Rotates a 2D array in multiples of 90 degrees.
The function cv::rotate rotates the array in one of three different ways:
*   Rotate by 90 degrees clockwise (rotateCode = ROTATE_90_CLOCKWISE).
*   Rotate by 180 degrees clockwise (rotateCode = ROTATE_180).
*   Rotate by 270 degrees clockwise (rotateCode = ROTATE_90_COUNTERCLOCKWISE).
@param src input array.
@param dst output array of the same type as src.  The size is the same with ROTATE_180,
and the rows and cols are switched for ROTATE_90_CLOCKWISE and ROTATE_90_COUNTERCLOCKWISE.
@param rotateCode an enum to specify how to rotate the array; see the enum #RotateFlags
@sa transpose , repeat , completeSymm, flip, RotateFlags
*/
CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode);

从以上声明可以看出,通过一个函数即可实现对图像90度、180度、270度(即-90度)的旋转,至于好不好用,我们来试验一下:

int main()
{
        Mat Img = imread("muyangnv.jpg");

        imshow("Img", Img);

        Mat outImg_90, outImg_180, outImg_270, outImg_other;

        rotate(Img, outImg_90, ROTATE_90_CLOCKWISE);
        imwrite("rotate90.bmp", outImg_90);
        
        rotate(Img, outImg_180, ROTATE_180);
        imwrite("rotate180.bmp", outImg_180);
        
        rotate(Img, outImg_270, ROTATE_90_COUNTERCLOCKWISE);
        imwrite("rotate270.bmp", outImg_270);

        return 0;
}

旋转90度、180度、270度的结果如下,跟第一种方法是一样的效果,由于一个函数搞定,简洁了很多。

发布了56 篇原创文章 · 获赞 56 · 访问量 13万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章