-
Notifications
You must be signed in to change notification settings - Fork 29
/
20.motion_vectors.py
237 lines (191 loc) · 6.73 KB
/
20.motion_vectors.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
import nvisii
import os
import numpy as np
from math import acos
from math import sqrt
from math import pi
import colorsys
import cv2
opt = lambda: None
opt.spp = 100
opt.width = 1280
opt.height = 720
opt.noise = False
opt.path_obj = 'content/dragon/dragon.obj'
opt.outf = '20_motion_vectors_outf/'
# # # # # # # # # # # # # # # # # # # # # # # # #
if os.path.isdir(opt.outf):
print(f'folder {opt.outf}/ exists')
else:
os.mkdir(opt.outf)
print(f'created folder {opt.outf}/')
# # # # # # # # # # # # # # # # # # # # # # # # #
nvisii.initialize(headless=True, verbose=True)
if not opt.noise is True:
nvisii.enable_denoiser()
camera = nvisii.entity.create(
name = "camera",
transform = nvisii.transform.create("camera"),
camera = nvisii.camera.create(
name = "camera",
aspect = float(opt.width)/float(opt.height)
)
)
camera.get_transform().look_at(
at = (0,0.1,0.1),
up = (0,0,1),
eye = (0,3.0,0.2),
)
nvisii.set_camera_entity(camera)
nvisii.set_dome_light_sky(sun_position = (10, 10, 1), saturation = 2)
nvisii.set_dome_light_intensity(1.5)
# # # # # # # # # # # # # # # # # # # # # # # # #
floor = nvisii.entity.create(
name = "floor",
mesh = nvisii.mesh.create_plane("floor", size = (10,10)),
material = nvisii.material.create("floor", base_color = (.5, .5, .5), roughness = 0.0, metallic = 1.0),
transform = nvisii.transform.create("floor", position = (0,0,-.3))
)
# Next, let's load an obj
mesh = nvisii.mesh.create_from_file("obj", opt.path_obj)
# Now, lets make three instances of that mesh
obj1 = nvisii.entity.create(
name="obj1",
mesh = mesh,
transform = nvisii.transform.create("obj1"),
material = nvisii.material.create("obj1")
)
obj2 = nvisii.entity.create(
name="obj2",
mesh = mesh,
transform = nvisii.transform.create("obj2"),
material = nvisii.material.create("obj2")
)
obj3 = nvisii.entity.create(
name="obj3",
mesh = mesh,
transform = nvisii.transform.create("obj3"),
material = nvisii.material.create("obj3")
)
obj4 = nvisii.entity.create(
name="obj4",
mesh = mesh,
transform = nvisii.transform.create("obj4"),
material = nvisii.material.create("obj4")
)
# place those objects into the scene
# lets set the obj_entity up
obj1.get_transform().set_position((-1.5, 0, 0))
obj1.get_transform().set_rotation((0.7071, 0, 0, 0.7071))
obj1.get_material().set_base_color((1,0,0))
obj1.get_material().set_roughness(0.7)
obj1.get_material().set_specular(1)
obj1.get_material().set_sheen(1)
obj2.get_transform().set_position((-.5, 0, 0))
obj2.get_transform().set_rotation((0.7071, 0, 0, 0.7071))
obj2.get_material().set_base_color((0,1,0))
obj2.get_material().set_roughness(0.7)
obj2.get_material().set_specular(1)
obj2.get_material().set_sheen(1)
obj3.get_transform().set_position((.5, 0, 0))
obj3.get_transform().set_rotation((0.7071, 0, 0, 0.7071))
obj3.get_material().set_base_color((0,0,1))
obj3.get_material().set_roughness(0.7)
obj3.get_material().set_specular(1)
obj3.get_material().set_sheen(1)
obj4.get_transform().set_position((1.5, 0, 0))
obj4.get_transform().set_rotation((0.7071, 0, 0, 0.7071))
obj4.get_material().set_base_color((.5,.5,.5))
obj4.get_material().set_roughness(0.7)
obj4.get_material().set_specular(1)
obj4.get_material().set_sheen(1)
# # # # # # # # # # # # # # # # # # # # # # # # #
# MOTION VECTORS section
# need to remove the motion blur that adding previous transform will cause.
# We also want the motion from frame 0 to 1
nvisii.sample_time_interval((0,0))
# make sure that raw sample the middle the of the pixel
# without this there will be noise on the motion segmentation
nvisii.sample_pixel_area(
x_sample_interval = (.5,.5),
y_sample_interval = (.5, .5)
)
def length(v):
return np.sqrt(v[0]**2+v[1]**2)
def dot_product(v,w):
return v[0]*w[0]+v[1]*w[1]
def normalize(v):
norm=np.linalg.norm(v, ord=1)
if norm==0:
norm=np.finfo(v.dtype).eps
return v/norm
def determinant(v,w):
return v[0]*w[1]-v[1]*w[0]
def inner_angle(v,w):
cosx=dot_product(v,w)/(length(v)*length(w))
rad=acos(cosx) # in radians
return rad*180/pi # returns degrees
def py_ang(A, B=(1,0)):
inner=inner_angle(A,B)
det = determinant(A,B)
if det<0: #this is a property of the det. If the det < 0 then B is clockwise of A
return inner
else: # if the det > 0 then A is immediately clockwise of B
return 360-inner
def generate_image_from_motion_vector(motion_vectors_array, use_magnitude=False):
image = np.zeros(motion_vectors_array.shape)
image[:,:,3] =1
indices = np.abs(motion_vectors_array[:,:,0]) + np.abs(motion_vectors_array[:,:,1])
indices = np.nonzero(indices > 0)
for i_indice in range(len(indices[0])):
i,j = indices[0][i_indice], indices[1][i_indice]
angle_vector = np.array([
motion_vectors_array[i,j,0],
motion_vectors_array[i,j,1]]
)
magnitude = length(angle_vector)
# Use the hsv to apply color as a function of the angle
c = [0,0,0]
if magnitude > 0.000001:
angle=py_ang(angle_vector)
if use_magnitude:
c = colorsys.hsv_to_rgb(angle/360,1,magnitude)
else:
c = colorsys.hsv_to_rgb(angle/360,1,1)
# for i_c in range(3):
image[i,j,0:3] = c
return image
nvisii.render_to_file(
width=int(opt.width),
height=int(opt.height),
samples_per_pixel=int(opt.spp),
file_path=opt.outf + "20_frame1.png"
)
obj1.get_transform().set_position(obj1.get_transform().get_position(),previous=True)
obj1.get_transform().add_position(nvisii.vec3(0,0.5,0))
obj2.get_transform().set_position(obj2.get_transform().get_position(),previous=True)
obj2.get_transform().add_position(nvisii.vec3(0,0,0.5))
obj3.get_transform().set_rotation(obj3.get_transform().get_rotation(),previous=True)
obj3.get_transform().add_rotation(nvisii.quat(0,-1,0,0))
motion_vectors_array = nvisii.render_data(
width=int(opt.width),
height=int(opt.height),
start_frame=0,
frame_count=1,
bounce=int(0),
options="diffuse_motion_vectors"
)
motion_vectors_array = np.array(motion_vectors_array).reshape(opt.height,opt.width,4) * -1
motion_vectors_array = np.flipud(motion_vectors_array)
image = generate_image_from_motion_vector(motion_vectors_array)
cv2.imwrite(opt.outf + "20_motion_from_1_to_2.png",image*255)
# frame now has to be set at 1 to have the current image, e.g., the transformed one
nvisii.sample_time_interval((1,1))
nvisii.render_to_file(
width=int(opt.width),
height=int(opt.height),
samples_per_pixel=int(opt.spp),
file_path=opt.outf + "20_frame2.png"
)
# let's clean up the GPU
nvisii.deinitialize()