【机器视觉学习笔记】双线性插值实现图片任意角度旋转(C++)

目录

  • 原理
  • 源码
    • RotateImage_BilinearInterpolation
    • 主函数
  • 效果
  • 与最近邻插值比较
    • 原图
    • 最近邻插值效果(局部)
    • 双线性插值效果(局部)
  • 完整源码

平台:Windows 10 20H2
Visual Studio 2015
OpenCV 4.5.3


原理

在这里插入图片描述
如图所示,我们需要求P点的像素值。我们已知了Q11、Q21、Q12、Q22、P的坐标。也知道Q11、Q21、Q12、Q22的像素值。所以先用关于X的单线性插值去分别计算R1、R2的像素值
在这里插入图片描述

再使用关于y方向的单线性插值计算P点的像素值。
在这里插入图片描述

在这里插入图片描述

由以上思路可化简得到如下式子。IxI_xIx为该点上的像素值或灰度值
在这里插入图片描述

源码

RotateImage_BilinearInterpolation

Mat RotateImage_BilinearInterpolation(Mat src, double angle)
{int x0, y0, x1, y1;angle = angle * 3.1415926535897932384626433832795 / 180;int dx = abs((int)src.cols*cos(angle)) + abs((int)src.rows*sin(angle));int dy = abs((int)src.cols*sin(angle)) + abs((int)src.rows*cos(angle));Mat dst(dy, dx, CV_8UC3, Scalar(0));  //创建新图像for (x1 = 0; x1 < dst.cols; x1++){for (y1 = 0; y1 < dst.rows; y1++){double fx0, fy0;double fx1, fy1;double R;double sita, sita0, sita1;int x01, y01;int x02, y02;int x03, y03;int x04, y04;double p, q;//将图片中点设为坐标原点fx1 = x1 - dst.cols / 2;fy1 = y1 - dst.rows / 2;R = sqrt(fx1 * fx1 + fy1 * fy1);	//极径sita = angle;sita1 = atan2(fy1, fx1);			//新点极角sita0 = sita1 + sita;				//旧点极角//旧点直角坐标(中点为坐标原点)fx0 = R * cos(sita0);fy0 = R * sin(sita0);//旧点直角坐标(坐标原点在角上)x0 = fx0 + src.cols / 2 + 0.5;y0 = fy0 + src.rows / 2 + 0.5;x01 = (int)(fx0 + src.cols / 2);y01 = (int)(fy0 + src.rows / 2);x02 = x01 + 1;y02 = y01;x03 = x01 + 1;y03 = y01 + 1;x04 = x01;y04 = y01 + 1;p = (fx0 + src.cols / 2) - x01;q = (fy0 + src.rows / 2) - y01;if (x01 >= 0 && x03 < src.cols && y01 >= 0 && y03 < src.rows){for (int i = 0; i < 3; ++i)dst.at<Vec3b>(Point(x1, y1))[i] = src.at<Vec3b>(Point(x01, y01))[i] * (1 - p) * (1 - q) + src.at<Vec3b>(Point(x02, y02))[i] * p * (1 - q) + src.at<Vec3b>(Point(x03, y03))[i] * p * q + src.at<Vec3b>(Point(x04, y04))[i] * (1 - p) * q;}else if (x0 >= 0 && x0 < src.cols && y0 >= 0 && y0 < src.rows)dst.at<Vec3b>(Point(x1, y1)) = src.at<Vec3b>(Point(x0, y0));elsedst.at<Vec3b>(Point(x1, y1)) = 0;}}return dst;
}

主函数

int main(int argc, char * argv[])
{Mat src;src = imread("D:\\Work\\OpenCV\\Workplace\\Test_1\\4.jpg");imshow("原图", src);imshow("输出", RotateImage_BilinearInterpolation(src, 45));waitKey(0);return 0;
}

效果

在这里插入图片描述
在这里插入图片描述

与最近邻插值比较

原图

在这里插入图片描述

最近邻插值效果(局部)

在这里插入图片描述

双线性插值效果(局部)

在这里插入图片描述

完整源码

#include <opencv2\opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;Mat RotateImage_BilinearInterpolation(Mat src, double angle)
{int x0, y0, x1, y1;angle = angle * 3.1415926535897932384626433832795 / 180;int dx = abs((int)src.cols*cos(angle)) + abs((int)src.rows*sin(angle));int dy = abs((int)src.cols*sin(angle)) + abs((int)src.rows*cos(angle));Mat dst(dy, dx, CV_8UC3, Scalar(0));  //创建新图像for (x1 = 0; x1 < dst.cols; x1++){for (y1 = 0; y1 < dst.rows; y1++){double fx0, fy0;double fx1, fy1;double R;double sita, sita0, sita1;int x01, y01;int x02, y02;int x03, y03;int x04, y04;double p, q;//将图片中点设为坐标原点fx1 = x1 - dst.cols / 2;fy1 = y1 - dst.rows / 2;R = sqrt(fx1 * fx1 + fy1 * fy1);	//极径sita = angle;sita1 = atan2(fy1, fx1);			//新点极角sita0 = sita1 + sita;				//旧点极角//旧点直角坐标(中点为坐标原点)fx0 = R * cos(sita0);fy0 = R * sin(sita0);//旧点直角坐标(坐标原点在角上)x0 = fx0 + src.cols / 2 + 0.5;y0 = fy0 + src.rows / 2 + 0.5;x01 = (int)(fx0 + src.cols / 2);y01 = (int)(fy0 + src.rows / 2);x02 = x01 + 1;y02 = y01;x03 = x01 + 1;y03 = y01 + 1;x04 = x01;y04 = y01 + 1;p = (fx0 + src.cols / 2) - x01;q = (fy0 + src.rows / 2) - y01;if (x01 >= 0 && x03 < src.cols && y01 >= 0 && y03 < src.rows){for (int i = 0; i < 3; ++i)dst.at<Vec3b>(Point(x1, y1))[i] = src.at<Vec3b>(Point(x01, y01))[i] * (1 - p) * (1 - q) + src.at<Vec3b>(Point(x02, y02))[i] * p * (1 - q) + src.at<Vec3b>(Point(x03, y03))[i] * p * q + src.at<Vec3b>(Point(x04, y04))[i] * (1 - p) * q;}else if (x0 >= 0 && x0 < src.cols && y0 >= 0 && y0 < src.rows)dst.at<Vec3b>(Point(x1, y1)) = src.at<Vec3b>(Point(x0, y0));elsedst.at<Vec3b>(Point(x1, y1)) = 0;}}return dst;
}int main(int argc, char * argv[])
{Mat src;src = imread("D:\\Work\\OpenCV\\Workplace\\Test_1\\4.jpg");imshow("原图", src);imshow("输出", RotateImage_BilinearInterpolation(src, 45));waitKey(0);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高德地图调用和添加标注

看过高德地图API的同学都知道&#xff0c;高德地图不同端调用是不一样的&#xff0c;作为一个前端菜鸟&#xff0c;前一阵分别在pc端和移动端分别调用了高德地图。情况是这个样子的&#xff0c;PC端呢我们可以用高德API的web端的javascript代码。调用没有问题&#xff0c;具体是…

第5章 - 几何变换

第五章-几何变换one. 缩放:two. 翻转&#xff1a;three. 仿射&#xff1a;1. 平移&#xff1a;2. 旋转&#xff1a;3. 更多复杂的仿射变换&#xff1a;four. 透视&#xff1a;five. 重映射&#xff1a;1. 映射参数的理解&#xff1a;2. 复制&#xff1a;3. 绕x轴旋转&#xff1…

安装设置Android Studio Win7安装

发一下牢骚和主题无关&#xff1a; 让人等待已久的Google I/O 2013 大会没有给我们带来Android5.0&#xff0c;也没有带来Adnroid4.3等等&#xff0c;但带来了Android Studio&#xff0c;虽说是预览版&#xff0c;又是基于Intellij IDEA&#xff0c; 但是也无不让开辟者们高兴。…

【树莓派学习笔记】一、烧录系统、(无屏幕)配置Wifi和SSH服务

目录系统镜像的准备格式化TF卡烧录镜像配置Wifi开启SSH服务第一次开机平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 系统镜像的准备 树莓派资源里有许多资源&#xff0c;包括我们要用到的镜像。 格式化TF卡 将TF卡格式化为FAT32格式。 …

Linux中Oracle的sqlplus下退格和Del键无效的问题解决

利用rlwrap工具解决方法 1、安装rlwrap和readline库 CentOS下可以用EPEL的yum源直接安装&#xff0c;步骤如下&#xff1a; &#xff08;1&#xff09;RHEL/CentOS/SL Linux 6.x 下安装 EPEL6 yum源&#xff1a; 32位系统选择&#xff1a; # rpm -ivh http://download.fedorap…

No tag datetimepicker defined in tag library imported with prefix s解决

今天在学习Struts2标签中的datetimepicker出现这样一个exception&#xff1a; No tag "datetimepicker" defined in tag library imported with prefix "s" 原因&#xff1a; struts2.3.8 把struts2中的和ajax相关的&#xff0c;如datetimepicker&#xff…

2sum、3sum、4sum以及任意连续的数的和为sum、任意连续或者不连续的数的和为sum...

2sum 如果数组是无序的&#xff0c;先排序&#xff08;n*logn&#xff09;&#xff0c;然后用两个指针i&#xff0c;j&#xff0c;各自指向数组的首尾两端&#xff0c;令i0&#xff0c;jn-1&#xff0c;然后i&#xff0c;j--&#xff0c;逐次判断a[i]a[j]?sum&#xff0c;如果…

第6章-阈值处理

第六章-阈值处理one. threshold函数&#xff1a;1. 二值化阈值处理&#xff08;cv2.THRESH_BINARY&#xff09;&#xff1a;2. 反二值化阈值处理(cv2.THRESH_BINARY_INV)3. 截断阈值化处理(cv2.THRESH_TRUNC)4. 超阈值零处理(cv2.THRESH_TOZERO_INV)5.低阈值零处理(cv2.THRESH_…

【树莓派学习笔记】二、(无屏幕)SSH远程登录、图形界面及系统配置

目录确定树莓派LAN IP使用PuTTY登陆带图形界面的远程登陆Xming方案VNC Server 方案系统配置换源(可选)备份原文件查询系统版本编辑sources.list文件同步更新源更新软件包重启树莓派固定LAN IP平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 确定…

Centos7完全分布式搭建Hadoop2.7.3

(一&#xff09;软件准备 1&#xff0c;hadoop-2.7.3.tar.gz&#xff08;包&#xff09; 2,三台机器装有cetos7的机子 &#xff08;二&#xff09;安装步骤 1&#xff0c;给每台机子配相同的用户 进入root : su root 创建用户s: useradd s 修改用户密码&#xff1a;passwd s 2…

python学习笔记:遍历目录

import os import os.pathif __name__ __main__:root_dirg:\\downloadfor root, dirs, files in os.walk(root_dir):for dir in dirs:print root%s dir%s % (root,dir)#print rootroot dirdirfor file in files:print root%s file%s % (root,file)#print rootroot fiefile 转载…

LeetCode - Majority Element

参考了别人的想法&#xff0c;思路简洁&#xff0c;效率高。虽然是在充分理解别人的思路后写出的代码&#xff0c;但是还是发现了自己的不足之处。以后还是要多思考多写。加油吧&#xff01; public class Solution {public int majorityElement(int[] num) {int ans 0, cnt …

第7章:图像的平滑处理

第7章&#xff1a;图像的平滑处理一、均值滤波&#xff1a;二、方框滤波&#xff1a;三、高斯滤波&#xff1a;四、中值滤波五、双边滤波&#xff1a;六、2D卷积​ 图像的平滑处理是在尽量图像原有信息的情况下&#xff0c;过滤掉图像内部的噪声。由于图像平滑处理的同时通常伴…

【树莓派学习笔记】三、点亮一个LED灯(C语言 - WiringPi、Python - RPi.GPIO/GPIO Zero、bash脚本)

目录C语言WiringPiPythonRPi.GPIOGPIO Zerobash脚本平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 若GPIO输出为3.3V 采用压降为1.7V的红色LED灯 设工作电流为15mA&#xff0c;则限流电阻取≥(3.3 - 1.7)/0.015 106.67欧较为安全。 C语言 Wi…

codevs1014 装箱问题

题目描述 Description有一个箱子容量为V&#xff08;正整数&#xff0c;0&#xff1c;&#xff1d;V&#xff1c;&#xff1d;20000&#xff09;&#xff0c;同时有n个物品&#xff08;0&#xff1c;n&#xff1c;&#xff1d;30&#xff09;&#xff0c;每个物品有一个体积&am…

OpenStack 之Nova添加扩展API流程,附带资源的查找功能

例子中涉及到SQLAlchemy 得相关操作&#xff0c;可以参考 上一随笔 Openstack 中规定&#xff0c;扩展openstack得api有两种方式 创建新的WSGI 资源扩展原有得WSGI资源得控制器&#xff08;我得理解是&#xff0c;接受到API请求后&#xff0c;具体得响应逻辑&#xff09;这两种…

转载:ASP.NET在后台代码实现个功能,根据选择提示用户是否继续执行操作

这种情况是指在后台处理一个HTTP Post命令时将时序重新交给浏览器端&#xff0c;然后运行javascript&#xff0c;然后再回到服务器端&#xff0c;然后继续进行后边的操作。如果你会画时序图&#xff0c;就可以发现这种有着两个来回通讯的程序比大多数所知道的那种只有一个来回的…

第8章:形态学操作

第8章&#xff1a;形态学操作one. 腐蚀操作&#xff1a;two. 膨胀&#xff1a;three. 通用形态学函数&#xff1a;four. 开运算&#xff1a;five. 闭运算&#xff1a;six. 形态学梯度运算&#xff1a;seven. 礼帽运算&#xff1a;eight. 黑帽运算&#xff1a;night. 核函数&…

【树莓派学习笔记】四、OpenCV的安装与卸载

目录安装修改host以连接上Github测试IP修改树莓派的hosts安装各种依赖包安装OpenCV只安装核心模块安装核心模块和opencv_contribC Opencv 测试编写测试源码编译测试卸载平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 安装 修改host以连接上Git…

MySQL ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

今天在使用mysql时&#xff0c;又遇到了如博文标题所示的问题&#xff0c;以前针对该问题未进行记录&#xff0c;今天特意进行说明存档。 该问题是由键值字段长度过长导致。mysql支持数据库表单一键值的最大长度不能超过767字节&#xff0c;超出这个长度即报错&#xf…