Skip to content

Commit 91dd23e

Browse files
authored
Merge pull request #44 from rnd-team-dev/r0.15.1
R0.15.1
2 parents 6afe0f5 + 2d203dd commit 91dd23e

File tree

87 files changed

+484
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+484
-31
lines changed

CHANGELOG.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
Release history
22
===============
33

4+
`v0.15.1` - 2023-03-16
5+
----------------------
6+
7+
Added
8+
~~~~~
9+
10+
- OpenCV-like intrinsic matrix in camera setup
11+
- configurable denoiser start frame
12+
13+
Changed
14+
~~~~~~~
15+
16+
- ovrlaping refractive volumes handling
17+
18+
419
`v0.15.0` - 2022-12-30
520
----------------------
621

@@ -553,6 +568,7 @@ Added
553568
- this changelog, markdown description content type tag for PyPI
554569
- use [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
555570

571+
.. _`v0.15.1`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.15.1
556572
.. _`v0.15.0`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.15.0
557573
.. _`v0.14.4`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.14.4
558574
.. _`v0.14.3`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.14.3

examples/1_basics/12_camera_shaders.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@
10271027
],
10281028
"metadata": {
10291029
"kernelspec": {
1030-
"display_name": "Python 3",
1030+
"display_name": "Python 3 (ipykernel)",
10311031
"language": "python",
10321032
"name": "python3"
10331033
},
@@ -1041,7 +1041,7 @@
10411041
"name": "python",
10421042
"nbconvert_exporter": "python",
10431043
"pygments_lexer": "ipython3",
1044-
"version": "3.7.4"
1044+
"version": "3.10.6"
10451045
}
10461046
},
10471047
"nbformat": 4,
Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"## Camera calibration\n",
8+
"\n",
9+
"Pinhole and thin-lens cameras accept OpenCV-like intrinsics matrix in setup/update functions. This notebook illustrates how intrinsic parameters should be provided and how you can recover them with OpenCV camera calibration."
10+
]
11+
},
12+
{
13+
"cell_type": "code",
14+
"execution_count": 1,
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"import numpy as np\n",
19+
"import cv2 as cv\n",
20+
"from plotoptix import TkOptiX"
21+
]
22+
},
23+
{
24+
"cell_type": "markdown",
25+
"metadata": {},
26+
"source": [
27+
"Setup the raytracer:"
28+
]
29+
},
30+
{
31+
"cell_type": "code",
32+
"execution_count": 2,
33+
"metadata": {},
34+
"outputs": [],
35+
"source": [
36+
"rt = TkOptiX(start_now=False)\n",
37+
"\n",
38+
"rt.set_param(min_accumulation_step=4,\n",
39+
" max_accumulation_frames=512)"
40+
]
41+
},
42+
{
43+
"cell_type": "markdown",
44+
"metadata": {},
45+
"source": [
46+
"Add chess board pattern used for calibration."
47+
]
48+
},
49+
{
50+
"cell_type": "code",
51+
"execution_count": 3,
52+
"metadata": {},
53+
"outputs": [],
54+
"source": [
55+
"rx = 10\n",
56+
"ry = 10\n",
57+
"n = 11\n",
58+
"\n",
59+
"x = np.linspace(0, rx, n)\n",
60+
"y = np.linspace(0, ry, n)\n",
61+
"X, Y = np.meshgrid(x, y)\n",
62+
"\n",
63+
"# positions of cubes\n",
64+
"xyz = np.stack((X.flatten(), Y.flatten(), np.zeros(n**2))).T - np.array([0, 0, 0.15])\n",
65+
"\n",
66+
"widx = [i for i in range(0,xyz.shape[0]) if i % 2 == 0]\n",
67+
"bidx = [i for i in range(0,xyz.shape[0]) if i % 2 == 1]\n",
68+
"\n",
69+
"xp = np.linspace(1, rx, n-1)\n",
70+
"yp = np.linspace(1, ry, n-1)\n",
71+
"Xp, Yp = np.meshgrid(xp, yp)\n",
72+
"xyzp = np.stack((Xp.flatten(), Yp.flatten(), np.zeros((n-1)**2))).T.astype(np.float32)\n",
73+
"#rt.set_data(\"points\", xyzp, r=0.1, c=0.9) # points to confirm true positions of objpoints\n",
74+
"\n",
75+
"rt.set_data(\"wcubes\", xyz[widx,:], u=[0.998, 0, 0], v=[0, 0.998, 0], w=[0, 0, 0.15], c=0.93, geom=\"Parallelepipeds\")\n",
76+
"rt.set_data(\"bcubes\", xyz[bidx,:], u=[0.998, 0, 0], v=[0, 0.998, 0], w=[0, 0, 0.15], c=0.15, geom=\"Parallelepipeds\")\n",
77+
"rt.set_data(\"base\", [-0.5, -0.5, -0.3], u=[12, 0, 0], v=[0, 12, 0], w=[0, 0, 0.2], c=0.9, geom=\"Parallelepipeds\")\n",
78+
"\n",
79+
"rt.set_data(\"plane\", [-20, -20, -1], u=[50, 0, 0], v=[0, 50, 0], c=0.9, geom=\"Parallelograms\") # a wall behind cubes\n",
80+
"\n",
81+
"rt.setup_area_light(\"light1\", center=[15, 4, 15], target=[5, 4, 0], u=7, v=7, color=[8.5, 8, 7.5])\n",
82+
"\n",
83+
"rt.set_ambient([0.1, 0.2, 0.4])\n",
84+
"rt.set_background(0)"
85+
]
86+
},
87+
{
88+
"cell_type": "markdown",
89+
"metadata": {},
90+
"source": [
91+
"Camera setup. Absolute scale in [mm] is used, though it requires to specify sensor height (Y dimension)."
92+
]
93+
},
94+
{
95+
"cell_type": "code",
96+
"execution_count": 4,
97+
"metadata": {},
98+
"outputs": [],
99+
"source": [
100+
"sensor_height = 24 # [mm]\n",
101+
"fx = 17 # [mm]\n",
102+
"fy = 17 # [mm]\n",
103+
"cx = 3 # [mm]\n",
104+
"cy = 0 # [mm]\n",
105+
"\n",
106+
"# OpenCV-like camera intrinsic matrix\n",
107+
"cam_mat = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]], dtype=np.float32)\n",
108+
"\n",
109+
"eye = [7, 7, 10]\n",
110+
"tgt = [6, 6, 0]\n",
111+
"up = [0, -1, 0]\n",
112+
"\n",
113+
"rt.setup_camera(\n",
114+
" \"cam1\", cam_type=\"ThinLens\",\n",
115+
" eye=eye, target=tgt, up=up,\n",
116+
" camera_matrix=cam_mat,\n",
117+
" sensor_height=sensor_height,\n",
118+
" glock=True\n",
119+
")"
120+
]
121+
},
122+
{
123+
"cell_type": "markdown",
124+
"metadata": {},
125+
"source": [
126+
"Start the ray tracing:"
127+
]
128+
},
129+
{
130+
"cell_type": "code",
131+
"execution_count": 5,
132+
"metadata": {
133+
"scrolled": true
134+
},
135+
"outputs": [],
136+
"source": [
137+
"rt.start()"
138+
]
139+
},
140+
{
141+
"cell_type": "markdown",
142+
"metadata": {},
143+
"source": [
144+
"**Collect calibration images.**\n",
145+
"\n",
146+
"Calibration with OpenCV is performed for a fixed image size, this it is set below to 1300x950 to avoid changes caused by the GUI.\n",
147+
"\n",
148+
"Change the anlgle of view and/or camera target and wait until callback notifies image was captured. Collect a few images. These will be used to reconstruct camera parameters."
149+
]
150+
},
151+
{
152+
"cell_type": "code",
153+
"execution_count": 10,
154+
"metadata": {},
155+
"outputs": [
156+
{
157+
"name": "stdout",
158+
"output_type": "stream",
159+
"text": [
160+
"1 images captured\n",
161+
"2 images captured\n",
162+
"3 images captured\n",
163+
"4 images captured\n",
164+
"5 images captured\n",
165+
"6 images captured\n",
166+
"7 images captured\n"
167+
]
168+
}
169+
],
170+
"source": [
171+
"width = 1500\n",
172+
"height = 950\n",
173+
"\n",
174+
"rt.set_rt_size((width, height))\n",
175+
"\n",
176+
"imgpoints = []\n",
177+
"objpoints = []\n",
178+
"\n",
179+
"def image_ready(rt: TkOptiX) -> None:\n",
180+
" gray = cv.cvtColor(rt._img_rgba, cv.COLOR_BGR2GRAY)\n",
181+
" retval, corners = cv.findChessboardCorners(gray, (n-1, n-1))\n",
182+
" if retval:\n",
183+
" corners2 = cv.cornerSubPix(\n",
184+
" gray, corners, (5,5), (-1,-1),\n",
185+
" (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 0.001)\n",
186+
" )\n",
187+
" imgpoints.append(corners2)\n",
188+
" objpoints.append(100*xyzp.astype(np.float32))\n",
189+
"\n",
190+
" print(len(imgpoints), \"images captured\")\n",
191+
" else:\n",
192+
" print(\"skip image\")\n",
193+
" \n",
194+
"rt.set_accum_done_cb(image_ready)"
195+
]
196+
},
197+
{
198+
"cell_type": "markdown",
199+
"metadata": {},
200+
"source": [
201+
"Run camera calibration. OpenCV returns calues in [pixels] so they need to appropriate scaling to get values back in [mm]."
202+
]
203+
},
204+
{
205+
"cell_type": "code",
206+
"execution_count": 13,
207+
"metadata": {},
208+
"outputs": [
209+
{
210+
"name": "stdout",
211+
"output_type": "stream",
212+
"text": [
213+
"fx: 672.6737619162795\n",
214+
"fy: 672.6596888212799\n",
215+
"fx: 16.99386345893759 [mm]\n",
216+
"fy: 16.993507928116546 [mm]\n",
217+
"cx: 0.12460680641213917\n",
218+
"cy: -0.000521407446712252\n",
219+
"cx: 2.99056335389134 [mm]\n",
220+
"cy: -0.012513778721094049 [mm]\n",
221+
"dist: [[-2.07361708e-04 4.49837393e-04 9.99845034e-06 -4.78913174e-06\n",
222+
" -2.68033315e-04]]\n"
223+
]
224+
}
225+
],
226+
"source": [
227+
"img_size = rt.get_size()\n",
228+
"pixel_pitch = sensor_height / img_size[1]\n",
229+
"\n",
230+
"ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, img_size, None, None)\n",
231+
"\n",
232+
"print(\"fx:\", mtx[0,0])\n",
233+
"print(\"fy:\", mtx[1,1])\n",
234+
"print(\"fx:\", pixel_pitch * mtx[0,0], \"[mm]\")\n",
235+
"print(\"fy:\", pixel_pitch * mtx[1,1], \"[mm]\")\n",
236+
"print(\"cx:\", mtx[0,2] / img_size[0] - 0.5)\n",
237+
"print(\"cy:\", mtx[1,2] / img_size[1] - 0.5)\n",
238+
"print(\"cx:\", sensor_height * (mtx[0,2] / img_size[0] - 0.5), \"[mm]\")\n",
239+
"print(\"cy:\", sensor_height * (mtx[1,2] / img_size[1] - 0.5), \"[mm]\")\n",
240+
"print(\"dist:\", dist)"
241+
]
242+
},
243+
{
244+
"cell_type": "markdown",
245+
"metadata": {},
246+
"source": [
247+
"Try another set of parameters and re-run image capturing and calibration."
248+
]
249+
},
250+
{
251+
"cell_type": "code",
252+
"execution_count": 11,
253+
"metadata": {},
254+
"outputs": [],
255+
"source": [
256+
"sensor_height = 24 # [mm]\n",
257+
"fx = 21 # [mm]\n",
258+
"fy = 18 # [mm]\n",
259+
"cx = 0 # [mm]\n",
260+
"cy = -2 # [mm]\n",
261+
"\n",
262+
"# OpenCV-like camera intrinsic matrix\n",
263+
"cam_mat = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]], dtype=np.float32)\n",
264+
"\n",
265+
"rt.update_camera(\"cam1\",\n",
266+
" camera_matrix=cam_mat,\n",
267+
" sensor_height=sensor_height,\n",
268+
")"
269+
]
270+
},
271+
{
272+
"cell_type": "markdown",
273+
"metadata": {},
274+
"source": [
275+
"Close the ray-tracer."
276+
]
277+
},
278+
{
279+
"cell_type": "code",
280+
"execution_count": 33,
281+
"metadata": {},
282+
"outputs": [],
283+
"source": [
284+
"rt.close()"
285+
]
286+
}
287+
],
288+
"metadata": {
289+
"kernelspec": {
290+
"display_name": "Python 3 (ipykernel)",
291+
"language": "python",
292+
"name": "python3"
293+
},
294+
"language_info": {
295+
"codemirror_mode": {
296+
"name": "ipython",
297+
"version": 3
298+
},
299+
"file_extension": ".py",
300+
"mimetype": "text/x-python",
301+
"name": "python",
302+
"nbconvert_exporter": "python",
303+
"pygments_lexer": "ipython3",
304+
"version": "3.10.6"
305+
}
306+
},
307+
"nbformat": 4,
308+
"nbformat_minor": 2
309+
}

examples/1_basics/4_materials_and_glass_colors.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@
346346
],
347347
"metadata": {
348348
"kernelspec": {
349-
"display_name": "Python 3",
349+
"display_name": "Python 3 (ipykernel)",
350350
"language": "python",
351351
"name": "python3"
352352
},
@@ -360,7 +360,7 @@
360360
"name": "python",
361361
"nbconvert_exporter": "python",
362362
"pygments_lexer": "ipython3",
363-
"version": "3.7.4"
363+
"version": "3.10.6"
364364
}
365365
},
366366
"nbformat": 4,

examples/1_basics/4_materials_configuration.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@
237237
],
238238
"metadata": {
239239
"kernelspec": {
240-
"display_name": "Python 3",
240+
"display_name": "Python 3 (ipykernel)",
241241
"language": "python",
242242
"name": "python3"
243243
},
@@ -251,7 +251,7 @@
251251
"name": "python",
252252
"nbconvert_exporter": "python",
253253
"pygments_lexer": "ipython3",
254-
"version": "3.7.4"
254+
"version": "3.10.6"
255255
}
256256
},
257257
"nbformat": 4,

0 commit comments

Comments
 (0)