q3dviewer 1.1.7__py3-none-any.whl → 1.1.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- q3dviewer/Qt/__init__.py +1 -0
- q3dviewer/base_glwidget.py +83 -1
- q3dviewer/custom_items/__init__.py +1 -0
- q3dviewer/custom_items/cloud_io_item.py +16 -1
- q3dviewer/custom_items/cloud_item.py +31 -20
- q3dviewer/custom_items/text3d_item.py +152 -0
- q3dviewer/custom_items/text_item.py +19 -4
- q3dviewer/glwidget.py +23 -3
- q3dviewer/shaders/cloud_frag.glsl +1 -1
- q3dviewer/shaders/cloud_vert.glsl +4 -4
- q3dviewer/shaders/gau_frag.glsl +1 -1
- q3dviewer/shaders/gau_prep.glsl +1 -1
- q3dviewer/shaders/gau_vert.glsl +1 -1
- q3dviewer/shaders/sort_by_key.glsl +1 -1
- q3dviewer/tools/cloud_viewer.py +79 -3
- q3dviewer/tools/example_viewer.py +8 -28
- q3dviewer/tools/film_maker.py +1 -1
- q3dviewer/tools/lidar_cam_calib.py +8 -8
- q3dviewer/utils/convert_ros_msg.py +49 -6
- {q3dviewer-1.1.7.dist-info → q3dviewer-1.1.9.dist-info}/METADATA +12 -9
- q3dviewer-1.1.9.dist-info/RECORD +44 -0
- {q3dviewer-1.1.7.dist-info → q3dviewer-1.1.9.dist-info}/WHEEL +1 -1
- {q3dviewer-1.1.7.dist-info → q3dviewer-1.1.9.dist-info}/entry_points.txt +1 -0
- q3dviewer/basic_window.py +0 -228
- q3dviewer/cloud_viewer.py +0 -74
- q3dviewer/custom_items/camera_frame_item.py +0 -173
- q3dviewer/custom_items/trajectory_item.py +0 -79
- q3dviewer/gau_io.py +0 -168
- q3dviewer/utils.py +0 -71
- q3dviewer-1.1.7.dist-info/RECORD +0 -49
- {q3dviewer-1.1.7.dist-info → q3dviewer-1.1.9.dist-info}/LICENSE +0 -0
- {q3dviewer-1.1.7.dist-info → q3dviewer-1.1.9.dist-info}/top_level.txt +0 -0
q3dviewer/cloud_viewer.py
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
from q3dviewer.custom_items import *
|
|
5
|
-
from q3dviewer.basic_window import *
|
|
6
|
-
from pypcd4 import PointCloud
|
|
7
|
-
|
|
8
|
-
class CloudViewer(Viewer):
|
|
9
|
-
def __init__(self):
|
|
10
|
-
super(CloudViewer, self).__init__(name="Cloud Viewer")
|
|
11
|
-
self.setAcceptDrops(True)
|
|
12
|
-
|
|
13
|
-
def dragEnterEvent(self, event):
|
|
14
|
-
if event.mimeData().hasUrls():
|
|
15
|
-
event.accept()
|
|
16
|
-
else:
|
|
17
|
-
event.ignore()
|
|
18
|
-
|
|
19
|
-
def dropEvent(self, event):
|
|
20
|
-
for url in event.mimeData().urls():
|
|
21
|
-
file_path = url.toLocalFile()
|
|
22
|
-
self.openCloudFile(file_path)
|
|
23
|
-
|
|
24
|
-
def openCloudFile(self, file):
|
|
25
|
-
cloud_item = self['cloud']
|
|
26
|
-
if cloud_item is None:
|
|
27
|
-
print("Can't find clouditem.")
|
|
28
|
-
return
|
|
29
|
-
if file.endswith('.pcd'):
|
|
30
|
-
pc = PointCloud.from_path(file).pc_data
|
|
31
|
-
if 'rgb' in pc.dtype.names:
|
|
32
|
-
color = pc["rgb"].astype(np.uint32)
|
|
33
|
-
cloud_item.setColorMode('RGB')
|
|
34
|
-
elif 'intensity' in pc.dtype.names:
|
|
35
|
-
color = pc["intensity"].astype(np.uint32)
|
|
36
|
-
cloud_item.setColorMode('I')
|
|
37
|
-
else:
|
|
38
|
-
color = pc['z'].astype(np.uint32)
|
|
39
|
-
cloud_item.setColorMode('#FFFFFF')
|
|
40
|
-
cloud = np.rec.fromarrays(
|
|
41
|
-
[np.stack([pc["x"], pc["y"], pc["z"]], axis=1), color],
|
|
42
|
-
dtype=cloud_item.data_type)
|
|
43
|
-
elif file.endswith('.npy'):
|
|
44
|
-
pc = np.load(file)
|
|
45
|
-
cloud = np.rec.fromarrays(
|
|
46
|
-
[np.stack([pc[:, 0], pc[:, 1], pc[:, 2]], axis=1), pc[:, 3].astype(np.uint32)],
|
|
47
|
-
dtype=cloud_item.data_type)
|
|
48
|
-
cloud_item.setData(data=cloud)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def main():
|
|
52
|
-
import argparse
|
|
53
|
-
parser = argparse.ArgumentParser()
|
|
54
|
-
parser.add_argument("--pcd", help="the pcd path")
|
|
55
|
-
args = parser.parse_args()
|
|
56
|
-
app = QApplication([])
|
|
57
|
-
viewer = CloudViewer()
|
|
58
|
-
cloud_item = CloudIOItem(size=1, alpha=0.1)
|
|
59
|
-
axis_item = GLAxisItem(size=0.5, width=5)
|
|
60
|
-
gird_item = GridItem(size=1000, spacing=20)
|
|
61
|
-
# viewer.viewerWidget.setBackgroundColor(255, 255, 255, 255)
|
|
62
|
-
|
|
63
|
-
viewer.addItems({'cloud': cloud_item, 'grid': gird_item, 'axis': axis_item})
|
|
64
|
-
|
|
65
|
-
if args.pcd:
|
|
66
|
-
pcd_fn = args.pcd
|
|
67
|
-
viewer.openCloudFile(pcd_fn)
|
|
68
|
-
|
|
69
|
-
viewer.show()
|
|
70
|
-
app.exec_()
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if __name__ == '__main__':
|
|
74
|
-
main()
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import pyqtgraph.opengl as gl
|
|
2
|
-
from OpenGL.GL import *
|
|
3
|
-
import numpy as np
|
|
4
|
-
from OpenGL.GL import shaders
|
|
5
|
-
from PIL import Image
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# Vertex and Fragment shader source code
|
|
9
|
-
vertex_shader_source = """
|
|
10
|
-
#version 330 core
|
|
11
|
-
layout(location = 0) in vec3 position;
|
|
12
|
-
layout(location = 1) in vec2 texCoord;
|
|
13
|
-
|
|
14
|
-
out vec2 TexCoord;
|
|
15
|
-
|
|
16
|
-
uniform mat4 view_matrix;
|
|
17
|
-
uniform mat4 project_matrix;
|
|
18
|
-
|
|
19
|
-
void main()
|
|
20
|
-
{
|
|
21
|
-
gl_Position = project_matrix * view_matrix * vec4(position, 1.0);
|
|
22
|
-
TexCoord = texCoord;
|
|
23
|
-
}
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
fragment_shader_source = """
|
|
27
|
-
#version 330 core
|
|
28
|
-
in vec2 TexCoord;
|
|
29
|
-
out vec4 color;
|
|
30
|
-
uniform sampler2D ourTexture;
|
|
31
|
-
void main()
|
|
32
|
-
{
|
|
33
|
-
color = texture(ourTexture, TexCoord);
|
|
34
|
-
}
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def set_uniform_mat4(shader, content, name):
|
|
39
|
-
content = content.T
|
|
40
|
-
glUniformMatrix4fv(
|
|
41
|
-
glGetUniformLocation(shader, name),
|
|
42
|
-
1,
|
|
43
|
-
GL_FALSE,
|
|
44
|
-
content.astype(np.float32)
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class GLCameraFrameItem(gl.GLGraphicsItem.GLGraphicsItem):
|
|
49
|
-
def __init__(self, T=np.eye(4), size=1, width=3, path=None):
|
|
50
|
-
gl.GLGraphicsItem.GLGraphicsItem.__init__(self)
|
|
51
|
-
self.size = size
|
|
52
|
-
self.width = width
|
|
53
|
-
self.T = T
|
|
54
|
-
self.path = path
|
|
55
|
-
|
|
56
|
-
def initializeGL(self):
|
|
57
|
-
# Rectangle vertices and texture coordinates
|
|
58
|
-
hsize = self.size / 2
|
|
59
|
-
self.vertices = np.array([
|
|
60
|
-
# positions # texture coords
|
|
61
|
-
[-hsize, -hsize, 0.0, 0.0, 0.0], # bottom-left
|
|
62
|
-
[hsize, -hsize, 0.0, 1.0, 0.0], # bottom-right
|
|
63
|
-
[hsize, hsize, 0.0, 1.0, 1.0], # top-right
|
|
64
|
-
[-hsize, hsize, 0.0, 0.0, 1.0], # top-left
|
|
65
|
-
[0, 0, -hsize * 0.66, 0.0, 0.0], # top-left
|
|
66
|
-
], dtype=np.float32)
|
|
67
|
-
|
|
68
|
-
R = self.T[:3, :3]
|
|
69
|
-
t = self.T[:3, 3]
|
|
70
|
-
self.vertices[:, :3] = (
|
|
71
|
-
R @ self.vertices[:, :3].T + t[:, np.newaxis]).T
|
|
72
|
-
|
|
73
|
-
self.focal_p = np.array([0, 0, hsize * 0.66])
|
|
74
|
-
|
|
75
|
-
indices = np.array([
|
|
76
|
-
0, 1, 2, # first triangle
|
|
77
|
-
2, 3, 0 # second triangle
|
|
78
|
-
], dtype=np.uint32)
|
|
79
|
-
|
|
80
|
-
self.vao = glGenVertexArrays(1)
|
|
81
|
-
vbo = glGenBuffers(1)
|
|
82
|
-
ebo = glGenBuffers(1)
|
|
83
|
-
|
|
84
|
-
glBindVertexArray(self.vao)
|
|
85
|
-
|
|
86
|
-
glBindBuffer(GL_ARRAY_BUFFER, vbo)
|
|
87
|
-
glBufferData(GL_ARRAY_BUFFER, self.vertices.itemsize *
|
|
88
|
-
5 * 4, self.vertices, GL_STATIC_DRAW)
|
|
89
|
-
|
|
90
|
-
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
|
|
91
|
-
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
|
92
|
-
indices.nbytes, indices, GL_STATIC_DRAW)
|
|
93
|
-
|
|
94
|
-
# Vertex positions
|
|
95
|
-
|
|
96
|
-
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
|
|
97
|
-
20, ctypes.c_void_p(0))
|
|
98
|
-
glEnableVertexAttribArray(0)
|
|
99
|
-
# Texture coordinates
|
|
100
|
-
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
|
101
|
-
20, ctypes.c_void_p(12))
|
|
102
|
-
glEnableVertexAttribArray(1)
|
|
103
|
-
|
|
104
|
-
project_matrix = np.array(self._GLGraphicsItem__view.projectionMatrix().data(),
|
|
105
|
-
np.float32).reshape([4, 4]).T
|
|
106
|
-
# Compile shaders and create shader program
|
|
107
|
-
self.program = shaders.compileProgram(
|
|
108
|
-
shaders.compileShader(vertex_shader_source, GL_VERTEX_SHADER),
|
|
109
|
-
shaders.compileShader(fragment_shader_source, GL_FRAGMENT_SHADER),
|
|
110
|
-
)
|
|
111
|
-
glUseProgram(self.program)
|
|
112
|
-
set_uniform_mat4(self.program, project_matrix, 'project_matrix')
|
|
113
|
-
glUseProgram(0)
|
|
114
|
-
|
|
115
|
-
self.texture = glGenTextures(1)
|
|
116
|
-
glBindTexture(GL_TEXTURE_2D, self.texture)
|
|
117
|
-
|
|
118
|
-
# Load image
|
|
119
|
-
image = Image.open(self.path)
|
|
120
|
-
# image = image.transpose(Image.FLIP_TOP_BOTTOM)
|
|
121
|
-
img_data = image.convert("RGBA").tobytes()
|
|
122
|
-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width,
|
|
123
|
-
image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
|
|
124
|
-
glGenerateMipmap(GL_TEXTURE_2D)
|
|
125
|
-
glBindTexture(GL_TEXTURE_2D, 0)
|
|
126
|
-
glBindVertexArray(0)
|
|
127
|
-
|
|
128
|
-
def setTransform(self, T):
|
|
129
|
-
self.T = T
|
|
130
|
-
|
|
131
|
-
def paint(self):
|
|
132
|
-
self.view_matrix = np.array(
|
|
133
|
-
self._GLGraphicsItem__view.viewMatrix().data(), np.float32).reshape([4, 4]).T
|
|
134
|
-
project_matrix = np.array(self._GLGraphicsItem__view.projectionMatrix(
|
|
135
|
-
).data(), np.float32).reshape([4, 4]).T
|
|
136
|
-
|
|
137
|
-
glEnable(GL_DEPTH_TEST)
|
|
138
|
-
glEnable(GL_BLEND)
|
|
139
|
-
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
|
140
|
-
|
|
141
|
-
glUseProgram(self.program)
|
|
142
|
-
set_uniform_mat4(self.program, self.view_matrix, 'view_matrix')
|
|
143
|
-
set_uniform_mat4(self.program, project_matrix, 'project_matrix')
|
|
144
|
-
glBindVertexArray(self.vao)
|
|
145
|
-
glBindTexture(GL_TEXTURE_2D, self.texture)
|
|
146
|
-
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
|
|
147
|
-
glBindTexture(GL_TEXTURE_2D, 0)
|
|
148
|
-
glBindVertexArray(0)
|
|
149
|
-
glUseProgram(0)
|
|
150
|
-
|
|
151
|
-
glLineWidth(self.width)
|
|
152
|
-
glBegin(GL_LINES)
|
|
153
|
-
glColor4f(1, 1, 1, 1) # z is blue
|
|
154
|
-
glVertex3f(*self.vertices[0, :3])
|
|
155
|
-
glVertex3f(*self.vertices[1, :3])
|
|
156
|
-
glVertex3f(*self.vertices[1, :3])
|
|
157
|
-
glVertex3f(*self.vertices[2, :3])
|
|
158
|
-
glVertex3f(*self.vertices[2, :3])
|
|
159
|
-
glVertex3f(*self.vertices[3, :3])
|
|
160
|
-
glVertex3f(*self.vertices[3, :3])
|
|
161
|
-
glVertex3f(*self.vertices[0, :3])
|
|
162
|
-
glVertex3f(*self.vertices[4, :3])
|
|
163
|
-
glVertex3f(*self.vertices[0, :3])
|
|
164
|
-
glVertex3f(*self.vertices[4, :3])
|
|
165
|
-
glVertex3f(*self.vertices[1, :3])
|
|
166
|
-
glVertex3f(*self.vertices[4, :3])
|
|
167
|
-
glVertex3f(*self.vertices[2, :3])
|
|
168
|
-
glVertex3f(*self.vertices[4, :3])
|
|
169
|
-
glVertex3f(*self.vertices[3, :3])
|
|
170
|
-
glEnd()
|
|
171
|
-
|
|
172
|
-
glDisable(GL_DEPTH_TEST)
|
|
173
|
-
glDisable(GL_BLEND)
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import pyqtgraph.opengl as gl
|
|
2
|
-
from OpenGL.GL import *
|
|
3
|
-
import numpy as np
|
|
4
|
-
import threading
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class TrajectoryItem(gl.GLGridItem):
|
|
8
|
-
def __init__(self, width=1, color=(0, 1, 0, 1)):
|
|
9
|
-
super(TrajectoryItem, self).__init__()
|
|
10
|
-
self.width = width
|
|
11
|
-
self.buff = np.empty((0, 3), np.float32)
|
|
12
|
-
self.wait_add_data = None
|
|
13
|
-
self.mutex = threading.Lock()
|
|
14
|
-
self.CAPACITY = 100000
|
|
15
|
-
self.valid_buff_top = 0
|
|
16
|
-
self.color = color
|
|
17
|
-
|
|
18
|
-
def addSetting(self, layout):
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
|
-
def setData(self, data, append=True):
|
|
22
|
-
self.mutex.acquire()
|
|
23
|
-
data = data.astype(np.float32).reshape(-1, 3)
|
|
24
|
-
if (append is False):
|
|
25
|
-
self.wait_add_data = data
|
|
26
|
-
self.add_buff_loc = 0
|
|
27
|
-
else:
|
|
28
|
-
if (self.wait_add_data is None):
|
|
29
|
-
self.wait_add_data = data
|
|
30
|
-
else:
|
|
31
|
-
self.wait_add_data = np.concatenate([self.wait_add_data, data])
|
|
32
|
-
self.add_buff_loc = self.valid_buff_top
|
|
33
|
-
self.mutex.release()
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def updateRenderBuffer(self):
|
|
37
|
-
if(self.wait_add_data is None):
|
|
38
|
-
return
|
|
39
|
-
self.mutex.acquire()
|
|
40
|
-
|
|
41
|
-
new_buff_top = self.add_buff_loc + self.wait_add_data.shape[0]
|
|
42
|
-
if new_buff_top > self.buff.shape[0]:
|
|
43
|
-
buff_capacity = self.buff.shape[0]
|
|
44
|
-
while (new_buff_top > buff_capacity):
|
|
45
|
-
buff_capacity += self.CAPACITY
|
|
46
|
-
self.buff = np.empty((buff_capacity, 3), np.float32)
|
|
47
|
-
self.buff[self.add_buff_loc:new_buff_top] = self.wait_add_data
|
|
48
|
-
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
|
|
49
|
-
glBufferData(GL_ARRAY_BUFFER, self.buff.nbytes, self.buff, GL_DYNAMIC_DRAW)
|
|
50
|
-
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
|
51
|
-
else:
|
|
52
|
-
self.buff[self.add_buff_loc:new_buff_top] = self.wait_add_data
|
|
53
|
-
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
|
|
54
|
-
glBufferSubData(GL_ARRAY_BUFFER, self.add_buff_loc * 12,
|
|
55
|
-
self.wait_add_data.shape[0] * 12, self.wait_add_data)
|
|
56
|
-
self.valid_buff_top = new_buff_top
|
|
57
|
-
self.wait_add_data = None
|
|
58
|
-
self.mutex.release()
|
|
59
|
-
|
|
60
|
-
def initializeGL(self):
|
|
61
|
-
self.vbo = glGenBuffers(1)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def paint(self):
|
|
65
|
-
self.setupGLState()
|
|
66
|
-
self.updateRenderBuffer()
|
|
67
|
-
glEnable(GL_BLEND)
|
|
68
|
-
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
|
69
|
-
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
|
|
70
|
-
glEnableClientState(GL_VERTEX_ARRAY)
|
|
71
|
-
glVertexPointer(3, GL_FLOAT, 0, None)
|
|
72
|
-
glLineWidth(self.width)
|
|
73
|
-
glColor4f(*self.color) # z is blue
|
|
74
|
-
|
|
75
|
-
glDrawArrays(GL_LINE_STRIP, 0, self.valid_buff_top)
|
|
76
|
-
glDisableClientState(GL_VERTEX_ARRAY)
|
|
77
|
-
|
|
78
|
-
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
|
79
|
-
glUseProgram(0)
|
q3dviewer/gau_io.py
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
from plyfile import PlyData
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def gsdata_type(sh_dim):
|
|
6
|
-
return [('pw', '<f4', (3,)),
|
|
7
|
-
('rot', '<f4', (4,)),
|
|
8
|
-
('scale', '<f4', (3,)),
|
|
9
|
-
('alpha', '<f4'),
|
|
10
|
-
('sh', '<f4', (sh_dim))]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def matrix_to_quaternion(matrices):
|
|
14
|
-
m00, m01, m02 = matrices[:, 0, 0], matrices[:, 0, 1], matrices[:, 0, 2]
|
|
15
|
-
m10, m11, m12 = matrices[:, 1, 0], matrices[:, 1, 1], matrices[:, 1, 2]
|
|
16
|
-
m20, m21, m22 = matrices[:, 2, 0], matrices[:, 2, 1], matrices[:, 2, 2]
|
|
17
|
-
t = 1 + m00 + m11 + m22
|
|
18
|
-
s = np.ones_like(m00)
|
|
19
|
-
w = np.ones_like(m00)
|
|
20
|
-
x = np.ones_like(m00)
|
|
21
|
-
y = np.ones_like(m00)
|
|
22
|
-
z = np.ones_like(m00)
|
|
23
|
-
|
|
24
|
-
t_positive = t > 0.0000001
|
|
25
|
-
s[t_positive] = 0.5 / np.sqrt(t[t_positive])
|
|
26
|
-
w[t_positive] = 0.25 / s[t_positive]
|
|
27
|
-
x[t_positive] = (m21[t_positive] - m12[t_positive]) * s[t_positive]
|
|
28
|
-
y[t_positive] = (m02[t_positive] - m20[t_positive]) * s[t_positive]
|
|
29
|
-
z[t_positive] = (m10[t_positive] - m01[t_positive]) * s[t_positive]
|
|
30
|
-
|
|
31
|
-
c1 = np.logical_and(m00 > m11, m00 > m22)
|
|
32
|
-
cond1 = np.logical_and(np.logical_not(t_positive), np.logical_and(m00 > m11, m00 > m22))
|
|
33
|
-
|
|
34
|
-
s[cond1] = 2.0 * np.sqrt(1.0 + m00[cond1] - m11[cond1] - m22[cond1])
|
|
35
|
-
w[cond1] = (m21[cond1] - m12[cond1]) / s[cond1]
|
|
36
|
-
x[cond1] = 0.25 * s[cond1]
|
|
37
|
-
y[cond1] = (m01[cond1] + m10[cond1]) / s[cond1]
|
|
38
|
-
z[cond1] = (m02[cond1] + m20[cond1]) / s[cond1]
|
|
39
|
-
|
|
40
|
-
c2 = np.logical_and(np.logical_not(c1), m11 > m22)
|
|
41
|
-
cond2 = np.logical_and(np.logical_not(t_positive), c2)
|
|
42
|
-
s[cond2] = 2.0 * np.sqrt(1.0 + m11[cond2] - m00[cond2] - m22[cond2])
|
|
43
|
-
w[cond2] = (m02[cond2] - m20[cond2]) / s[cond2]
|
|
44
|
-
x[cond2] = (m01[cond2] + m10[cond2]) / s[cond2]
|
|
45
|
-
y[cond2] = 0.25 * s[cond2]
|
|
46
|
-
z[cond2] = (m12[cond2] + m21[cond2]) / s[cond2]
|
|
47
|
-
|
|
48
|
-
c3 = np.logical_and(np.logical_not(c1), np.logical_not(c2))
|
|
49
|
-
cond3 = np.logical_and(np.logical_not(t_positive), c3)
|
|
50
|
-
s[cond3] = 2.0 * np.sqrt(1.0 + m22[cond3] - m00[cond3] - m11[cond3])
|
|
51
|
-
w[cond3] = (m10[cond3] - m01[cond3]) / s[cond3]
|
|
52
|
-
x[cond3] = (m02[cond3] + m20[cond3]) / s[cond3]
|
|
53
|
-
y[cond3] = (m12[cond3] + m21[cond3]) / s[cond3]
|
|
54
|
-
z[cond3] = 0.25 * s[cond3]
|
|
55
|
-
return np.array([w, x, y, z]).T
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def load_ply(path, T=None):
|
|
59
|
-
plydata = PlyData.read(path)
|
|
60
|
-
pws = np.stack((np.asarray(plydata.elements[0]["x"]),
|
|
61
|
-
np.asarray(plydata.elements[0]["y"]),
|
|
62
|
-
np.asarray(plydata.elements[0]["z"])), axis=1)
|
|
63
|
-
|
|
64
|
-
alphas = np.asarray(plydata.elements[0]["opacity"])
|
|
65
|
-
alphas = 1/(1 + np.exp(-alphas))
|
|
66
|
-
|
|
67
|
-
scales = np.stack((np.asarray(plydata.elements[0]["scale_0"]),
|
|
68
|
-
np.asarray(plydata.elements[0]["scale_1"]),
|
|
69
|
-
np.asarray(plydata.elements[0]["scale_2"])), axis=1)
|
|
70
|
-
|
|
71
|
-
rots = np.stack((np.asarray(plydata.elements[0]["rot_0"]),
|
|
72
|
-
np.asarray(plydata.elements[0]["rot_1"]),
|
|
73
|
-
np.asarray(plydata.elements[0]["rot_2"]),
|
|
74
|
-
np.asarray(plydata.elements[0]["rot_3"])), axis=1)
|
|
75
|
-
|
|
76
|
-
rots /= np.linalg.norm(rots, axis=1)[:, np.newaxis]
|
|
77
|
-
|
|
78
|
-
sh_dim = len(plydata.elements[0][0])-14
|
|
79
|
-
shs = np.zeros([pws.shape[0], sh_dim])
|
|
80
|
-
shs[:, 0] = np.asarray(plydata.elements[0]["f_dc_0"])
|
|
81
|
-
shs[:, 1] = np.asarray(plydata.elements[0]["f_dc_1"])
|
|
82
|
-
shs[:, 2] = np.asarray(plydata.elements[0]["f_dc_2"])
|
|
83
|
-
|
|
84
|
-
sh_rest_dim = sh_dim - 3
|
|
85
|
-
for i in range(sh_rest_dim):
|
|
86
|
-
name = "f_rest_%d" % i
|
|
87
|
-
shs[:, 3 + i] = np.asarray(plydata.elements[0][name])
|
|
88
|
-
|
|
89
|
-
shs[:, 3:] = shs[:, 3:].reshape(-1, 3, sh_rest_dim//3).transpose([0, 2, 1]).reshape(-1, sh_rest_dim)
|
|
90
|
-
|
|
91
|
-
pws = pws.astype(np.float32)
|
|
92
|
-
rots = rots.astype(np.float32)
|
|
93
|
-
scales = np.exp(scales)
|
|
94
|
-
scales = scales.astype(np.float32)
|
|
95
|
-
alphas = alphas.astype(np.float32)
|
|
96
|
-
shs = shs.astype(np.float32)
|
|
97
|
-
|
|
98
|
-
dtypes = gsdata_type(sh_dim)
|
|
99
|
-
|
|
100
|
-
gs = np.rec.fromarrays(
|
|
101
|
-
[pws, rots, scales, alphas, shs], dtype=dtypes)
|
|
102
|
-
|
|
103
|
-
return gs
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def rotate_gaussian(T, gs):
|
|
107
|
-
# Transform to world
|
|
108
|
-
pws = (T @ gs['pw'].T).T
|
|
109
|
-
w = gs['rot'][:, 0]
|
|
110
|
-
x = gs['rot'][:, 1]
|
|
111
|
-
y = gs['rot'][:, 2]
|
|
112
|
-
z = gs['rot'][:, 3]
|
|
113
|
-
R = np.array([
|
|
114
|
-
[1.0 - 2*(y**2 + z**2), 2*(x*y - z*w), 2*(x * z + y * w)],
|
|
115
|
-
[2*(x*y + z*w), 1.0 - 2*(x**2 + z**2), 2*(y*z - x*w)],
|
|
116
|
-
[2*(x*z - y*w), 2*(y*z + x*w), 1.0 - 2*(x**2 + y**2)]
|
|
117
|
-
]).transpose(2, 0, 1)
|
|
118
|
-
R_new = T @ R
|
|
119
|
-
rots = matrix_to_quaternion(R_new)
|
|
120
|
-
gs['pw'] = pws
|
|
121
|
-
gs['rot'] = rots
|
|
122
|
-
return gs
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def load_gs(fn):
|
|
126
|
-
if fn.endswith('.ply'):
|
|
127
|
-
return load_ply(fn)
|
|
128
|
-
elif fn.endswith('.npy'):
|
|
129
|
-
return np.load(fn)
|
|
130
|
-
else:
|
|
131
|
-
print("%s is not a supported file." % fn)
|
|
132
|
-
exit(0)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def save_gs(fn, gs):
|
|
136
|
-
np.save(fn, gs)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def get_example_gs():
|
|
140
|
-
gs_data = np.array([[0., 0., 0., # xyz
|
|
141
|
-
1., 0., 0., 0., # rot
|
|
142
|
-
0.05, 0.05, 0.05, # size
|
|
143
|
-
1.,
|
|
144
|
-
1.772484, -1.772484, 1.772484],
|
|
145
|
-
[1., 0., 0.,
|
|
146
|
-
1., 0., 0., 0.,
|
|
147
|
-
0.2, 0.05, 0.05,
|
|
148
|
-
1.,
|
|
149
|
-
1.772484, -1.772484, -1.772484],
|
|
150
|
-
[0., 1., 0.,
|
|
151
|
-
1., 0., 0., 0.,
|
|
152
|
-
0.05, 0.2, 0.05,
|
|
153
|
-
1.,
|
|
154
|
-
-1.772484, 1.772484, -1.772484],
|
|
155
|
-
[0., 0., 1.,
|
|
156
|
-
1., 0., 0., 0.,
|
|
157
|
-
0.05, 0.05, 0.2,
|
|
158
|
-
1.,
|
|
159
|
-
-1.772484, -1.772484, 1.772484]
|
|
160
|
-
], dtype=np.float32)
|
|
161
|
-
dtypes = gsdata_type(3)
|
|
162
|
-
gs = np.frombuffer(gs_data.tobytes(), dtype=dtypes)
|
|
163
|
-
return gs
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if __name__ == "__main__":
|
|
167
|
-
gs = load_gs("/home/liu/workspace/EasyGaussianSplatting/data/final.npy")
|
|
168
|
-
print(gs.shape)
|
q3dviewer/utils.py
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import time
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def matrix_to_quaternion(matrix):
|
|
6
|
-
trace = matrix[0, 0] + matrix[1, 1] + matrix[2, 2]
|
|
7
|
-
if trace > 0:
|
|
8
|
-
s = 0.5 / np.sqrt(trace + 1.0)
|
|
9
|
-
w = 0.25 / s
|
|
10
|
-
x = (matrix[2, 1] - matrix[1, 2]) * s
|
|
11
|
-
y = (matrix[0, 2] - matrix[2, 0]) * s
|
|
12
|
-
z = (matrix[1, 0] - matrix[0, 1]) * s
|
|
13
|
-
else:
|
|
14
|
-
if matrix[0, 0] > matrix[1, 1] and matrix[0, 0] > matrix[2, 2]:
|
|
15
|
-
s = 2.0 * np.sqrt(1.0 + matrix[0, 0] - matrix[1, 1] - matrix[2, 2])
|
|
16
|
-
w = (matrix[2, 1] - matrix[1, 2]) / s
|
|
17
|
-
x = 0.25 * s
|
|
18
|
-
y = (matrix[0, 1] + matrix[1, 0]) / s
|
|
19
|
-
z = (matrix[0, 2] + matrix[2, 0]) / s
|
|
20
|
-
elif matrix[1, 1] > matrix[2, 2]:
|
|
21
|
-
s = 2.0 * np.sqrt(1.0 + matrix[1, 1] - matrix[0, 0] - matrix[2, 2])
|
|
22
|
-
w = (matrix[0, 2] - matrix[2, 0]) / s
|
|
23
|
-
x = (matrix[0, 1] + matrix[1, 0]) / s
|
|
24
|
-
y = 0.25 * s
|
|
25
|
-
z = (matrix[1, 2] + matrix[2, 1]) / s
|
|
26
|
-
else:
|
|
27
|
-
s = 2.0 * np.sqrt(1.0 + matrix[2, 2] - matrix[0, 0] - matrix[1, 1])
|
|
28
|
-
w = (matrix[1, 0] - matrix[0, 1]) / s
|
|
29
|
-
x = (matrix[0, 2] + matrix[2, 0]) / s
|
|
30
|
-
y = (matrix[1, 2] + matrix[2, 1]) / s
|
|
31
|
-
z = 0.25 * s
|
|
32
|
-
return np.array([w, x, y, z])
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def quaternion_to_matrix(quaternion):
|
|
36
|
-
_EPS = np.finfo(float).eps * 4.0
|
|
37
|
-
q = np.array(quaternion[:4], dtype=np.float64, copy=True)
|
|
38
|
-
nq = np.dot(q, q)
|
|
39
|
-
if nq < _EPS:
|
|
40
|
-
return np.identity(4)
|
|
41
|
-
q *= np.sqrt(2.0 / nq)
|
|
42
|
-
q = np.outer(q, q)
|
|
43
|
-
return np.array((
|
|
44
|
-
(1.0-q[1, 1]-q[2, 2], q[0, 1]-q[2, 3], q[0, 2]+q[1, 3], 0.0),
|
|
45
|
-
(q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2], q[1, 2]-q[0, 3], 0.0),
|
|
46
|
-
(q[0, 2]-q[1, 3], q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1], 0.0),
|
|
47
|
-
(0.0, 0.0, 0.0, 1.0)
|
|
48
|
-
), dtype=np.float64)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def make_transform(pose, rotation):
|
|
52
|
-
transform = np.matrix(np.identity(4, dtype=np.float64))
|
|
53
|
-
transform = quaternion_to_matrix(rotation)
|
|
54
|
-
transform[0:3, 3] = np.transpose(pose)
|
|
55
|
-
return transform
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class FPSMonitor():
|
|
59
|
-
def __init__(self):
|
|
60
|
-
self.stamp_record = []
|
|
61
|
-
|
|
62
|
-
def count(self):
|
|
63
|
-
cur_stamp = time.time()
|
|
64
|
-
self.stamp_record.append(cur_stamp)
|
|
65
|
-
while len(self.stamp_record) > 0:
|
|
66
|
-
if(cur_stamp - self.stamp_record[0] > 1.):
|
|
67
|
-
self.stamp_record.pop(0)
|
|
68
|
-
else:
|
|
69
|
-
break
|
|
70
|
-
return len(self.stamp_record)
|
|
71
|
-
|
q3dviewer-1.1.7.dist-info/RECORD
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
q3dviewer/__init__.py,sha256=cjyfUE5zK6xohDGDQIWfb0DKkWChVznBd7CrVLg7whQ,376
|
|
2
|
-
q3dviewer/base_glwidget.py,sha256=6Z5rINQ1Y9KqtpBexr0hMX66pNTh6qvovlb7fJe5ZGM,12303
|
|
3
|
-
q3dviewer/base_item.py,sha256=63MarHyoWszPL40ox-vPoOAQ1N4ypekOjoRARdPik-E,1755
|
|
4
|
-
q3dviewer/basic_window.py,sha256=CFErOPRMysFcCqq3vhDsQ-xZzLArO3m1yABCTIhq5do,7946
|
|
5
|
-
q3dviewer/cloud_viewer.py,sha256=IxxrB6Sl6aPCr9P9QzKHGkMcDP_DjsBWbkmIbsAoIM4,2358
|
|
6
|
-
q3dviewer/gau_io.py,sha256=S6NmqL5vSMgHVxKR-eu4CWCqgZeWBJKYRoOMAwr8Xbo,5890
|
|
7
|
-
q3dviewer/glwidget.py,sha256=pkMQxPXNxVWp_sZUFX2r4IHuw_So9ok5e-ZdvBhArFQ,4631
|
|
8
|
-
q3dviewer/utils.py,sha256=evF0d-v17hbTmquC24fmMIp9CsXpUnSQZr4MVy2sfao,2426
|
|
9
|
-
q3dviewer/viewer.py,sha256=Vq3ucDlBcBBoiVVGmqG1sRjhLePl50heblx6wJpsc1A,2603
|
|
10
|
-
q3dviewer/Qt/__init__.py,sha256=CcwS6oSXBXTMr58JNbRNYcPMVubDD2jiPtJ55DoLm8o,2199
|
|
11
|
-
q3dviewer/custom_items/__init__.py,sha256=19z_BFXJEm8j31WqREICN31fiFcaIeUqvfo39d02vbk,509
|
|
12
|
-
q3dviewer/custom_items/axis_item.py,sha256=-WM2urosqV847zpTpOtxdLjb7y9NJqFCH13qqodcCTg,2572
|
|
13
|
-
q3dviewer/custom_items/camera_frame_item.py,sha256=VBsr3Avly_YWXViIh4DJkGc_HJt227GeOYLpGtbYTOw,5605
|
|
14
|
-
q3dviewer/custom_items/cloud_io_item.py,sha256=E3Qyc4nuVP-MQAff4zII9JB-xQjVRsviATpqvpLQveM,3507
|
|
15
|
-
q3dviewer/custom_items/cloud_item.py,sha256=ITOzVq4MAKFIQOGkIgY0Xc2a-yumwHWg3wIvZgjuyGc,13125
|
|
16
|
-
q3dviewer/custom_items/frame_item.py,sha256=bUzww3tSDah0JZeqtU6_cYHhhTVWzXhJVMcAa5pCXHI,7458
|
|
17
|
-
q3dviewer/custom_items/gaussian_item.py,sha256=JMubpahkTPh0E8ShL3FLTahv0e35ODzjgK5K1i0YXSU,9884
|
|
18
|
-
q3dviewer/custom_items/grid_item.py,sha256=LDB_MYACoxld-xvz01_MfAf12vLcRkH7R_WtGHHdSgk,4945
|
|
19
|
-
q3dviewer/custom_items/image_item.py,sha256=k7HNTqdL2ckTbxMx7A7eKaP4aksZ85-pBjNdbpm6PXM,5355
|
|
20
|
-
q3dviewer/custom_items/line_item.py,sha256=rel-lx8AgjDY7qyIecHxHQZzaswRn2ZTiOIjB_0Mrqo,4444
|
|
21
|
-
q3dviewer/custom_items/text_item.py,sha256=VdmoCgXAfqN58fMKydqrdnJHCT53VelRiv_88X9aCfQ,2185
|
|
22
|
-
q3dviewer/custom_items/trajectory_item.py,sha256=uoKQSrTs_m_m1M8iNAm3peiXnZ9uVPsYQLYas3Gksjg,2754
|
|
23
|
-
q3dviewer/shaders/cloud_frag.glsl,sha256=tbCsDUp9YlPe0hRWlFS724SH6TtMeLO-GVYROzEElZg,609
|
|
24
|
-
q3dviewer/shaders/cloud_vert.glsl,sha256=7VrNDbEVqzatpQOuIfFOLYgtbFVWG0Rxl2Od7DZ-l8U,2357
|
|
25
|
-
q3dviewer/shaders/gau_frag.glsl,sha256=5_UY84tWDts59bxP8x4I-wgnzY8aGeGuo28wX--LW7E,975
|
|
26
|
-
q3dviewer/shaders/gau_prep.glsl,sha256=eCT9nm65uz32w8NaDjeGKhyAZh42Aea-QTwr3yQVr9U,7218
|
|
27
|
-
q3dviewer/shaders/gau_vert.glsl,sha256=NNbVhv_JyqZDK9iXAyBAcIHAtim7G9yWbC9IaUfTL1w,1666
|
|
28
|
-
q3dviewer/shaders/sort_by_key.glsl,sha256=CA2zOcbyDGYAJSJEUvgjUqNshg9NAehf8ipL3Jsv4qE,1097
|
|
29
|
-
q3dviewer/tools/__init__.py,sha256=01wG7BGM6VX0QyFBKsqPmyf2e-vrmV_N3-mo-VQ1VBg,20
|
|
30
|
-
q3dviewer/tools/cloud_viewer.py,sha256=-yKVWQb-UWpP7h3khR3dipT_X8XLLL6JllGZJ1vaOM4,3877
|
|
31
|
-
q3dviewer/tools/example_viewer.py,sha256=sedL18GU3bTTjVJBREPVJ5hTLfSDFq_j91E4qXnG8TU,964
|
|
32
|
-
q3dviewer/tools/film_maker.py,sha256=CXsI2SocgnQProIWKJ6lvRXtFv4DoO-rm6YNfweAJmw,16678
|
|
33
|
-
q3dviewer/tools/gaussian_viewer.py,sha256=vIwWmiFhjNmknrEkBLzt2yiegeH7LP3OeNjnGM6GzaI,1633
|
|
34
|
-
q3dviewer/tools/lidar_calib.py,sha256=hHnsSaQh_Pkdh8tPntt0MgEW26nQyAdC_HQHq4I3sw8,10562
|
|
35
|
-
q3dviewer/tools/lidar_cam_calib.py,sha256=AyF3RipBo1R5LYJqm5RR8LUbEovRWJiBUEmUtnrx6e8,11318
|
|
36
|
-
q3dviewer/tools/ros_viewer.py,sha256=ARB3I5wohY3maP8dCu0O0hxObd6JFKuK2y7AApVgMWA,2551
|
|
37
|
-
q3dviewer/utils/__init__.py,sha256=dwTNAAebTiKY4ygv2G1O-w6-TbJnmnNVO2UfJXvJhaQ,107
|
|
38
|
-
q3dviewer/utils/cloud_io.py,sha256=xarfYakY0zgKwvZkgKSPO6b4DEo42hsq3mcvCbK64yg,12134
|
|
39
|
-
q3dviewer/utils/convert_ros_msg.py,sha256=sAoQfy3qLQKsIArBAVm8H--wlQXOcmkKK3-Ox9UCcrc,1686
|
|
40
|
-
q3dviewer/utils/gl_helper.py,sha256=dRY_kUqyPMr7NTcupUr6_VTvgnj53iE2C0Lk0-oFYsI,1435
|
|
41
|
-
q3dviewer/utils/helpers.py,sha256=SqR4YTQZi13FKbkVUYgodXce1JJ_YmrHEIRkUmnIUas,3085
|
|
42
|
-
q3dviewer/utils/maths.py,sha256=zHaPtvVZIuo8xepIXCMeSL9tpx8FahUrq0l4K1oXrBk,8834
|
|
43
|
-
q3dviewer/utils/range_slider.py,sha256=9djTxuzmzH54DgSwAljRpLGjsrIJ0hTxhaxFjPxsk8g,4007
|
|
44
|
-
q3dviewer-1.1.7.dist-info/LICENSE,sha256=81cMOyNfw8KLb1JnPYngGHJ5W83gSbZEBU9MEP3tl-E,1124
|
|
45
|
-
q3dviewer-1.1.7.dist-info/METADATA,sha256=ckr5ZX5GWsS3T7JmlUjlPzgwxRizYkjdV_vCAsBZYHo,7969
|
|
46
|
-
q3dviewer-1.1.7.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
47
|
-
q3dviewer-1.1.7.dist-info/entry_points.txt,sha256=aeUdGH7UIgMZEMFUc-0xPZWspY95GoPdZcZuLceq85g,361
|
|
48
|
-
q3dviewer-1.1.7.dist-info/top_level.txt,sha256=HFFDCbGu28txcGe2HPc46A7EPaguBa_b5oH7bufmxHM,10
|
|
49
|
-
q3dviewer-1.1.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|