虚拟视点demo
2019年7月16日15:55:11
感觉虚拟视点也是视觉slam里头一个重要的需求和应该实现的功能,但是好像
没看到什么资料。
百度的全景地图,或者有些公司网站上的3d装修效果图,可以用鼠标拖动查看不同视角,但是
图片看起来很奇怪,那不是虚拟视点,只是对图片做了变换。
虚拟视点的一些资料:
https://www.cnblogs.com/riddick/p/8511960.html
https://www.zhihu.com/question/40793359/answer/130155294
其他有点关联的方向:
https://zhuanlan.zhihu.com/p/73599241
谷歌也有篇文章把短基线变成长基线的文章,也有点虚拟视点的意思。
这里利用sfmlearner的设施做了个简单的demo:
原始图:
相机沿着Z轴往前移动0.5m,注意红框处和上图的对比,的确是往前移动了,这里没做插值,所以
不是太好看 pose = np.array([0, 0, -0.5, 0, 0, 0]) # tx, ty, tz, rx, ry, rz -- [B, 6] 弧度制!!!
下面是pose = np.array([0, -0.5, 0, 0, 0, 0],相机往下走了,y=-0.5
注意depth图红框处,原本从上往下拍时被桌面或者凳子挡住的部分现在看的到了,但是对应的深度图
在之前的角度是测不到的,相机往下移动之后这部分的深度图就显示为空缺了,对应的color1部分也
是黑色的。
下面是代码:
- # -*- coding: utf-8 -*-
- """
- Created on Tue Jul 16 11:57:48 2019
- @author: scj
- project test
- https://pytorch.org/docs/stable/nn.html?highlight=f%20grid_sample#torch.nn.functional.grid_sample
- https://blog.csdn.net/chamber_of_secrets/article/details/83512540
- https://blog.csdn.net/houdong1992/article/details/88122682
- """
- import torch
- import numpy as np
- import cv2
- import matplotlib.pyplot as plt
- #depth = cv2.imread('/media/scj/work/depth/joinMap/depth/1.pgm', -1)
- depth = cv2.imread('D:\\depth\\joinMap\\depth\\1.pgm', -1)
- depth = depth/1000
- depth_copy = depth.copy()
- #fig = plt.subplots(1)
- #plt.imshow( depth_copy )
- #plt.title("depth")
- #color = cv2.imread('/media/scj/work/depth/joinMap/color/1.png')
- color = cv2.imread('D:\\depth\\joinMap\\color\\1.png')
- #fig = plt.subplots(1)
- #plt.imshow( cv2.cvtColor(color, cv2.COLOR_BGR2RGB) )
- #plt.title("color")
- #####################
- fig=plt.figure()
- plt.subplot(121)
- plt.imshow(cv2.cvtColor(color, cv2.COLOR_BGR2RGB))
- plt.title("color")
- plt.subplot(122)
- plt.imshow(depth_copy)
- plt.title("depth")
- plt.show()
- #####################
- #color = np.transpose(color, (2, 0, 1))
- # print(depth.shape, color.shape) # (480, 640) (3, 480, 640)
- depth = depth[np.newaxis, :].astype(np.float64)
- depth = torch.from_numpy(depth)
- #print(depth.size() ) # torch.Size([1, 480, 640])
- cx = 325.5
- cy = 253.5
- fx = 518.0
- fy = 519.0
- intrinsics = np.array([
- [fx, 0, cx],
- [0, fy, cy],
- [0, 0, 1],
- ]).astype(np.float64)
- intrinsics = intrinsics[np.newaxis, :]
- intrinsics = torch.from_numpy(intrinsics)
- #print( intrinsics.size() ) # (1, 3, 3)
- ##########
- from inverse_warp import pixel2cam # uv2xyz
- cam_coords = pixel2cam(depth, intrinsics.inverse() )
- #print(cam_coords.size() )
- xyz1 = cam_coords.detach().numpy().squeeze()
- #print(xyz1.shape)
- #
- #fig = plt.subplots(1)
- #plt.imshow( xyz1[0, :, :] )
- #plt.title("x")
- #
- #fig = plt.subplots(1)
- #plt.imshow( xyz1[1, :, :] )
- #plt.title("y")
- #
- #fig = plt.subplots(1)
- #plt.imshow( xyz1[2, :, :] )
- #plt.title("z")
- # tx, ty, tz, rx, ry, rz -- [B, 6] 弧度制!!!
- pose = np.array([0, -0.5, 0, 0, 0, 0]).astype(np.float64)
- pose = pose[np.newaxis, :]
- pose = torch.from_numpy(pose)
- from inverse_warp import pose_vec2mat
- pose_mat = pose_vec2mat(pose, rotation_mode='euler') # [B,3,4]
- print(pose_mat)
- proj_cam_to_src_pixel = intrinsics @ pose_mat # [B, 3, 4] K*T_21
- #print(proj_cam_to_src_pixel)
- from inverse_warp import cam2pixel
- # cam2pixel 多传了一个Z出来
- src_pixel_coords, Z2 = cam2pixel(cam_coords, # XYZ
- proj_cam_to_src_pixel[:,:,:3], # R
- proj_cam_to_src_pixel[:,:,-1:], # t
- padding_mode='zeros') # [B,H,W,2]
- print(src_pixel_coords.size() )
- uv2 = src_pixel_coords.detach().numpy().squeeze()
- #fig = plt.subplots(1)
- #plt.imshow( uv2[:, :, 0] )
- #plt.title("u2")
- #
- #fig = plt.subplots(1)
- #plt.imshow( uv2[:, :, 1] )
- #plt.title("v2")
- #################
- b = color[:, :, 0]
- g = color[:, :, 1]
- r = color[:, :, 2]
- b = b.reshape(307200, 1)
- g = g.reshape(307200, 1)
- r = r.reshape(307200, 1)
- u2 = uv2[:, :, 0].reshape(307200, 1)
- v2 = uv2[:, :, 1].reshape(307200, 1)
- color1 = np.zeros_like(color)
- zz = Z2.detach().numpy().squeeze() # (307200, )
- #zz[133, 182] - depth_copy[133, 182] # 深度的确有变化 相差0.5
- depth1 = np.zeros((480, 640))
- for i in range(307200):
- uu = u2[i]
- vv = v2[i]
- if uu>-1 and uu < 1 and vv>-1 and vv<1:
- xx = int(0.5*(uu+1)*639)
- yy = int(0.5*(vv+1)*479)
- color1[yy, xx, 0] = b[i]
- color1[yy, xx, 1] = g[i]
- color1[yy, xx, 2] = r[i]
- depth1[yy, xx] = zz[i]
- #fig = plt.subplots(1)
- #plt.imshow( cv2.cvtColor(color1, cv2.COLOR_BGR2RGB) )
- #plt.title("color1")
- #
- #
- #fig = plt.subplots(1)
- #plt.imshow( depth1 )
- #plt.title("depth1")
- fig=plt.figure()
- plt.subplot(121)
- plt.imshow(cv2.cvtColor(color1, cv2.COLOR_BGR2RGB))
- plt.title("color1")
- plt.subplot(122)
- plt.imshow(depth1)
- plt.title("depth1")
- plt.show()
当然,上图的效果不行,还要做插值才能好看点。
虚拟视点demo的更多相关文章
- 真实场景的双目立体匹配(stereo matching)以及虚拟视点合成(virtual view synthsis)示例
双目立体匹配一直是双目视觉的研究热点,双目相机拍摄同一场景的左.右两幅视点图像,运用立体匹配匹配算法获取视差图,进而获取深度图.而深度图的应用范围非常广泛,由于其能够记录场景中物体距离摄像机的距离,可 ...
- 真实场景的虚拟视点合成(View Synthsis)详解
上一篇博客中介绍了从拍摄图像到获取视差图以及深度图的过程,现在开始介绍利用视差图或者深度图进行虚拟视点的合成.虚拟视点合成是指利用已知的参考相机拍摄的图像合成出参考相机之间的虚拟相机位置拍摄的图像,能 ...
- 虚拟树Demos\Minimal 简单的例子
//分析虚拟树demo6-VirtualTreeView\VirtualTreeViewV5.3.0\Demos\Minimal的main.pas文件 unit Main; // Demonstrat ...
- 性能优化:虚拟列表,如何渲染10万条数据的dom,页面同时不卡顿
列表大概有2万条数据,又不让做成分页,如果页面直接渲染2万条数据,在一些低配电脑上可能会照成页面卡死,基于这个需求,我们来手写一个虚拟列表 思路 列表中固定只显示少量的数据,比如60条 在列表滚动的时 ...
- OSG中找到特定节点的方法
OSG中找到特定节点的方法 转自:http://38288890.blog.163.com/blog/static/19612845320072721549504/ 为了在OSG中找到需要的节点并对节 ...
- 裸眼3D立体显示技术原理详解
众所周知,现实世界是一个三维空间,除去时间这一维度,现实世界是由长度.宽度和高度三个维度组成,我们每天就生活在这个三维世界中,而现有的显示设备大多数都只能显示二维信息,并不能带给人真实的三维感觉.为了 ...
- MongoDB助力快速搭建物流订单系统
简介 快递物流系统里最常见的一种业务类型就是订单的查询和记录.订单的特点是随着递送过程,订单数据需要随时更新路径.数据结构上需要可以灵活应对,这点非常符合Document模型,并且MongoDB支持G ...
- Win 10 系统下研华采集卡Advantech Navi SDK虚拟demo设备安装方法
研华的DAQNavi是其采集卡设备的.net编程SDK,安装了其通讯工具Navigator后,可以添加虚拟采集卡 demo device. 在Win10上,执行添加操作时,可能会出现添加失败,这是由于 ...
- C# 开发Modbus Rtu客户端 modbus测试Demo,Modbus 串口通信 , 虚拟MODBUS-RTU测试
前言 本文将使用一个NuGet公开的组件技术来实现一个ModBus RTU的客户端,方便的对Modbus rtu的服务器进行读写,这个服务器可以是电脑端C#设计的,也可以是PLC实现的,也可以是其他任 ...
随机推荐
- 服务器上office不能正常使用?
(1)确保dll版本和服务器上office版本一致 (2)配置dcom (3)项目配置文件中添加用户模拟语句 <system.web> <identity impersonate=& ...
- maven 私服 nexus 安装
1.去官方下载他的免费版,人民称为oss版(这一步自行百度去官网解决),官网:https://www.sonatype.com/ 2.下载好后,解压是两个文件夹: 3.配置环境变量: 4.安装生成w ...
- spring利用xml配置定时任务
在开发中会经常遇到做定时任务的需求,例如日志定时清理与处理,数据信息定时同步等需求. 1.在spring中利用xml配置定时任务,如下 <!-- ftpiptv信息同步接口定时任务配置--> ...
- CSS设置元素的隐藏和显示
常见的三种方式 display display: none 隐藏对象 display: block 除了转换为块级元素以外,同时还有显示元素的意思 特点:隐藏之后不保留位置 visibility 值h ...
- js对象中属性调用.和[] 两种方式的区别
JS 调用属性一般有两种方法——点和中括号的方法. 标准格式是对象.属性(不带双引号),注意一点的是:js对象的属性,key标准是不用加引号的,加也可以,特别的情况必须加,如果key数字啊,表达式啊等 ...
- go module 设置
国内无法获取被墙的go module,解决方法,设置环境变量 GO111MODULE=on goproxy=https://goproxy.io
- WinPE基础知识之导入表
// 导入表 (结构体数组,以一个全零元素为结尾,每一个数组元素,代表一个PE文件导入信息) // 导入表存储的是从其它PE文件导入过来的函数名.序号,加载到内存之后,还存储这些函数的地址 typed ...
- 1.JavaWeb 知识点概览
1.tomcat服务器的安装和配置.http协议 1.1 虚拟目录的 /*映射*/(配置Context元素)(server.xml catalina\localhost\) http://blog.c ...
- Spring Cloud(二)服务提供者 Eureka + 服务消费者(rest + Ribbon)
Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连接超时 ...
- davinci 删除路线站点关系
删除路线站点关系 DELETE FROM tb_station_info_draw WHERE id in (SELECT stationId FROM tb_road_station_relatio ...