基于OpenCV的全景图剪切程序:一张全景生成六张立方体天空盒图

#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(-ny, nx);
			}

			// Map from angular coordinates to [-1, 1], respectively.
			u = u / (M_PI);
			v = v / (M_PI / 2);

			// Warp around, if our coordinates are out of bounds. 
			while (v < -1) {
				v += 2;
				u += 1;
			}
			while (v > 1) {
				v -= 2;
				u += 1;
			}

			while (u < -1) {
				u += 2;
			}
			while (u > 1) {
				u -= 2;
			}

			// Map from [-1, 1] to in texture space
			u = u / 2.0f + 0.5f;
			v = v / 2.0f + 0.5f;

			u = u*(inWidth - 1);
			v = v*(inHeight - 1);

			mapx.at<float>(x, y) = u;
			mapy.at<float>(x, y) = v;
		}
	}

	// Recreate output image if it has wrong size or type. 
	if (face.cols != width || face.rows != height ||
		face.type() != in.type()) {
		face = Mat(width, height, in.type());
	}

	// Do actual  using OpenCV's remap
	remap(in, face, mapx, mapy, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
	if (faceId == 0)
	{
		imwrite("cube0000.png", face);
	}
	else if (faceId == 1)
	{
		imwrite("cube0001.png", face);
	}
	else if (faceId == 2)
	{
		imwrite("cube0002.png", face);
	}
	else if (faceId == 3)
	{
		imwrite("cube0003.png", face);
	}
	else if (faceId == 4)
	{
		imwrite("cube0004.png", face);
	}
	else if (faceId == 5)
	{
		imwrite("cube0005.png", face);
	}
	/*  waitKey(10000);*/

}


int main(){

	int faceId = 0;
	int width = 1296;
	int height = 1296;
	cv::Mat srcimage = cv::imread("reye0.png");
	cv::Mat resultImage;
	for (int i = 0; i < 6; i++) {
		createCubeMapFace(srcimage, resultImage, i, width, height);
	}
}
转载自:https://blog.csdn.net/qq_30832659/article/details/52494713
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值