On Screen Keyboard (PC and Console) best practices - Unity Answers
上記記事のコードをコピペして呼び出すと出てくる。Windows10にはTouchKeyboardとOn-Screen-Keyboardの2種類のスクリーンキーボードがあるが、試したところOSKは不可能でTouchKeyboardのみ呼び出し可能だった。できるのは、キーボードの表示・非表示のみ。
On Screen Keyboard (PC and Console) best practices - Unity Answers
上記記事のコードをコピペして呼び出すと出てくる。Windows10にはTouchKeyboardとOn-Screen-Keyboardの2種類のスクリーンキーボードがあるが、試したところOSKは不可能でTouchKeyboardのみ呼び出し可能だった。できるのは、キーボードの表示・非表示のみ。
Macで映像転送と言えばSyphonですが、PythonでSyphonできないぽかったのでメモリマップトファイルを利用して実装しました。メモリマップトファイルはメモリを映像のような大量のデータだとソケット通信とかでは速度が間に合わないので、これ一択ぽいです。メモリマップトファイルにバイト列として画像を置いて通信する仕組みです。
注意点としては、映像のフォーマットを送受信出来ないので、決めうちにする必要があります。今回は1200x1200のRGB画像を送る前提のサンプルコードを載せておきます。なおコードは元のプロジェクトから抜き出して書いているもので、テストしておりません。ライセンスはパブリックドメインです。
Unityは、Monoではなく.NET Coreでないとメモリマップトファイルが利用出来なかった気がします。Unity側ではRawImageにメモリマップトファイルから取り出したTextureを貼ってます。Textureは明示的にDestoryしないとメモリーリークするので気をつけて。
import os import mmap DATA_LENGTH = 4320000 fd = os.open('/tmp/mmappython', os.O_CREAT | os.O_TRUNC | os.O_RDWR) assert os.write(fd, b'\x00' * DATA_LENGTH) == DATA_LENGTH buf = mmap.mmap(fd, DATA_LENGTH, mmap.MAP_SHARED, mmap.PROT_WRITE) buf.seek(0) byte_data = b'\x00' * DATA_LENGTH buf.write(byte_data) buf.close()
using System.Collections; using System.Collections.Generic; using System.IO; using System.IO.MemoryMappedFiles; using UnityEngine; using UnityEngine.UI; public class MmfManager : MonoBehaviour { private string filePath = "/tmp/mmappython"; private const int dataLength = 4320000; private RawImage rawImage; private MemoryMappedFile mmf; private MemoryMappedViewStream stream; public void InitMemoryMappedFile() { if (File.Exists(filePath) == false) { byte[] bs = new byte[dataLength]; using(FileStream fs = File.Open(filePath, FileMode.Create)) { fs.Write(bs, 0, bs.Length); } } mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.Open); Debug.Log(filePath); stream = mmf.CreateViewStream(); Debug.Log(stream.Capacity); Debug.Log(stream.Length); } void Start () { rawImage = GetComponent<RawImage>(); } void Update () { stream.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[dataLength]; int retVal = stream.Read(buffer, 0, dataLength); if (retVal == dataLength) { Texture oldTex = rawImage.texture; Texture2D tex = new Texture2D(1200, 1200, TextureFormat.RGB24, false); tex.LoadRawTextureData(buffer); tex.Apply(); rawImage.texture = tex; Destroy(oldTex); } } void OnDestroy() { stream.Close(); stream.Dispose(); mmf.Dispose(); stream = null; mmf = null; } }
intel RealSense™ Depth Camera D435
FUJIFILM 光吸収・赤外線透過フィルター(IRフィルター) 単品 フイルター IR 76 7.5X 1
Kinect後継として指名されているIntelのRealSenseシリーズだが、距離をセンシングするIRステレオカメラ部は、単体の赤外線カメラとして利用可能だ。性能、値段、入手性のバランスが優れた赤外線カメラと言える。D415とD435の2種類あり、後者のほうが広角なのだが、センサからして違うので、どちらを選ぶかの参考になるように記事をまとめた。
librealsenseはIntel公式のようで公式ではないらしいSDK。特に問題なく使えるが、コメントで書いた通り、カメラ側に設定を反映させるのに変なコツがいる。
# coding: utf-8 import pyrealsense2 as rs import numpy as np import cv2 # Stop Laser Emitter context = rs.context() sensor = context.sensors[0] sensor.set_option(rs.option.emitter_enabled, 0.0) # pipelineを一度start()しないと最初の接続時に設定が反映されない pipeline = rs.pipeline() pipeline.start() pipeline.stop() config = rs.config() config.enable_stream(rs.stream.infrared, 1, 1280, 720, rs.format.y8, 30) pipeline.start(config) cv2.namedWindow('pysense', cv2.WINDOW_AUTOSIZE) try: while True: frames = pipeline.wait_for_frames() ir_frame = frames.get_infrared_frame() if not ir_frame: continue ir_image = np.asanyarray(ir_frame.get_data()) cv2.imshow('pysense', ir_image) k = cv2.waitKey(1) if k == 27: break finally: pipeline.stop() cv2.destroyAllWindows()
赤外線カメラとして利用する場合、D435の方が、
といった値段相応の機能性と使いやすさがあるため、ケチケチしたプロジェクトでない限りはD435がオススメだ。