当前位置: 首页 > 编程日记 > 正文

OpenCV代码提取:rotate函数的实现

OpenCV中并没有直接提供实现rotate的函数,这里通过getRotationMatrix2D和warpAffine函数实现rotate,并增加了一个crop参数,用来判断是否进行crop。目前支持uchar和float两种类型,经测试,与OpenCV3.1结果完全一致。

公式的推导可以参考:http://blog.csdn.net/fengbingchun/article/details/17713429

实现代码rotate.hpp:

// fbc_cv is free software and uses the same licence as OpenCV
// Email: fengbingchun@163.com#ifndef FBC_CV_ROTATE_HPP_
#define FBC_CV_ROTATE_HPP_/* reference: include/opencv2/imgproc.hppmodules/imgproc/src/imgwarp.cpp
*/#include "core/mat.hpp"
#include "warpAffine.hpp"namespace fbc {// Calculates an affine matrix of 2D rotation
// Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top - left corner)
FBC_EXPORTS int getRotationMatrix2D(Point2f center, double angle, double scale, Mat_<double, 1>& dst);// Applies an rotate to an image
// The function cannot operate in - place
// support type: uchar/float
template<typename _Tp, int chs>
int rotate(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, Point2f center, double angle,bool crop = true, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar())
{FBC_Assert(typeid(float).name() == typeid(_Tp).name() || typeid(uchar).name() == typeid(_Tp).name());FBC_Assert(src.data != NULL && src.rows > 0 && src.cols > 0);Mat_<double, 1> rot_matrix(2, 3);getRotationMatrix2D(center, angle, 1.0, rot_matrix);if (crop) {if (dst.data == NULL) {dst = Mat_<_Tp, chs>(src.rows, src.cols);}} else {Rect bbox = RotatedRect(center, Size2f(src.cols, src.rows), angle).boundingRect();double* p = (double*)rot_matrix.data;p[2] += bbox.width / 2.0 - center.x;p[5] += bbox.height / 2.0 - center.y;if (dst.rows != bbox.height || dst.cols != bbox.width) {dst = Mat_<_Tp, chs>(bbox.height, bbox.width);}}warpAffine(src, dst, rot_matrix, flags, borderMode, borderValue);return 0;
}} // namespace fbc#endif // FBC_CV_ROTATE_HPP_
测试代码test_rotate.cpp:

#include "test_rotate.hpp"
#include <assert.h>
#include <opencv2/opencv.hpp>
#include <rotate.hpp>int test_getRotationMatrix2D()
{cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);if (!matSrc.data) {std::cout << "read image fail" << std::endl;return -1;}double angle = -50.0;double scale = 0.6;fbc::Point2f center = fbc::Point2f(matSrc.cols / 2, matSrc.rows / 2);fbc::Mat_<double, 1> mat_rot(2, 3);fbc::getRotationMatrix2D(center, angle, scale, mat_rot);// Compute a rotation matrix with respect to the center of the imagecv::Point center_ = cv::Point(matSrc.cols / 2, matSrc.rows / 2);// Get the rotation matrix with the specifications abovecv::Mat mat_rot_ = cv::getRotationMatrix2D(center_, angle, scale);assert(mat_rot.cols == mat_rot_.cols && mat_rot.rows == mat_rot_.rows);assert(mat_rot.step == mat_rot_.step);for (int y = 0; y < mat_rot.rows; y++) {const fbc::uchar* p = mat_rot.ptr(y);const uchar* p_ = mat_rot_.ptr(y);for (int x = 0; x < mat_rot.step; x++) {assert(p[x] == p_[x]);}}return 0;
}int test_rotate_uchar()
{cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);if (!matSrc.data) {std::cout << "read image fail" << std::endl;return -1;}double angle = -50.0;for (int interpolation = 0; interpolation < 5; interpolation++) {fbc::Point2f center = fbc::Point2f(matSrc.cols / 2.0, matSrc.rows / 2.0);fbc::Mat_<uchar, 3> mat(matSrc.rows, matSrc.cols, matSrc.data);fbc::Mat_<uchar, 3> rotate_dst;fbc::rotate(mat, rotate_dst, center, angle, true, interpolation);// Compute a rotation matrix with respect to the center of the imagecv::Point2f center_ = cv::Point2f(matSrc.cols / 2.0, matSrc.rows / 2.0);// Get the rotation matrix with the specifications abovecv::Mat mat_rot_ = getRotationMatrix2D(center_, angle, 1.0);cv::Mat rotate_dst_;cv::warpAffine(matSrc, rotate_dst_, mat_rot_, matSrc.size(), interpolation);assert(rotate_dst.step == rotate_dst_.step && rotate_dst.rows == rotate_dst_.rows);for (int y = 0; y < rotate_dst.rows; y++) {const fbc::uchar* p = rotate_dst.ptr(y);const uchar* p_ = rotate_dst_.ptr(y);for (int x = 0; x < rotate_dst.step; x++) {assert(p[x] == p_[x]);}}}return 0;
}int test_rotate_float()
{cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);if (!matSrc.data) {std::cout << "read image fail" << std::endl;return -1;}cv::cvtColor(matSrc, matSrc, CV_BGR2GRAY);matSrc.convertTo(matSrc, CV_32FC1);double angle = -50.0;for (int interpolation = 0; interpolation < 5; interpolation++) {fbc::Point2f center = fbc::Point2f(matSrc.cols / 2.0, matSrc.rows / 2.0);fbc::Mat_<float, 1> mat(matSrc.rows, matSrc.cols, matSrc.data);fbc::Mat_<float, 1> rotate_dst;fbc::rotate(mat, rotate_dst, center, angle, true, interpolation);// Compute a rotation matrix with respect to the center of the imagecv::Point2f center_ = cv::Point2f(matSrc.cols / 2.0, matSrc.rows / 2.0);// Get the rotation matrix with the specifications abovecv::Mat mat_rot_ = getRotationMatrix2D(center_, angle, 1.0);cv::Mat rotate_dst_;cv::warpAffine(matSrc, rotate_dst_, mat_rot_, matSrc.size(), interpolation);assert(rotate_dst.step == rotate_dst_.step && rotate_dst.rows == rotate_dst_.rows);for (int y = 0; y < rotate_dst.rows; y++) {const fbc::uchar* p = rotate_dst.ptr(y);const uchar* p_ = rotate_dst_.ptr(y);for (int x = 0; x < rotate_dst.step; x++) {assert(p[x] == p_[x]);}}}return 0;
}int test_rotate_without_crop()
{cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/1.jpg", 1);if (!matSrc.data) {std::cout << "read image fail" << std::endl;return -1;}double angle = -50.0;double scale = 0.6;fbc::Point2f center = fbc::Point2f(matSrc.cols / 2.0, matSrc.rows / 2.0);fbc::Mat_<uchar, 3> mat(matSrc.rows, matSrc.cols, matSrc.data);fbc::Mat_<uchar, 3> rotate_dst;fbc::rotate(mat, rotate_dst, center, angle, true/*false*/, 2, 0, fbc::Scalar(128, 255, 0));cv::Mat mat_save(rotate_dst.rows, rotate_dst.cols, CV_8UC3, rotate_dst.data);cv::imwrite("E:/GitCode/OpenCV_Test/test_images/1_rotate2.jpg", mat_save);return 0;
}
以下分别是源图像,调用rotate函数,生成的crop和非crop的结果图像:

GitHub:https://github.com/fengbingchun/OpenCV_Test

相关文章:

在 Node.js 中用子进程操作标准输入/输出

翻译&#xff1a;疯狂的技术宅原文&#xff1a;http://2ality.com/2018/05/chi... 本文首发微信公众号&#xff1a;jingchengyideng欢迎关注&#xff0c;每天都给你推送新鲜的前端技术文章 在本中&#xff0c;我们在 Node.js 中把 shell 命令作为子进程运行。然后异步读取这些进…

再见,Python 2.x

整理 | 屠敏来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;在技术的长河中&#xff0c;软件、工具、系统等版本的迭代本是常事&#xff0c;但由于使用习惯、版本的兼容性、易用性等因素&#xff0c;很多用户及开发者在使用或做开发的过程中&#xff0c;并不愿意及…

Android UI系列-----CheckBox和RadioButton(1)

主要记录一下CheckBox多选框和RadioGroup、RadioButton单选框的设置以及注册监听器 1.CheckBox 布局文件&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android…

C++中struct的使用

C语言继承了C语言的struct&#xff0c;并且加以扩充。在C语言中struct是只能定义数据成员&#xff0c;而不能定义成员函数的。而在C中&#xff0c;struct类似于class&#xff0c;在其中既可以定义数据成员&#xff0c;又可以定义成员函数。结构类型是用户定义的复合类型&#x…

填报表中也可以添加 html 事件

在实际的项目开发中&#xff0c;填报表的应用十分广泛。 多数情况下&#xff0c;填报表会作为整个项目的一部分配合需求灵活使用&#xff0c;但有时也会受大项目环境的影响&#xff0c;产生一些特别的要求。比如&#xff0c;通常报表单元格的数据类型大多是文本&#xff0c;有时…

60+业内技术专家,9大核心技术专题,AI ProCon倒计时一周!

2018 年&#xff0c;由 CSDN 举办的第一届 AI 开发者大会喊出“只讲技术&#xff0c;拒绝空谈”&#xff0c;两天会议时间&#xff0c;国内外几十家顶尖科技企业讲述了其主流技术及其应用案例&#xff0c;真正引领国内开发者紧跟技术浪潮。一年过去&#xff0c;在你还未有所觉察…

密码学研究-数字签名

引入&#xff1a;提到签名&#xff0c;大家都不陌生&#xff0c;大家知道&#xff0c;重大的文件一般都要领导签名&#xff0c;来确保这个文件的真实有效。而一些比较重要的合同&#xff0c;比如买房的购房合同&#xff0c;都要盖“骑缝章”&#xff0c;这个骑缝章&#xff0c;…

C++11中shared_ptr的使用

在C中&#xff0c;动态内存的管理是通过一对运算符来完成的&#xff1a;new&#xff0c;在动态内存中为对象分配空间并返回一个指向该对象的指针&#xff0c;可以选择对对象进行初始化&#xff1b;delete&#xff0c;接受一个动态对象的指针&#xff0c;销毁该对象&#xff0c;…

colly源码学习

colly源码学习 colly是一个golang写的网络爬虫。它使用起来非常顺手。看了一下它的源码&#xff0c;质量也是非常好的。本文就阅读一下它的源码。 使用示例 func main() {c : colly.NewCollector()// Find and visit all linksc.OnHTML("a[href]", func(e *colly.HTM…

可惜了,你们只看到“双马会”大型尬聊

作者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;导读&#xff1a;2019 年 8 月 29 日&#xff0c;世界人工智能大会&#xff08;WAIC&#xff09;在上海正式拉开帷幕。开幕式上&#xff0c;最让人瞩目的莫过于阿里巴巴前 CEO 马云与特斯拉 CEO Elon Musk …

Java 过滤特殊字符的 正则表达式

Java正则表达式学习&#xff1a; 因为正则表达式是一个很庞杂的体系&#xff0c;此例仅举些入门的概念&#xff0c;更多的请参阅相关书籍及自行摸索。 \\ 反斜杠 \t 间隔 (\u0009) \n 换行 (\u000A) \r 回车 (\u000D) \d 数字 等价于[0-9] \D 非数字 等价于[^0-9] \s 空…

C++11中unique_ptr的使用

在C中&#xff0c;动态内存的管理是通过一对运算符来完成的&#xff1a;new&#xff0c;在动态内存中为对象分配空间并返回一个指向该对象的指针&#xff0c;可以选择对对象进行初始化&#xff1b;delete&#xff0c;接受一个动态对象的指针&#xff0c;销毁该对象&#xff0c;…

从这篇YouTube论文,剖析强化学习在工业级场景推荐系统中的应用

作者 | 吴海波转载自知乎用户吴海波【导读】本文作者根据两篇工业界背景的论文解答了 RL 在推荐场景需要解决的问题与困难&#xff0c;以及入门需要学习得相关知识点。2 个月前&#xff0c;业界开始流传 youtube 成功将 RL 应用在了推荐场景&#xff0c;并且演讲者在视频中说是…

java中两个Integer类型的值相比较的问题

转载自&#xff1a; https://www.cnblogs.com/xh0102/p/5280032.html 两个Integer类型整数进行比较时&#xff0c;一定要先用intValue()方法将其转换为int数之后再进行比较&#xff0c;因为直接使用比较两个Integer会出现问题。 总结&#xff1a; 当给Integer直接赋值时&#x…

C#共享内存实例 附源码

原文 C#共享内存实例 附源码 网上有C#共享内存类&#xff0c;不过功能太简单了&#xff0c;并且写内存每次都从开头写。故对此进行了改进&#xff0c;并做了个小例子&#xff0c;供需要的人参考。 主要改进点&#xff1a; 通过利用共享内存的一部分空间(以下称为“数据信息区”…

C++11中weak_ptr的使用

在C中&#xff0c;动态内存的管理是通过一对运算符来完成的&#xff1a;new&#xff0c;在动态内存中为对象分配空间并返回一个指向该对象的指针&#xff0c;可以选择对对象进行初始化&#xff1b;delete&#xff0c;接受一个动态对象的指针&#xff0c;销毁该对象&#xff0c;…

经典不过时,回顾DeepCompression神经网络压缩

作者 | 薰风初入弦转载自知乎导读&#xff1a;本文作者为我们详细讲述了 ICLR 2016 的最佳论文 Deep Compression 中介绍的神经网络压缩方法。神经网络压缩一直是一个重要的研究方向&#xff0c;而目前业界最认可的压缩方法莫过于 ICLR 2016 的最佳论文 Deep Compression&#…

区块链技术特点之去中心化特性

想知道更多关于区块链技术知识&#xff0c;请百度【链客区块链技术问答社区】 链客&#xff0c;有问必答&#xff01;&#xff01; 由于区块链技术去中心化的特性&#xff0c;其在我们生活中的很多重要领域&#xff08;如金融、管理&#xff09;等方面具有重要的意义。例如&…

Android APK反编译

转自&#xff1a;http://blog.csdn.net/ithomer/article/details/6727581 一、Apk反编译得到Java源代码 下载上述反编译工具包&#xff0c;打开apk2java目录下的dex2jar-0.0.9.9文件夹&#xff0c;内含apk反编译成java源码工具&#xff0c;以及源码查看工具。 apk反编译工具dex…

Java泛型进阶 - 如何取出泛型类型参数

在JDK5引入了泛型特性之后&#xff0c;她迅速地成为Java编程中不可或缺的元素。然而&#xff0c;就跟泛型乍一看似乎非常容易一样&#xff0c;许多开发者也非常容易就迷失在这项特性里。多数Java开发者都会注意到Java编译器的类型擦除实现方式&#xff0c;Type Erasure会导致关…

C++11中override的使用

override是C11中的一个继承控制关键字。override确保在派生类中声明的重载函数跟基类的虚函数有相同的声明。 override明确地表示一个函数是对基类中一个虚函数的重载。更重要的是&#xff0c;它会检查基类虚函数和派生类中重载函数的签名不匹配问题。如果签名不匹配&#xff…

平头哥发布一站式芯片设计平台“无剑”,芯片设计成本降低50%

导读&#xff1a;8 月 29 日&#xff0c;在上海举行的世界人工智能大会上&#xff0c;阿里巴巴旗下半导体公司平头哥发布 SoC 芯片平台“无剑”。无剑是面向 AIoT 时代的一站式芯片设计平台&#xff0c;提供集芯片架构、基础软件、算法与开发工具于一体的整体解决方案&#xff…

Windows XP下,JDK环境变量配置

2019独角兽企业重金招聘Python工程师标准>>> 1.安装JDK&#xff0c;安装过程中可以自定义安装目录等信息&#xff0c;例如我们选择安装目录为D:\java\jdk1.5.0_08&#xff1b; 2.安装完成后&#xff0c;右击“我的电脑”&#xff0c;点击“属性”&#xff1b; 3.选择…

Markdown语法简介

Markdown是一种方便记忆、书写的纯文本标记语言&#xff0c;用户可以使用这些标记符号以最小的输入代价生成极富表现力的文档。它目标是实现易读易写。Markdown的语法全由一些符号所组成。Markdown语法的目标是成为一种适用于网络的书写语言。 Markdown优点&#xff1a;纯文本…

吴恩达:AI未来将呈现四大发展趋势

作者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;导读&#xff1a;8 月 30 日&#xff0c;世界人工智能大会精彩继续。在今天的全球工业智能峰会上&#xff0c;Landing.AI 创始人及首席执行官吴恩达来到现场&#xff0c;做了题为《人工智能是新电力》的演讲…

嵌入式课程安排 嵌入式培训课程大纲参考

嵌入式是一门综合性的学科&#xff0c;现在学习嵌入式开发不是单纯局限于单片机或者Linux&#xff0c;嵌入式课程中包含着非常多的内容。以粤嵌嵌入式课程进行参考&#xff0c;看看我们要学习嵌入式的话&#xff0c;要掌握哪些必备的技能。嵌入式课程安排包含&#xff1a;1、入…

Linux网站架构系列之Apache----进阶篇

本篇博文为Linux网站架构系列之apache的第二篇&#xff0c;我将带大家一起学习apache的编译参数&#xff0c;目录结构和配置文件等方面的知识&#xff0c;实现对apache服务的进一步掌握&#xff0c;并使之能更好的应用到生产实战中去。一、编译参数在上篇的apache部署中&#x…

仅用10天设计的JavaScript,凭什么成为程序员最受欢迎的编程语言?

导语&#xff1a;在这个世纪之交诞生的 JavaScript&#xff0c;没人想到会发展为当今世界上最流行的语言之一。它不够成熟&#xff0c;不够严肃&#xff0c;甚至连名字都是模仿的 Java。那么&#xff0c;JavaScript 的成功是依靠运气和完美时机的侥幸吗&#xff1f;其实不然——…

C++11中= delete;的使用

C11中&#xff0c;对于deleted函数&#xff0c;编译器会对其禁用&#xff0c;从而避免某些非法的函数调用或者类型转换&#xff0c;从而提高代码的安全性。 对于 C 的类&#xff0c;如果程序员没有为其定义特殊成员函数&#xff0c;那么在需要用到某个特殊成员函数的时候&…

vue 使用scss

使用vue-cli模板创建的项目中&#xff0c;使用scss步骤 1. cmd命令&#xff1a; cnpm install sass-loader --save-devcnpm install node-sass --sava-dev2.查看package.json文件中是否已自动添加以下信息 3. 转载于:https://www.cnblogs.com/duanzhenzhen/p/10453495.html