void warp_perspect_3_angle(cv::Mat face, float roll, float yaw, float pitch) {

cv::Mat face_img = face.clone();
int imgHeight = face_img.rows;
int imgWidth = face_img.cols;

float alpha, beta, gamma;
alpha = pitch * 3.1415926 / 180;
beta = yaw* 3.1415926 / 180;
gamma = roll * 3.1415926 / 180;
Mat Rot = Mat::eye(3, 3, CV_32FC1);

Rot.at<float>(0, 0) = cos(beta) * cos(gamma);
Rot.at<float>(0, 1) = cos(beta) * sin(gamma);
Rot.at<float>(0, 2) = -sin(beta);
Rot.at<float>(1, 0) = sin(alpha) * sin(beta) * cos(gamma) - cos(alpha) * sin(gamma);
Rot.at<float>(1, 1) = sin(alpha) * sin(beta) * sin(gamma) + cos(alpha) * cos(gamma);
Rot.at<float>(1, 2) = sin(alpha) * cos(beta);
Rot.at<float>(2, 0) = cos(alpha) * sin(beta) * cos(gamma) + sin(alpha) * sin(gamma);
Rot.at<float>(2, 1) = cos(alpha) * sin(beta) * sin(gamma) - sin(alpha) * cos(gamma);
Rot.at<float>(2, 2) = cos(alpha) * cos(beta);

Mat invRot;
invert(Rot, invRot, DECOMP_SVD);

float fx = imgWidth/2;
float fy = imgHeight/2;
float cx = imgWidth / 2;
float cy = imgHeight / 2;

Mat point3D = Mat::zeros(3, 1, CV_32FC1);
Mat oldPoint3D = Mat::zeros(3, 1, CV_32FC1);

Mat dstImg = face_img.clone();
dstImg.setTo(0);

uchar* pImgData = (uchar*)face_img.data;
uchar* pDstData = (uchar*)dstImg.data;
for (int j = 0; j < imgHeight; j++)
{
for (int i = 0; i < imgWidth; i++)
{
float X = (i - cx) / fx;
float Y = (j - cy) / fy;
float Z = 1;

point3D.at<float>(0, 0) = X;
point3D.at<float>(1, 0) = Y;
point3D.at<float>(2, 0) = Z;
//求旋转前坐标点
oldPoint3D = invRot*point3D;
float oldX = oldPoint3D.at<float>(0, 0);
float oldY = oldPoint3D.at<float>(1, 0);
float oldZ = oldPoint3D.at<float>(2, 0);
//重投影到二维平面
if (oldZ > 1e-3)
{
float u = ((fx*oldX + cx*oldZ) / oldZ);
float v = ((fy*oldY + cy*oldZ) / oldZ);

int u0 = floor(u);
int v0 = floor(v);
int u1 = u0 + 1;
int v1 = v0 + 1;

if (u0 >= 0 && v0 >= 0 && u1 < imgWidth && v1 < imgHeight)
{
float dx = u - u0;
float dy = v - v0;
float weight1 = (1 - dx)*(1 - dy);
float weight2 = dx*(1 - dy);
float weight3 = (1 - dx)*dy;
float weight4 = dx*dy;

pDstData[j*imgWidth * 3 + i * 3 + 0] = weight1*pImgData[v0*imgWidth * 3 + u0 * 3 + 0] +
weight2*pImgData[v0*imgWidth * 3 + u1 * 3 + 0] +
weight3*pImgData[v1*imgWidth * 3 + u0 * 3 + 0] +
weight4*pImgData[v1*imgWidth * 3 + u1 * 3 + 0];

pDstData[j*imgWidth * 3 + i * 3 + 1] = weight1*pImgData[v0*imgWidth * 3 + u0 * 3 + 1] +
weight2*pImgData[v0*imgWidth * 3 + u1 * 3 + 1] +
weight3*pImgData[v1*imgWidth * 3 + u0 * 3 + 1] +
weight4*pImgData[v1*imgWidth * 3 + u1 * 3 + 1];

pDstData[j*imgWidth * 3 + i * 3 + 2] = weight1*pImgData[v0*imgWidth * 3 + u0 * 3 + 2] +
weight2*pImgData[v0*imgWidth * 3 + u1 * 3 + 2] +
weight3*pImgData[v1*imgWidth * 3 + u0 * 3 + 2] +
weight4*pImgData[v1*imgWidth * 3 + u1 * 3 + 2];
}
}
}
}
imshow("show", dstImg);

---------------------

绕X 轴 Y轴 Z轴旋转的结果的更多相关文章

  1. Android立体旋转动画实现与封装(支持以X、Y、Z三个轴为轴心旋转)

    本文主要介绍Android立体旋转动画,或者3D旋转,下图是我自己实现的一个界面 立体旋转分为以下三种: 1. 以X轴为轴心旋转 2. 以Y轴为轴心旋转 3. 以Z轴为轴心旋转--这种等价于andro ...

  2. PhoneGap 加速计 api 获取加速计 x 轴 y 轴 z 轴信息

    一.PhoneGap 加速计 Accelerometer 对象介绍 1.主要方法 accelerometer.getCurrentAcceleration 获取当前设备在 x,y,z 轴上的加速度信息 ...

  3. 传感器(3)传感器的X,Y,Z轴

    设备正面水平向上. X轴 : 左右方向,向右是正值. Y轴 : 远近方向,远离你是负. Z轴 : 上下方向,向上是正值.

  4. [osg][原]osg的坐标系:使用右手法则Y轴向前、X向、右Z向上。camare的默认姿态:向下看(Z轴负向),头向前(Y轴正向)

    参考:http://blog.csdn.net/tmljs1988/article/details/7561887 图中上半边为opengl坐标系,下半边的osg坐标系: osg::Camare的默认 ...

  5. OpenGL编程(七)3D模型的深度(z轴)检测

    下图是我们要修改后的效果图: 一.深度检测 1.模型Z轴显示有问题: 上一次试验中,如果认真留意,会发现一个问题.当控制锥体在左右或上下旋转时,你会发现锥体看起来是在+-180度之间来回摆动,而不是3 ...

  6. atlas z 轴

    问题源自一个帖子,因为上传的图比较多,就另开了这个贴写下自己的试验结果,原帖在下面链接中 http://game.ceeger.com/forum/read.php?tid=8911#info NGU ...

  7. (转)NGUI中深度depth和z轴关系

    先列出转载链接: http://game.ceeger.com/forum/read.php?tid=8917 转载原文: 问题源自一个帖子,因为上传的图比较多,就另开了这个贴写下自己的试验结果,原帖 ...

  8. 用MATLAB绘制折线图,x轴为字符串,并旋转一定的角度!!!

    先上代码,然后再一行一行解释: x=1:37; %这一行其实一开始,写的时候是没有的,后来需要给X轴上规定几个刻度才加上的 plot(x,Y,'linewidth',2); %以x为自变量,y为因变量 ...

  9. transform:translateZ() 字体模糊问题 父类重返Z轴平面

    translateZ()变糊 第一种情况: 当translateZ(m)中的 m设置为 非整数,1.5px 之类的,字体会模糊,但是不明显;和浏览器渲染,字体格式,或者操作系统有关, 这个 css中 ...

随机推荐

  1. IntelliJ IDEA 2018 2.X破解

    一 下载idea 官网 :https://www.jetbrains.com/idea/ 二 下载破解包 IntelliJ IDEA 2018.1.X--2.X(2.6可用,图就不改了) 链接: ht ...

  2. C. Roads in Berland

    题目链接: http://codeforces.com/problemset/problem/25/C 题意: 给一个最初的所有点与点之间的最短距离的矩阵.然后向图里加边,原有的边不变,问加边后的各个 ...

  3. maven添加oracle和sqlserver报错

    Failure to find com.oracle:ojdbc6:jar:12.1.0.1-atlassian-hosted in 'xxx' Missing artifact com.micros ...

  4. JAVA中JavaBean对象之间属性拷贝的方法

    JAVA中JavaBean对象之间的拷贝通常是用get/set方法,但如果你有两个属性相同的JavaBean或有大部分属性相同的JavaBean,对于这种情况,可以采用以下几个简便方法处理. 下面对这 ...

  5. 史上最全最常用的正则表达式(转自微信公众号:javascript)

    很多不太懂正则的朋友,在遇到需要用正则校验数据时,往往是在网上去找很久,结果找来的还是不很符合要求.所以我最近把开发中常用的一些正则表达式整理了一下,在这里分享一下.给自己留个底,也给朋友们做个参考. ...

  6. dfs(最长路径)

    http://poj.org/problem?id=1154 LETTERS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: ...

  7. TCL环境检查

    set w [open 1.txt w+] foreach a [info var] { if { [llength [array name $a]]==0 } { puts $w $a:[set $ ...

  8. [Java聊天室server]实战之三 接收循环

    前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识.但学习之前,更 ...

  9. k3 cloud中数值以百分比的形式展示

    显示格式化字符串:P去掉区域设置的勾选

  10. Gradle中的GroupID和ArtifactID指的是什么?

    GroupId和ArtifactId被统称为“坐标”是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找. GroupId一般分为多个段 ...