图像旋转算法的实现

上一篇转载的文章(http://blog.csdn.net/carson2005/article/details/36900161)介绍了图像旋转的原理,这里给出代码实现,具体原理请参考上面的链接;

实现代码:

void ImgRotate(cv::Mat imgIn, float theta, cv::Mat& imgOut)
{
	int oldWidth = imgIn.cols;
	int oldHeight = imgIn.rows;

	// 源图四个角的坐标(以图像中心为坐标系原点)
	float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;
	fSrcX1 = (float) (- (oldWidth  - 1) / 2);
	fSrcY1 = (float) (  (oldHeight - 1) / 2);
	fSrcX2 = (float) (  (oldWidth  - 1) / 2);
	fSrcY2 = (float) (  (oldHeight - 1) / 2);
	fSrcX3 = (float) (- (oldWidth  - 1) / 2);
	fSrcY3 = (float) (- (oldHeight - 1) / 2);
	fSrcX4 = (float) (  (oldWidth  - 1) / 2);
	fSrcY4 = (float) (- (oldHeight - 1) / 2);

	// 旋转后四个角的坐标(以图像中心为坐标系原点)
	float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;
	fDstX1 =  cos(theta) * fSrcX1 + sin(theta) * fSrcY1;
	fDstY1 = -sin(theta) * fSrcX1 + cos(theta) * fSrcY1;
	fDstX2 =  cos(theta) * fSrcX2 + sin(theta) * fSrcY2;
	fDstY2 = -sin(theta) * fSrcX2 + cos(theta) * fSrcY2;
	fDstX3 =  cos(theta) * fSrcX3 + sin(theta) * fSrcY3;
	fDstY3 = -sin(theta) * fSrcX3 + cos(theta) * fSrcY3;
	fDstX4 =  cos(theta) * fSrcX4 + sin(theta) * fSrcY4;
	fDstY4 = -sin(theta) * fSrcX4 + cos(theta) * fSrcY4;

	int newWidth  = ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5);
	int newHeight = ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) )  + 0.5);

	imgOut.create(newHeight, newWidth, imgIn.type());

	float dx = -0.5*newWidth*cos(theta) - 0.5*newHeight*sin(theta) + 0.5*oldWidth;
	float dy = 0.5*newWidth*sin(theta) - 0.5*newHeight*cos(theta) + 0.5*oldHeight;

	int x,y;
	for (int i=0; i<newHeight; i++)
	{
		for (int j=0; j<newWidth; j++)
		{
			x = float(j)*cos(theta) + float(i)*sin(theta) + dx;
			y = float(-j)*sin(theta) + float(i)*cos(theta) + dy;

			if ((x<0) || (x>=oldWidth) || (y<0) || (y>=oldHeight))
			{
				if (imgIn.channels() == 3)
				{
					imgOut.at<cv::Vec3b>(i,j) = cv::Vec3b(0,0,0);
				}
				else if (imgIn.channels() == 1)
				{
					imgOut.at<uchar>(i,j) = 0;
				}
			}
			else
			{
				if (imgIn.channels() == 3)
				{
					imgOut.at<cv::Vec3b>(i,j) = imgIn.at<cv::Vec3b>(y,x);
				}
				else if (imgIn.channels() == 1)
				{
					imgOut.at<uchar>(i,j) = imgIn.at<uchar>(y,x);
				}
			}
		}
	}
}

测试代码:

void ImgRotateTest()
{
	cv::Mat srcImg = cv::imread("test.jpg");
	if (srcImg.empty())
	{
		printf("srcImg load error \n");
		system("pause");
		exit(-1);
	}

	float angle = 30.0f*3.1415926/180.0f;

	cv::Mat dstImg;
	ImgRotate(srcImg, angle, dstImg);
	cv::imwrite("result.jpg", dstImg);
	cv::imshow("src", srcImg);
	cv::imshow("dst", dstImg);
	cv::waitKey(0);

}

测试结果:

图像旋转算法的实现,布布扣,bubuko.com

时间: 2024-08-24 00:16:48

图像旋转算法的实现的相关文章

基于《Combining Sketch and Tone for Pencil Drawing Production》的图像铅笔画算法的实现

一,借鉴: 本文借鉴了CSDN博主风吹夏天对此论文算法的理解:风吹夏天的图像铅笔画算法,以及香港中文大学Cewu Lu等人写的该论文的主页.原文作者和博主风吹夏天都给过代码,但是代码不全.我仔细看了原论文和该博主的文章后,基本上,大致算法思想就理通了.本文对于具体算法细节就不细述了,个人建议还是先进行原论文的研读,对该论文所进行的步骤先有个大致的了解. 二,算法思路 1,首先需要产生笔画结构 大致思路:对原图像进行梯度运算,得出大致轮廓 -----> 设计8个方向的卷积核,并依据论文中的公式对像

Canny边缘检测算法的实现

Canny原理 Canny的原理就不细说了,冈萨雷斯的<数字图像处理>(第三版)P463~465讲解的比较清楚,主要就四个步骤: 1. 对图像进行高斯滤波 2. 计算梯度大小和梯度方向 3. 对梯度幅值图像进行非极大抑制 4. 双阈值处理和连接性分析(通常这一步与非极大抑制并行,详见下面的代码) 下面重点说一下非极大抑制. 非极大抑制 对一幅图像计算梯度大小和梯度方向后,需要进行非极大抑制,一般都是通过计算梯度方向,沿着梯度方向,判断该像素点的梯度大小是否是极大值.这里主要说一下方向的判断.

Bug2算法的实现(RobotBASIC环境中仿真)

移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不能看几遍就理解理论中的奥妙,只能在别人大谈XX理论XX算法的时候,自己一个人苦逼的面对错误的程序问为什么... 下面开始动手来实现一下简单的Bug2避障算法.由于算法中涉及到机器人与外界环境的交互,因此需要选择一个仿真软件.常用的移动机器人仿真软件主要有Gazebo.V-rep.Webots.MRD

用OpenCV实现Photoshop算法(一): 图像旋转

最近学习了OpenCV,于是想用它实现Photoshop的主要功能,用于照片处理. 对于一张照片,PS的一般处理步骤包括: 1, 旋转图片,校正位置. 2,剪切,调整大小,重新构图. 3,调整色阶.曲线,使图片曝光正确.对比适中. 4,调整对比度.饱和度 5,印章去掉不想要的东西,液化调整形体线条 6,对于人像图片,美肤.美白 7, 用色彩平衡.可选颜色等调整色调,形成照片调性 8,加一些光效 9,锐化 以后的一系列博文将采用OpenCV逐一实现Photoshop的算法和功能, 并用计算机视觉人

万年历算法的实现(C语言--gcc编译)

/** cal.c * * 现行的格里历是从儒略历演化而来的.儒略历每4年一个润年,润年366天,平年365天.* 如果从公元1年算的话,那么凡是能够被4整除的都是润年.从天文角度看,儒略历这种 * 历法是有误差的,到16世纪误差已经达到了10天.1582年,罗马教皇对儒略历进行了 * 一次校定,该年的10-5到10-14这10天被抹掉,并规定凡不能被400整除的世纪年不再 * 算为润年,校定之后的儒略历即为现行的格里历. * * 但是英国直到1752年才开始使用格里历,此时时间误差已经达到了1

搜索引擎--范例:中英文混杂分词算法的实现--正向最大匹配算法的原理和实现

纯中文和中英文混杂的唯一区别是,分词的时候你如何辨别一个字符是英文字符还是孩子字符, 人眼很容易区分,但是对于计算机来说就没那么容易了,只要能辨别出中文字符和英文的字符,分词本身就不是一个难题 1:文本的编码问题: utf8:windows下,以utf8格式保存的文本是一个3个字节(以16进制)的BOM的,并且你不知道一个汉字是否是用3位表示,但是英文适合ascii编码一样的 ascii:英文一位,中文两位,并且中文的第一个字节的值是大于128和,不会和英文混淆,推荐 unicode:中文基本是

每日算法之三十七:Rotate Image (图像旋转)

You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place? 原地图像顺时针旋转90度.因为要求空间复杂度是常数,因此应该迭代旋转操作. class Solution { public: void rotate(vector<vector<int> > &mat

opencv-从图像旋转学习Mat数据访问

先看一个简单的例子 代码: // ConsoleApplication3_6_23.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include<opencv2/opencv.hpp> #include<iostream> #include<vector> using namespace std; using namespace c

探讨排序算法的实现

排序算法是我们工作中使用最普遍的算法,常见的语言库中基本都会有排序算法的实现,比如c标准库的qsort,stl的sort函数等.本文首先介绍直接插入排序,归并排序,堆排序,快速排序和基数排序等比较排序算法,然后介绍计数排序,基数排序等具有线性时间的排序算法.本文主要讨论算法的实现方法,并不会过多介绍基本理论. 评价一个排序算法优劣适用与否,一般需要从三个方面来分析 时间复杂度.用比较操作和移动操作数的最高次项表示,由于在实际应用中最在乎的是运行时间的上限,所以一般取输入最坏情况的下的运行时间作为