去年实习的时候,接到一个任务将公司软件生成的一张全景图扭曲切割成六个正常的面,然后动态生成一个3D网页。忙活了2天后完成代码。但最终因为某些原因未被采用。
首先配置OpenCV。
找寻了众多资料,找了一个算是我觉得最靠谱的:http://tieba.baidu.com/p/3931605400
安装好OpenCV以后我们来看原始图片
全景图的剪切原理我也不一一叙述了,贴出详细的原理解释:
http://paulbourke.net/geometry/transformationprojection/
接下来我们就po出源码:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<math.h>
#include <iostream>
using namespace cv;
using namespace std;
float M_PI = 3.14159265358979323846f;
float faceTransform[6][2] =
{
{
0, 0},
{M_PI /2,0},
{M_PI,0},
{-M_PI /2,0},
{
0,-M_PI/2},
{
0,M_PI/2}
};
inline void createCubeMapFace(const Mat &in, Mat &face, int faceId = 0, const int width = -1,const int height = -1)
{
float inWidth = in.cols;
float inHeight = in.rows; // 获取图片的行列数量
// cout << in.cols;
// cout << in.rows;
// system("pause");
// Allocate map
Mat mapx(height, width, CV_32F);
Mat mapy(height, width, CV_32F); //分配图的x,y轴
// Calculate adjacent (ak) and opposite (an) of the
// triangle that is spanned from the sphere center
//to our cube face.
const float an = sin(M_PI / 4);
const float ak = cos(M_PI / 4); //计算相邻ak和相反an的三角形张成球体中心
// cout << ak;
// cout << an;
// system("pause");
const float ftu = faceTransform[faceId][0];
const float ftv = faceTransform[faceId][1];
// For each point in the target image,
// calculate the corresponding source coordinates. 对于每个图像计算相应的源坐标
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Map face pixel coordinates to [-1, 1] on plane 将坐标映射在平面上
float nx = (float)y / (float)height - 0.5f;
float ny = (float)x / (float)width - 0.5f;
nx *= 2;
ny *= 2;
// Map [-1, 1] plane coord to [-an, an]
// thats the coordinates in respect to a unit sphere
// that contains our box.
nx *= an;
ny *= an;
float u, v;
// Project from plane to sphere surface.
if (ftv == 0) {
// Center faces
u = atan2(nx, ak);
v = atan2(ny * cos(u), ak);
u += ftu;
}
else if (ftv > 0) {
// Bottom face
float d = sqrt(nx * nx + ny * ny);
v = M_PI / 2 - atan2(d, ak);
u = atan2(ny, nx);
}
else {
// Top face
//cout << "aaa";
float d = sqrt(nx * nx + ny * ny);
v = -M_PI / 2 + atan2(d, ak);
u = atan2