From 6318891502dae95e109134b657dcb81010ed7eca Mon Sep 17 00:00:00 2001 From: Kazik Pogoda Date: Sat, 24 Aug 2019 00:30:31 +0200 Subject: [PATCH] orx-kinect-v1-demo module for testing the code and verifying use cases --- orx-kinect-v1-demo/build.gradle | 13 ++++ .../src/main/kotlin/BasicUseCaseDemo.kt | 26 +++++++ .../src/main/kotlin/DepthToColorMapsDemo.kt | 73 +++++++++++++++++++ .../src/main/kotlin/MultipleKinectsDemo.kt | 27 +++++++ .../main/kotlin/NativeFreenectCommandsDemo.kt | 39 ++++++++++ .../src/main/resources/logback.xml | 13 ++++ settings.gradle | 39 +++++----- 7 files changed, 211 insertions(+), 19 deletions(-) create mode 100644 orx-kinect-v1-demo/build.gradle create mode 100644 orx-kinect-v1-demo/src/main/kotlin/BasicUseCaseDemo.kt create mode 100644 orx-kinect-v1-demo/src/main/kotlin/DepthToColorMapsDemo.kt create mode 100644 orx-kinect-v1-demo/src/main/kotlin/MultipleKinectsDemo.kt create mode 100644 orx-kinect-v1-demo/src/main/kotlin/NativeFreenectCommandsDemo.kt create mode 100644 orx-kinect-v1-demo/src/main/resources/logback.xml diff --git a/orx-kinect-v1-demo/build.gradle b/orx-kinect-v1-demo/build.gradle new file mode 100644 index 00000000..9ef36ea1 --- /dev/null +++ b/orx-kinect-v1-demo/build.gradle @@ -0,0 +1,13 @@ +def os = org.gradle.internal.os.OperatingSystem.current() +def openrndrOs +if (os.windows) { openrndrOs = "windows" } +else if (os.macOsX) { openrndrOs = "macos" } +else if (os.linux) { openrndrOs = "linux-x64" } + +dependencies { + compile project(":orx-kinect-v1") + runtime project(":orx-kinect-v1-natives-$openrndrOs") + runtime "org.openrndr:openrndr-gl3:$openrndrVersion" + runtime "org.openrndr:openrndr-gl3-natives-$openrndrOs:$openrndrVersion" + runtime "ch.qos.logback:logback-classic:1.2.3" +} diff --git a/orx-kinect-v1-demo/src/main/kotlin/BasicUseCaseDemo.kt b/orx-kinect-v1-demo/src/main/kotlin/BasicUseCaseDemo.kt new file mode 100644 index 00000000..8cca5feb --- /dev/null +++ b/orx-kinect-v1-demo/src/main/kotlin/BasicUseCaseDemo.kt @@ -0,0 +1,26 @@ +package org.openrndr.extra.kinect.v1.demo + +import org.openrndr.application +import org.openrndr.extra.kinect.v1.getKinectsV1 + +/** + * Basic kinect use case showing continuous stream from the depth camera. + * + * Note: kinect depth map is stored only on the RED color channel to save + * space. Therefore depth map is displayed only in the red tones. + */ +fun main() = application { + configure { // default resolution of the Kinect v1 depth camera + width = 640 + height = 480 + } + program { + val kinects = getKinectsV1(this) + val kinect = kinects.startDevice() + kinect.depthCamera.enabled = true + kinect.depthCamera.mirror = true + extend { + drawer.image(kinect.depthCamera.currentFrame) + } + } +} diff --git a/orx-kinect-v1-demo/src/main/kotlin/DepthToColorMapsDemo.kt b/orx-kinect-v1-demo/src/main/kotlin/DepthToColorMapsDemo.kt new file mode 100644 index 00000000..150491e5 --- /dev/null +++ b/orx-kinect-v1-demo/src/main/kotlin/DepthToColorMapsDemo.kt @@ -0,0 +1,73 @@ +package org.openrndr.extra.kinect.v1.demo + +import org.openrndr.application +import org.openrndr.draw.ColorBuffer +import org.openrndr.draw.ColorFormat +import org.openrndr.draw.colorBuffer +import org.openrndr.extra.kinect.* +import org.openrndr.extra.kinect.v1.getKinectsV1 + +/** + * Shows 4 different representations of the depth map. + *
    + *
  1. the original depth map stored as RED channel values
  2. + *
  3. the same values expressed as gray tones
  4. + *
  5. + * color map according to natural light dispersion as described + * by Alan Zucconi in the + * Improving the Rainbow + * article. + *
  6. + *
  7. + * color map according to + * + * Turbo, An Improved Rainbow Colormap for Visualization + * + * by Google. + *
  8. + *
+ * + * @see DepthToGrayscaleMapper + * @see DepthToColorsZucconi6Mapper + * @see DepthToColorsTurboMapper + */ +fun main() = application { + configure { + width = 2 * 640 + height = 2 * 480 + } + program { + val kinects = getKinectsV1(this) + val kinect = kinects.startDevice() + kinect.depthCamera.enabled = true + kinect.depthCamera.mirror = true + val camera = kinect.depthCamera + val grayscaleFilter = DepthToGrayscaleMapper() + val zucconiFilter = DepthToColorsZucconi6Mapper() + val turboFilter = DepthToColorsTurboMapper() + val grayscaleBuffer = kinectColorBuffer(camera) + val zucconiBuffer = kinectColorBuffer(camera) + val turboBuffer = kinectColorBuffer(camera) + extend { + /* + * Note: getting the latest frame this way will guarantee + * that filters are being applied only if the actual new frame + * from kinect was received. Kinect has different refresh rate + * than usual screen (30 fps). + */ + kinect.depthCamera.getLatestFrame()?.let { frame -> + grayscaleFilter.apply(frame, grayscaleBuffer) + zucconiFilter.apply(frame, zucconiBuffer) + turboFilter.apply(frame, turboBuffer) + } + drawer.image(camera.currentFrame) + drawer.image(grayscaleBuffer, camera.width.toDouble(), 0.0) + drawer.image(turboBuffer, 0.0, camera.height.toDouble()) + drawer.image(zucconiBuffer, camera.width.toDouble(), camera.height.toDouble()) + } + } +} + +private fun kinectColorBuffer(camera: KinectCamera): ColorBuffer { + return colorBuffer(camera.width, camera.height, format = ColorFormat.RGB) +} \ No newline at end of file diff --git a/orx-kinect-v1-demo/src/main/kotlin/MultipleKinectsDemo.kt b/orx-kinect-v1-demo/src/main/kotlin/MultipleKinectsDemo.kt new file mode 100644 index 00000000..2d4a0657 --- /dev/null +++ b/orx-kinect-v1-demo/src/main/kotlin/MultipleKinectsDemo.kt @@ -0,0 +1,27 @@ +package org.openrndr.extra.kinect.v1.demo + +import org.openrndr.application +import org.openrndr.extra.kinect.v1.getKinectsV1 + +/** + * Stream from 2 kinects side by side. + */ +fun main() = application { + configure { + width = 640 * 2 + height = 480 + } + program { + val kinects = getKinectsV1(this) + val depthCamera1 = kinects.startDevice(0).depthCamera + val depthCamera2 = kinects.startDevice(1).depthCamera + depthCamera1.enabled = true + depthCamera1.mirror = true + depthCamera2.enabled = true + depthCamera2.mirror = true + extend { + drawer.image(depthCamera1.currentFrame) + drawer.image(depthCamera2.currentFrame, depthCamera1.width.toDouble(), 0.0) + } + } +} diff --git a/orx-kinect-v1-demo/src/main/kotlin/NativeFreenectCommandsDemo.kt b/orx-kinect-v1-demo/src/main/kotlin/NativeFreenectCommandsDemo.kt new file mode 100644 index 00000000..720435fc --- /dev/null +++ b/orx-kinect-v1-demo/src/main/kotlin/NativeFreenectCommandsDemo.kt @@ -0,0 +1,39 @@ +package org.openrndr.extra.kinect.v1.demo + +import org.bytedeco.libfreenect.global.freenect +import org.bytedeco.libfreenect.global.freenect.* +import org.openrndr.application +import org.openrndr.extra.kinect.v1.getKinectsV1 + +/** + * Even though this library is abstracting freenect access, it is still + * possible to call any low level kinect API through execute methods. + * The calls are executed in separate kinect runner thread but they will + * block the calling thread until the result is returned. + */ +fun main() = application { + program { + val kinects = getKinectsV1(this) + kinects.execute { ctx -> + freenect_set_log_level(ctx.fnCtx, freenect.FREENECT_LOG_FLOOD) // lots of logs + } + kinects.execute { ctx -> + // extra FREENECT_DEVICE_MOTOR gives control over tilt and LEDs + freenect_select_subdevices(ctx.fnCtx, FREENECT_DEVICE_CAMERA xor FREENECT_DEVICE_MOTOR) + } + val kinect = kinects.startDevice() + var tilt = 90.0 + extend { + kinect.execute { ctx -> + freenect_set_led(ctx.fnDev, (seconds * 10).toInt() % 7) // disco + } + val currentTilt = if ((seconds % 10) < 5) -90.0 else 90.0 + if (currentTilt != tilt) { + kinect.execute { ctx -> + freenect_set_tilt_degs(ctx.fnDev, currentTilt) + } + tilt = currentTilt + } + } + } +} diff --git a/orx-kinect-v1-demo/src/main/resources/logback.xml b/orx-kinect-v1-demo/src/main/resources/logback.xml new file mode 100644 index 00000000..3d7044e6 --- /dev/null +++ b/orx-kinect-v1-demo/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + true + + + + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + diff --git a/settings.gradle b/settings.gradle index 420d5f80..01422ade 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,22 +1,23 @@ rootProject.name = 'orx' include 'orx-camera', - 'orx-compositor', - 'orx-easing', - 'orx-file-watcher', - 'orx-filter-extension', - 'orx-integral-image', - 'orx-interval-tree', - 'orx-jumpflood', - 'orx-kdtree', - 'orx-mesh-generators', - 'orx-midi', - 'orx-no-clear', - 'orx-noise', - 'orx-obj-loader', - 'orx-olive', - 'orx-kinect-common', - 'orx-kinect-v1', - 'orx-kinect-v1-natives-linux-x64', - 'orx-kinect-v1-natives-macos' - 'orx-kinect-v1-natives-windows' + 'orx-compositor', + 'orx-easing', + 'orx-file-watcher', + 'orx-filter-extension', + 'orx-integral-image', + 'orx-interval-tree', + 'orx-jumpflood', + 'orx-kdtree', + 'orx-mesh-generators', + 'orx-midi', + 'orx-no-clear', + 'orx-noise', + 'orx-obj-loader', + 'orx-olive', + 'orx-kinect-common', + 'orx-kinect-v1', + 'orx-kinect-v1-natives-linux-x64', + 'orx-kinect-v1-natives-macos', + 'orx-kinect-v1-natives-windows', + 'orx-kinect-v1-demo'