虚拟视点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实现的,也可以是其他任 ...
随机推荐
- Python初学者常见错误详解
Python初学者常见错误详解 0.忘记写冒号 在 if.elif.else.for.while.class.def 语句后面忘记添加 “:” if spam == 42 print('Hello ...
- 怎么保证 redis 和 db 中的数据一致
你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题? 首先需要考虑到:更新数据库或者更新缓存都有可能失败,在这种前提下分析业务带来的 ...
- 关于BIOS系统的认识和学习(源自摘录)
BIOS系统的介绍与学习 BIOS (basic input output system 即基本输入输出系统)在计算机系统中起着非常重要的作用,其是计算机系统最底层的设置, BIOS设置程序是被固化到 ...
- varchar、nvarchar
Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示. NCHAR.NVARCHAR.NTEXT.这三种从名字上看比前面三种多了个 ...
- paramiko模块实现远程传输控制
一.什么是paramiko呢? paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的parami ...
- [NOIP10.3模拟赛]3.w题解--神奇树形DP
题目链接: 咕 闲扯: 这题考场上把子任务都敲满了,5个namespace,400行11k 结果爆0了哈哈,因为写了个假快读只能读入一位数,所以手测数据都过了,交上去全TLE了 把边分成三类:0. 需 ...
- http、tcp简述
网络简述第一章 http.tcp简述 一.网络7层协议从上到下分别是 7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层 : 其中高层(即7.6.5.4层)定 ...
- empty和isset的区别
1.empty 判断一个变量是否为空 null.false.0.0.0.’0′.array() .' '.var $a 都会返回true. 2.isset 判断一个变量是否设置 0.00.’0′. ...
- LeetCode 腾讯精选50题--二叉树中的最大路径和
二叉树中的最大路径和 题目描述 给定一个非空二叉树,返回器最大路径和,路径指一条从任意节点出发,到达任意节点的序列,该路径至少包含一个节点,且不一定经过根节点 解题思路 树这一类数据结构我还不是很熟悉 ...
- for循环中的闭包
// 问题1:判断下面一段代码运行的结果是什么? var data = [] for (var i = 0; i < 3; i++) { data[i] = function() { conso ...