一、需求:
- 给出立方体六个面,合成一张全景图
二、主要知识:py360convert
2.1、该项目的特点:
- 立方体贴图和等矩形之间的转换
-
- 等角于平面
-
- 纯python实现,仅依赖于numpy和scipy
- 矢量化实施(在大多数地方)
c2e
e2c
在1.6 GHz Intel Core i5 CPU上花费300ms并花费160ms
2.2、安装
pip install py360convert
现在,您可以在任何地方import py360convert
或使用命令行工具convert360
。
2.3、参数:
e2c(e_img, face_w=256, mode='bilinear', cube_format='dice')
将给定的等矩形转换为立方体贴图。
参数:
e_img
:形状为[H,W,C]的块状数组。face_w
:每个立方体面的宽度。mode
:bilinear
或nearest
。cube_format
:请参阅c2e
说明。
e2p(e_img, fov_deg, u_deg, v_deg, out_hw, in_rot_deg=0, mode='bilinear')
从给定的等角线拍摄透视图。 参数:
e_img
:形状为[H,W,C]的块状数组。fov_deg
:以int或tuple给出的视野(h_fov_deg, v_fov_deg)
。u_deg
:水平视角在[-pi,pi]范围内。(-左/ +右)。v_deg
:垂直视角,范围为[-pi / 2,pi / 2]。(-向下/ +向上)。out_hw
:(height, width)
以元组输出图像。in_rot_deg
:平面内旋转。mode
:bilinear
或nearest
。
三、示例:
3.1、立方体六个面:
背面(b):
前面(f):
左面(l):
右面(r):
上面(u):
下面(d):
3.2、合成全景图效果:
三、编辑后端代码:
import uuid
import os
import py360convert
from django.core.files.storage import default_storage
from django.http import JsonResponse
import cv2# Create your views here.def image_transpose(req):if req.method == 'POST':# 给图片唯一标识uuid0 = str(uuid.uuid1())# 获取图片信息,六个面依次为:前、后、左、右、上、下front_image = req.FILES.get("front_image", None)backward_image = req.FILES.get("backward_image", None)left_image = req.FILES.get("left_image", None)right_image = req.FILES.get("right_image", None)top_image = req.FILES.get("top_image", None)bottom_image = req.FILES.get("bottom_image", None)quality_para = req.POST.get("quality", None)target_size_w = req.POST.get("size", None)# 获取图片宽度if not target_size_w:target_size_w = 3000if target_size_w is not None:target_size_w = int(target_size_w)target_size_h = int(target_size_w // 2)# 控制图片清晰度if not quality_para:quality_para = 3quality_map = {0: 40,1: 60,2: 90}quality_para = int(quality_para)quality_save = quality_map.get(quality_para, None)if quality_save is None:quality_save = 70os.mkdir('./static/trans' + uuid0)out_path = 'static/' + uuid0# 合成全景图if front_image and backward_image and left_image and right_image and top_image and bottom_image:default_storage.save(os.path.join('static/trans/', uuid0, 'front_image.jpg'),front_image)default_storage.save(os.path.join('static/trans/', uuid0, 'backward_image.jpg'),backward_image)default_storage.save(os.path.join('static/trans/', uuid0, 'left_image.jpg'),left_image)default_storage.save(os.path.join('static/trans/', uuid0, 'right_image.jpg'),right_image)default_storage.save(os.path.join('static/trans/', uuid0, 'top_image.jpg'),top_image)default_storage.save(os.path.join('static/trans/', uuid0, 'bottom_image.jpg'),bottom_image)cube_dice0 = cv2.imread(os.path.join('static/trans/', uuid0, 'front_image.jpg'))cube_dice1 = cv2.imread(os.path.join('static/trans/', uuid0, 'right_image.jpg'))cube_dice2 = cv2.imread(os.path.join('static/trans/', uuid0, 'backward_image.jpg'))cube_dice3 = cv2.imread(os.path.join('static/trans/', uuid0, 'left_image.jpg'))cube_dice4 = cv2.imread(os.path.join('static/trans/', uuid0, 'top_image.jpg'))cube_dice5 = cv2.imread(os.path.join('static/trans/', uuid0, 'bottom_image.jpg'))cube_dice1 = cv2.flip(cube_dice1, 1)cube_dice2 = cv2.flip(cube_dice2, 1)cube_dice4 = cv2.flip(cube_dice4, 0)res = py360convert.c2e([cube_dice0, cube_dice1, cube_dice2, cube_dice3, cube_dice4,cube_dice5], target_size_h, target_size_w, cube_format='list')cv2.imwrite(os.path.join('static/trans/', uuid0, 'panorama.jpg'),res, [int(cv2.IMWRITE_JPEG_QUALITY), quality_save])# 保存图片:第一种方式,自己配置下载到相应的地方;第二种下载到本地return JsonResponse({"error": 0,"message": "no error",# 这里下载图片,目前采用自己配置的环境"result": {"panorama": 'https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + uuid0 + '/panorama.jpg'}})else:return JsonResponse({"error": 1,"message": "Saving files error!","result": {}})else:return JsonResponse({"error": 1,"message": "method error","result": {}})