opencv实现图像任意角度旋转的算法解析及代码实现

原创 2015年11月20日 15:00:27

算法解析







程序实现

#include "CXCORE.h"
#include "cv.h"
#include "highgui.h"
using namespace cv;
IplImage*m_img;
double max(double a,double b)
{
return (a > b) ? a : b;
}
void ImgRotate(bool direction)
{
int oldWidth = m_img->width;
int oldHeight = m_img->height;


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


// 旋转后四个角的坐标(以图像中心为坐标系原点)  
float fDstX1, fDstY1, fDstX2, fDstY2, fDstX3, fDstY3, fDstX4, fDstY4;
float theta = 0.5*CV_PI*direction;
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)) );
int newHeight = (max(fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2)) );


IplImage*dst = cvCreateImage(cvSize(newWidth, newHeight), m_img->depth, m_img->nChannels);
//见旋转原理,行列式中第三行第一二列
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;
//读取新图片每一个点
for (int height = 0; height<newHeight; height++)
{
uchar*ptrNow = (uchar*)(dst->imageData + height*dst->widthStep);//指向图片的第height行第0列
for (int width = 0; width<newWidth; width++)
{
int x = float(width)*cos(theta) + float(height)*sin(theta) + dx;
int y = float(-width)*sin(theta) + float(height)*cos(theta) + dy;//对应原始图像的点
uchar*ptrOld = (uchar*)(m_img->imageData + y*m_img->widthStep);//指向原始图像的第y行第0列
if ((x<0) || (x >= oldWidth) || (y<0) || (y >= oldHeight))//判断是否是没有图像的区域
{
if (m_img->nChannels == 3)//判断图像是几通道图像
{
ptrNow[3 * width + 1] = 0;
ptrNow[3 * width + 2] = 0;
ptrNow[3 * width + 3] = 0;
}
else if (m_img->nChannels == 1)
{
ptrNow[width] = 0;
}
}
else
{
if (m_img->nChannels == 3)
{
ptrNow[3 * width + 1] = ptrOld[3 * x + 1];
ptrNow[3 * width + 2] = ptrOld[3 * x + 2];
ptrNow[3 * width + 3] = ptrOld[3 * x + 3];
}
else if (m_img->nChannels == 1)
{
ptrNow[width] = ptrOld[x];
}
}
}
}
cvZero(m_img);
m_img = cvCreateImage(cvSize(newWidth, newHeight), dst->depth, dst->nChannels);
cvCopy(dst, m_img);
cvReleaseImage(&dst);
}


int main(int argc, char*argv[])
{
    m_img = cvLoadImage("D:\\主导实习\\车厢图片\\result.jpg");
ImgRotate(true);
cvNamedWindow("show_image", 0);
cvShowImage("show_image", m_img);
cvWaitKey(0);
return 0;
}

图像缩放系列文章的源代码下载

          《图形图像处理-之-高质量的快速的图像缩放》系列文章的源代码下载                   HouSisong@GMail.com  2009.03.07tag:图像缩放...

1+1=2的 blog 文章索引

本blog太乱了?文章相互之间没有关联?,那么从本文开始可能是比较好的^_^。主要内容:本 blog 中和之前发布在其他 blog 中文章的索引。...

数字图像处理基础(十一)---缩放、角度旋转和仿射变换及代码实现

 源码如下: int  picProcessBasics::IMGAffineTransform(Mat* srcImage, Mat* dstImage_warp,d...

opencv&nbsp;任意角度旋转图像

转载(http://www.cnblogs.com/HappyXie/archive/2011/03/02/1969434.html)   //OpenCV 4 下的图像任意角度的旋转 //需要in...
  • rxm1989
  • rxm1989
  • 2014年09月25日 13:25
  • 258

opencv&nbsp;任意角度旋转图像

转载自(http://www.cnblogs.com/HappyXie/archive/2011/03/02/1969434.html)   //OpenCV 4 下的图像任意角度的旋转 //需要i...
  • rxm1989
  • rxm1989
  • 2014年09月25日 13:27
  • 209

opencv&nbsp;任意角度旋转图像

转载自(http://www.cnblogs.com/HappyXie/archive/2011/03/02/1969434.html)   //OpenCV 4 下的图像任意角度的旋转 //需要i...
  • rxm1989
  • rxm1989
  • 2014年09月25日 13:25
  • 216

winform实现图片任意角度旋转

  • 2011年09月22日 17:35
  • 457KB
  • 下载

opencv 实现图像任意角度的旋转

  • 2016年12月07日 14:52
  • 3KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:opencv实现图像任意角度旋转的算法解析及代码实现
举报原因:
原因补充:

(最多只允许输入30个字)