SPRESENSEカメラのモニターをProcessingで作ってみた! [SPRESENSE]
前回、SPRESENSEとProcessingを使ってタイムラプスカメラを作ってみました。そこに、いつもチェックしているスタックオーバーフローで次のような問いかけが!
カメラのリアルタイムのプレビューをPCの画面に表示する方法
SPRESENSEのカメラで現在映しているプレビューを、PCの画面に表示させることは可能でしょうか。接続方法は、できれば、USB(メインボード側のSerial)が良いです。
ん!?これは、できそうな気がするぞ。SPRESENSEとProcessingを使えば…。
ということでチャレンジしてみました!
接続はリクエスト通りシリアルケーブル一本で。SPRESENSE からプレビュー画像を転送し、PC上の Processing でデータを受けて画像を表示します。
余談ですが、少し前に3Dプリンタで作ったカメラホルダをつけてみました。カメラとUSBケーブルの干渉がなくなり、少しすっきりしました。
今回作成したスケッチです。すごくシンプルなのですが、Processing のシリアルはなかなか使いこなすのが大変で苦労しました。Windows + Java のためか、リアルタイムには程遠く、安定した通信をするために、ところどころ工夫が必要でした。
SPRESENSEのスケッチ
Processingのスケッチ
動かしてみると、パフォーマンスは、おおよそ 0.9-0.8fps 。理論的には、 (2000000/8) bytes / 153,600 bytes / =1.6 fps 位のはずですが、Processing の応答性が思いのほか悪く、あまり良い数字は出ませんでした。
実際の動きはこちらの動画で見ることができます!
パフォーマンスはいまいちですけど、この小さなカメラで画面を見れるのはいいですね。次はプレビューではなくて、もう少し大きな画像を転送してみようかな…。
(^^)/~
<参考記事>
SPRESENSEとProcessingでタイムラプスに挑戦!
https://makers-with-myson.blog.so-net.ne.jp/2019-08-17
カメラのリアルタイムのプレビューをPCの画面に表示する方法
SPRESENSEのカメラで現在映しているプレビューを、PCの画面に表示させることは可能でしょうか。接続方法は、できれば、USB(メインボード側のSerial)が良いです。
ん!?これは、できそうな気がするぞ。SPRESENSEとProcessingを使えば…。
ということでチャレンジしてみました!
接続はリクエスト通りシリアルケーブル一本で。SPRESENSE からプレビュー画像を転送し、PC上の Processing でデータを受けて画像を表示します。
余談ですが、少し前に3Dプリンタで作ったカメラホルダをつけてみました。カメラとUSBケーブルの干渉がなくなり、少しすっきりしました。
今回作成したスケッチです。すごくシンプルなのですが、Processing のシリアルはなかなか使いこなすのが大変で苦労しました。Windows + Java のためか、リアルタイムには程遠く、安定した通信をするために、ところどころ工夫が必要でした。
SPRESENSEのスケッチ
#include <Camera.h> #define BAUDRATE 2000000 void CamCB(CamImage img) { if (img.isAvailable() == false) return; while (Serial.available() <= 0); // taking a picture is started by receiving 'S' if (Serial.read() != 'S') return; delay(1); // wait for stable connection digitalWrite(LED0, HIGH); img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565); char *buf = img.getImgBuff(); for (int i = 0; i < img.getImgSize(); ++i, ++buf) { Serial.write(*buf); } digitalWrite(LED0, LOW); } void setup() { Serial.begin(BAUDRATE); while (!Serial) {}; theCamera.begin(); theCamera.startStreaming(true, CamCB); theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT); } void loop() { /* do nothing here */ }
Processingのスケッチ
import processing.serial.*; import java.io.*; Serial myPort; PImage img; final static int WIDTH = 320; final static int HEIGHT = 240; boolean started = false; int serialTimer = 0; int total = 0; int x = 0; int y = 0; void setup() { size(320, 240); background(0); img = createImage(WIDTH, HEIGHT, RGB); myPort = new Serial(this, Serial.list()[0], 2000000); myPort.clear(); println("setup finished"); delay(2000); // wait for stable connection } void draw() { if (started == false) { started = true; println("start"); myPort.write('S'); myPort.clear(); total = 0; delay(10); return; } // To get stable connection, please adjsut this interval final int interval = 1; if (millis() - serialTimer > interval) { serialTimer = millis(); if (myPort.available() <= 0) return; while (myPort.available() > 0) { char lbyte = (char)myPort.read(); char ubyte = (char)myPort.read(); x = total % WIDTH; y = total / WIDTH; int value = (ubyte << 8) | (lbyte); // RGB565 format char r = (char)(((value & 0xf800) >> 11) << 3); char g = (char)(((value & 0x07E0) >> 5) << 2); char b = (char)((value & 0x001f) << 3); color c = color(r, g, b); img.set(x, y, c); ++total; if (total >= WIDTH*HEIGHT) { println("end"); myPort.clear(); started = false; total = 0; image(img, 0, 0); break; } } } }
動かしてみると、パフォーマンスは、おおよそ 0.9-0.8fps 。理論的には、 (2000000/8) bytes / 153,600 bytes / =1.6 fps 位のはずですが、Processing の応答性が思いのほか悪く、あまり良い数字は出ませんでした。
実際の動きはこちらの動画で見ることができます!
パフォーマンスはいまいちですけど、この小さなカメラで画面を見れるのはいいですね。次はプレビューではなくて、もう少し大きな画像を転送してみようかな…。
(^^)/~
<参考記事>
SPRESENSEとProcessingでタイムラプスに挑戦!
https://makers-with-myson.blog.so-net.ne.jp/2019-08-17