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的更多相关文章

  1. 真实场景的双目立体匹配(stereo matching)以及虚拟视点合成(virtual view synthsis)示例

    双目立体匹配一直是双目视觉的研究热点,双目相机拍摄同一场景的左.右两幅视点图像,运用立体匹配匹配算法获取视差图,进而获取深度图.而深度图的应用范围非常广泛,由于其能够记录场景中物体距离摄像机的距离,可 ...

  2. 真实场景的虚拟视点合成(View Synthsis)详解

    上一篇博客中介绍了从拍摄图像到获取视差图以及深度图的过程,现在开始介绍利用视差图或者深度图进行虚拟视点的合成.虚拟视点合成是指利用已知的参考相机拍摄的图像合成出参考相机之间的虚拟相机位置拍摄的图像,能 ...

  3. 虚拟树Demos\Minimal 简单的例子

    //分析虚拟树demo6-VirtualTreeView\VirtualTreeViewV5.3.0\Demos\Minimal的main.pas文件 unit Main; // Demonstrat ...

  4. 性能优化:虚拟列表,如何渲染10万条数据的dom,页面同时不卡顿

    列表大概有2万条数据,又不让做成分页,如果页面直接渲染2万条数据,在一些低配电脑上可能会照成页面卡死,基于这个需求,我们来手写一个虚拟列表 思路 列表中固定只显示少量的数据,比如60条 在列表滚动的时 ...

  5. OSG中找到特定节点的方法

    OSG中找到特定节点的方法 转自:http://38288890.blog.163.com/blog/static/19612845320072721549504/ 为了在OSG中找到需要的节点并对节 ...

  6. 裸眼3D立体显示技术原理详解

    众所周知,现实世界是一个三维空间,除去时间这一维度,现实世界是由长度.宽度和高度三个维度组成,我们每天就生活在这个三维世界中,而现有的显示设备大多数都只能显示二维信息,并不能带给人真实的三维感觉.为了 ...

  7. MongoDB助力快速搭建物流订单系统

    简介 快递物流系统里最常见的一种业务类型就是订单的查询和记录.订单的特点是随着递送过程,订单数据需要随时更新路径.数据结构上需要可以灵活应对,这点非常符合Document模型,并且MongoDB支持G ...

  8. Win 10 系统下研华采集卡Advantech Navi SDK虚拟demo设备安装方法

    研华的DAQNavi是其采集卡设备的.net编程SDK,安装了其通讯工具Navigator后,可以添加虚拟采集卡 demo device. 在Win10上,执行添加操作时,可能会出现添加失败,这是由于 ...

  9. C# 开发Modbus Rtu客户端 modbus测试Demo,Modbus 串口通信 , 虚拟MODBUS-RTU测试

    前言 本文将使用一个NuGet公开的组件技术来实现一个ModBus RTU的客户端,方便的对Modbus rtu的服务器进行读写,这个服务器可以是电脑端C#设计的,也可以是PLC实现的,也可以是其他任 ...

随机推荐

  1. MQTT图形化客户端比较

    1 MQTT.fx (1)协议支持 TCP(tcp) TLS(tls) (2)特点 界面美观,操作便捷 不支持WebSocket协议 基于java开发 支持代理 通过Nashorn Engine的JS ...

  2. 高性能网站建设之 MS Sql Server数据库分区

    什么是数据库分区?数据库分区是一种对表的横向分割,Sql server 2005企业版和之后的Sql server版本才提供这种技术,这种对表的横向分割不同于2000中的表分割,它对访问用户是透明的, ...

  3. ie/chorme 清除缓存 刷新js,css

    1 有时候你发现你刚改过的js 没有用,然后就是你的浏览器 没有清楚缓存,它可能还是保存的之前的 网页文件: chorme 浏览器下(版本:ver 59.0.3071.104(正式版本) (64 位) ...

  4. X509证书在window server 2003/IIS 6环境部署

    利用makecert.exe工具生成的X509证书在winform程序中运行正常,但是给部署在IIS中的应用程序用却获取不到证书信息,返回为空.原因是,iis没有权限读取位于证书存储区的X509证书, ...

  5. [NOIP10.4模拟赛]3.z题解--思维

    题目链接: 咕咕 闲扯: 哈哈这道T3考场上又敲了5个namespace,300+行,有了前车之鉴还对拍过,本以为子任务分稳了 结果只有30分哈哈,明明用极限数据对拍过不知怎么回事最后数据又是读不全, ...

  6. 2017JAVA面试题附答案

    JAVA基础 JAVA中的几种基本类型,各占用多少字节?   String能被继承吗?为什么? 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变.平 ...

  7. RabbitMQ的交换机类型(三)

      RabbitMQ的交换机类型共有四种,是根据其路由过程的不同而划分成的 分别是Direct Exchange(直连交换机), Fanout Exchange(扇型交换机), Topic Excha ...

  8. java_实现Hello World

    1.新建项目 在空白处右击--New--java Project 2.项目文件结构 新建了项目之后项目文件在工作空间里面,(如果忘记工作空间的路径可以点击File---Switch Workspace ...

  9. 嵌入式Linux应用开发完全手册读书笔记——常用的命令

    嵌入式开发中常用的命令 grep命令 用法:grep [option] PATTERN [FILE...] 例如: 在内核目录下查找包含"request_irq"字样的文件 gre ...

  10. 深入理解Java虚拟机——读书笔记

    首先 强烈推荐周志明老师的这本书,真的可以说是(起码中文出版界)新手了解Java虚拟机必须人手一本的教科书!!!   第二部分自动内存管理机制 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器 ...