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 - ) / );
fSrcY1 = (float)((oldHeight - ) / );
fSrcX2 = (float)((oldWidth - ) / );
fSrcY2 = (float)((oldHeight - ) / );
fSrcX3 = (float)(-(oldWidth - ) / );
fSrcY3 = (float)(-(oldHeight - ) / );
fSrcX4 = (float)((oldWidth - ) / );
fSrcY4 = (float)(-(oldHeight - ) / ); // 旋转后四个角的坐标(以图像中心为坐标系原点)
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 = ; i < newHeight; i++)
{
for (int j = ; 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 < ) || (x >= oldWidth) || (y < ) || (y >= oldHeight))
{
if (imgIn.channels() == )
{
imgOut.at<cv::Vec3b>(i, j) = cv::Vec3b(, , );
}
else if (imgIn.channels() == )
{
imgOut.at<uchar>(i, j) = ;
}
}
else
{
if (imgIn.channels() == )
{
imgOut.at<cv::Vec3b>(i, j) = imgIn.at<cv::Vec3b>(y, x);
}
else if (imgIn.channels() == )
{
imgOut.at<uchar>(i, j) = imgIn.at<uchar>(y, x);
}
}
}
}
} void getAfterRotateRoi(cv::Mat& imgIn, int cols, int rows, Mat& imgOut)
{ imgOut.create(cols, rows, imgIn.type());
Point center(imgIn.cols / , imgIn.rows / ); imgOut = imgIn(Rect(imgIn.cols / - cols / , imgIn.rows / - rows / , cols,rows)); } Mat ImageRotate2NewSize(Mat& src, const CvPoint &_center, double angle, double scale)
{
double angle2 = angle * CV_PI / ;
int width = src.cols;
int height = src.rows; double alpha = cos(angle2) * scale;
double beta = sin(angle2) * scale; int new_width = (int)(width * fabs(alpha) + height * fabs(beta));
int new_height = (int)(width * fabs(beta) + height * fabs(alpha)); CvPoint2D32f center;
center.x = float(width / );
center.y = float(height / );
//计算二维旋转的仿射变换矩阵
Mat M = getRotationMatrix2D(center, angle, scale); // 给计算得到的旋转矩阵添加平移
M.at<double>(, ) += (int)((new_width - width) / );
M.at<double>(, ) += (int)((new_height - height) / ); // rotate
Mat dst;
warpAffine(src, dst, M, cvSize(new_width, new_height), CV_INTER_LINEAR);
return dst;
}

参考:http://www.tuicool.com/articles/RZz2Eb

OPENCV 旋转图像算法-汇总的更多相关文章

  1. OpenCV——旋转模糊

    参考来源: 学习OpenCV:滤镜系列(5)--径向模糊:缩放&旋转 // define head function #ifndef PS_ALGORITHM_H_INCLUDED #defi ...

  2. OpenCV——旋转模糊 (二)

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  3. python 下 安装openCV

    安装openCV openCV是Intel 创建的计算机视觉库,用于计算机图像处理. 安装anaconda,在命令行中输入conda install cv2/opencv 报错汇总 网络连接问题 报错 ...

  4. python手记(36)

    #!/usr/bin/env python #-*- coding: utf-8 -*- #code:myhaspl@qq.com import cv2 import numpy as np fn=& ...

  5. 提升Tesseract-OCR输出的质量

    图片处理 修改比例(Rescaling) 二值化(Binarisation) 去除噪点(Noise Removal) 旋转/偏移校正(Rotation / Deskewing) 边界(Borders) ...

  6. Excel2010数据透视表1

    “透视”作为一个动词,意思是旋转.如果将数据看成是一个物体,数据透视表允许旋转数据汇总,从不同角度或观点来看它.数据透视表能够轻松地移动字段,交换字段位置,设置创建项目的特定组. 如果给出一个陌生的物 ...

  7. Day7 Scrum 冲刺博客

    一.站立式会议1. 会议照片 2. 工作进度+燃尽图 团队成员 昨日完成工作 今日工作计划 遇到的困难  周梓波  添加键盘监听事件 由于游戏中计分规则不合理,进行重新设计  无  纪昂学  添加方块 ...

  8. 【图像算法OpenCV】几何不变矩--Hu矩

    原文地址  http://blog.csdn.NET/daijucug/article/details/7535370 [图像算法OpenCV]几何不变矩--Hu矩 一 原理 几何矩是由Hu(Visu ...

  9. 图像旋转 OpenCV实现

    经常对一幅图像进行旋转操作,OpenCV中提供了很方便易用的仿射变换函数warpAffine, 通过getRotationMatrix2D可以得到放射变换矩阵(矩阵大小2x3) #include &l ...

随机推荐

  1. junit断言总结

    我们平时编写自己的测试类,如果没有断言,那么就没写测试的必要了. JUnit框架用一组assert方法封装了最常见的测试任务.这些assert方法可以极大地简化单元测试的编写. Assert类包含了一 ...

  2. Go基础--goroutine和channel

    goroutine 在go语言中,每一个并发的执行单元叫做一个goroutine 这里说到并发,所以先解释一下并发和并行的概念: 并发:逻辑上具备同时处理多个任务的能力 并行:物理上在同一时刻执行多个 ...

  3. 基于 HTML5 WebGL 的 3D SCADA 主站系统

    这个例子的初衷是模拟服务器与客户端的通信,我把整个需求简化变成了今天的这个例子.3D 的模拟一般需要鹰眼来辅助的,这样找产品以及整个空间的概括会比较明确,在这个例子中我也加了,这篇文章就算是我对这次项 ...

  4. 《.NET 设计规范》第 7 章:异常

    第 7 章:异常 异常与各种面向对象语言集成得非常好. 异常增强了 API 的一致性. 在用返回值来报告错误时,错误处理的代码与可能会发生错误的代码距离总是很近. 更容易使错误处理的带码全局化. 错误 ...

  5. c# Char && string

    char 支持的方法 字符串 声明字符串 String str = [null]; 可以用此方法声明一个空字符串   连接字符串 str +"" + str1; 比较两个字符串 C ...

  6. Linux内核链表-通用链表的实现

    最近编程总想着参考一些有名的开源代码是如何实现的,因为要写链表就看了下linux内核中对链表的实现. 链表是一种非常常见的数据结构,特别是在动态创建相应数据结构的情况下更是如此,然而在操作系统内核中, ...

  7. LOJ #116 有源汇点有上下界的最大流

    先连一条从汇点到源点的容量为INF的边,将其转化成无源汇点有上下界的可行流,判断是否可行 若可行的话删掉超级源点和超级汇点,再跑一遍最大流即可 #include <iostream> #i ...

  8. 【转】我读过最好的epoll讲解(来自知乎)

    首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象.不管是文件,还是套接字,还是管道,我们都可以把他们看作流.之后我们来讨论I/O的操作,通过read,我 ...

  9. SpringMVC源码之参数解析绑定原理

    摘要 本文从源码层面简单讲解SpringMVC的参数绑定原理 SpringMVC参数绑定相关组件的初始化过程 在理解初始化之前,先来认识一个接口 HandlerMethodArgumentResolv ...

  10. Win10编译SqlCipher步骤

    准备工作 Visual Studio 2015,其他版本未验证,估计问题不大 ActiveState ActivePerl,用于编译OpenSSL Mingw,在官网下载minimum install ...