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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章