绕X 轴 Y轴 Z轴旋转的结果

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);

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

原文地址:https://www.cnblogs.com/ly570/p/11278002.html

时间: 2024-08-06 22:12:07

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

OpenGL画图的时候免不了需要知道自己建立的opengl坐标的x,y,z轴的极值

在我们用OpenGL画图的时候免不了需要知道自己建立的opengl坐标的x,y,z轴的极值(也就是最大表示范围).那么该如何来测试,下面一起来看看: 首先,你需要知道自己是按照什么视角来建立的坐标系,我的是按照NeHe的那本书来的: [cpp] view plain copy void GLWidget::resizeGL(int width, int height) { if(0 == height) height = 1;//To prevent a side is 0 glViewport

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

本文主要介绍Android立体旋转动画,或者3D旋转,下图是我自己实现的一个界面 立体旋转分为以下三种: 1. 以X轴为轴心旋转 2. 以Y轴为轴心旋转 3. 以Z轴为轴心旋转--这种等价于android默认自带的旋转动画RotateAnimation 实现立体旋转核心步骤: 1. 继承系统Animation重写applyTransformation方法 通过applyTransformation方法的回调参数 float interpolatedTime, Transformation t 来

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

一.PhoneGap 加速计 Accelerometer 对象介绍 1.主要方法 accelerometer.getCurrentAcceleration 获取当前设备在 x,y,z 轴上的加速度信息 accelerometer.watchAcceleration       定期获取设备的加速度信息 accelerometer.clearWatch      停止定期获取设备的加速度信息 2.参数 accelerometerSuccess 获取加速度信息成功的回调函数 acceleromete

CABasicAnimation x y z 轴旋转动画

x轴旋转:CABasicAnimation *theAnimation;theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];theAnimation.duration=1;theAnimation.fromValue = [NSNumber numberWithFloat:0];theAnimation.toValue = [NSNumber numberWithFloat:3.141

直线绕z轴旋转所成曲面的方程

直线:(x-x0)/L=(y-y0)/M=(z-z0)/N绕z轴旋转所成曲面的方程为: x2+y2=α+β(z-z0)+γ(z-z0)2 其中 α=x02+y02 β=(2/N)(Lx0+My0) γ=(L2+M2)/N2 绕其他两个轴的方程类似于此. 原文地址:https://www.cnblogs.com/jmz11111/p/8157604.html

SVG渲染顺序及z轴显示问题(zIndex)

SVG是严格按照定义元素的顺序来渲染的,这个与HTML靠z-index值来控制分层不一样. 在SVG中,写在前面的元素先被渲染,写在后面的元素后被渲染.后渲染的元素会覆盖前面的元素,虽然有时候受透明度影响,看起来不是被覆盖的,但是SVG确实是严格按照先后顺序来渲染的. 注意:SVG是以XML定义的,所以是大小写敏感的,这点与HTML不一样. 关于z轴显示问题的解决方案: 注:动态移动对应的标签在SVG文档中的顺序,在文档结尾处的显示在z轴的上部. Html代码 <svg style='borde

Mac - NSView不能保证subview的z轴顺序

从iPhone转到mac的开发者,会自然而然的以为NSView的subview(或控件)是有z轴顺序的,但实际上apple并不保证subview是按照添加的顺序显示.NSView也不存在类似于UIView的bringSubviewToFront方法. 应该避免subview之间有交集.但由于我是把我的iPhone项目转成mac,我并不像改变太多.还是找到了解决方法.就是在addSubview的时候使用以下方法: [self addSubview:subviewFront positioned:N

陀螺仪以及三轴陀螺仪和六轴陀螺仪的区别_六轴陀螺仪和九轴陀螺仪的区别

来源:电子发烧友 链接:http://www.elecfans.com/article/88/142/2017/20171201590857.html 陀螺仪,是一种用来感测与维持方向的装置,基於角动量不灭的理论设计出来的.陀螺仪主要是由一个位於轴心可以旋转的轮子构成. 陀螺仪一旦开始旋转,由於轮子的角动量,陀螺仪有抗拒方向改变的趋向.陀螺仪多用於导航.定位等系统. 1850年法国的物理学家福柯(J.Foucault)为了研究地球自转,首先发现高速转动中的转子(rotor),由于惯性作用它的旋转

将两个矩阵相乘,A为x行y列的矩阵,B为y行z列的矩阵,A*B

m1*m2=m其中是一个x行z列的一个矩阵,例如 代码如下: #include<stdio.h>void matrix_multiply(int *m1, int *m2, int *m, int x, int y, int z){ int row = 0;  //m矩阵的行 int col = 0;  //m的列 int k = 0; int *m1p = m1;     int *m2p = m2; for (row = 0; row < x; row++) {  for (col