UnitV で画像シリアル転送の味見 ーエッジAI活用への道 12ー
前回よりUnitV を使用したハイテク金魚水槽システムの実現に方向転換しているこの道。
今回はUnitV で撮影した画像をシリアルでM5StickC に転送して表示してみます。
目次
構成
UnitVとM5StickCをUnitVに付属された4ピンコネクタケーブルでつなぐだけです。
動作
早速動作をご覧ください。
UnitV と M5StickC
さすがにビットマップそのまま転送はしんどいですね。
あとなんか色おかしい。なんで? pic.twitter.com/VZefAvXvoU— HomeMadeGarbage (@H0meMadeGarbage) January 16, 2020
撮影画像(64×160)をUARTでM5StickCに送って表示しています。FPS 3ってところでしょうか。。
あとなんか色がおかしいです。おそらく転送や受信でおかしいことをしているのでしょう。。。俺のことだし
ではコード(間違い探し)をご覧ください。
UnitVコード(MaixPy IDE)
UnitVで撮影画像(64×160)をUART送信します。demo_uart.py とdemo_camera.pyを参考にコーディングしました。
転送ボーレートは921600にしました。
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 |
from machine import UART from board import board_info from fpioa_manager import fm from Maix import GPIO import sensor, lcd sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.set_windowing((64,160)) sensor.set_vflip(1) sensor.set_hmirror(1) sensor.run(1) sensor.skip_frames() fm.register(35, fm.fpioa.UART1_TX, force=True) fm.register(34, fm.fpioa.UART1_RX, force=True) uart = UART(UART.UART1, 921600,8,0,0, timeout=1000, read_buf_len=4096) while(True): img = sensor.snapshot() uart.write(img) |
参考
- M5StickV MicroPython Instructions
- M5StickV MicroPython 画像処理<imageクラス>
- M5StickV MicroPython 画像取得<sensorクラス>
M5StickCコード(Arduino IDE)
64ピクセル × 160ピクセル × 2バイトの撮影画像を受信してLCDに表示します。
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 |
#include <M5StickC.h> int x = 64, y = 160; uint8_t rx_buffer[20480]; uint16_t rx_buffer2[10240]; uint16_t color; void setup() { M5.begin(); M5.Axp.ScreenBreath(13); Serial.begin(115200); Serial2.begin(921600, SERIAL_8N1, 32, 33); } void loop() { if (Serial2.available()) { int rx_size = Serial2.readBytes(rx_buffer, 2*x*y); Serial.println("RX!"); for(int i = 0; i < x*y; i++){ rx_buffer2[i] = rx_buffer[2*i] << 8 + rx_buffer[2*i+1]; } M5.Lcd.drawBitmap(0, 0, x, y, rx_buffer2); } } |
参考
おわりに
送受信コードのどこかに問題があるために色がおかしいですが、撮影画像のビットマップUART転送は現実的ではないことを実感として得ることができました。
次回は圧縮してWiFi転送なぞを試してみたいです。
ではまた
追記
色修正 (2020/1/17)
M5StickCのLCD表示の際に色がおかしかった原因がわかりました。
M5StickCコードの23行目で2バイトの色データ生成しているのですが、
ビットシフトの時に16ビットにキャストし忘れてました。。
1 2 3 4 5 |
rx_buffer2[i] = rx_buffer[2*i] << 8 + rx_buffer[2*i+1]; ↓ 修正 rx_buffer2[i] = (uint16_t)(rx_buffer[2*i] << 8) + rx_buffer[2*i+1]; |
なおった。
やはりコードミス
ビットシフトの時に16ビットにキャストしないといけないのね。。。rx_buffer2[i] = rx_buffer[2*i] << 8 + rx_buffer[2*i+1];
↓
rx_buffer2[i] = (uint16_t)(rx_buffer[2*i] << 8) + rx_buffer[2*i+1]; pic.twitter.com/8iFUtT2wVr— HomeMadeGarbage (@H0meMadeGarbage) January 17, 2020
無事に色が正常に表示されるようになりました。
色修正2 (2020/1/18)
ご指摘がありました。ありがとうございます!
ビットシフトより足し算の方が演算の優先順位が高いので、単にカッコの効果かも知れません
— mはげ (@Tw_Mhage) January 18, 2020
その通りでした。単純に()するだけで改善しました。
1 2 3 4 5 |
rx_buffer2[i] = rx_buffer[2*i] << 8 + rx_buffer[2*i+1]; ↓ 修正 rx_buffer2[i] = (rx_buffer[2*i] << 8) + rx_buffer[2*i+1]; |
ビットシフトより足し算の方が演算の優先順位が高い!
勉強になりました。
ボーレート変更 (2020/1/18)
転送ボーレートを921600 → 1152000 (1M)にしてみました。
ボーレート 1152000 (1M)にしてみた。
こんなもんかな。
4Mはさすがに通信できませんでした。 pic.twitter.com/e5APEI9Jch— HomeMadeGarbage (@H0meMadeGarbage) January 18, 2020
少し早くなったかな。
あとUnitVの撮影画像をサイズ変更して出力すると左上に偏ります。。 sensor.set_framesize や sensor.set_windowing が中央でクロップしてくれないんです。。
なんだかなぁ 🙄
参考
copy() (2020/1/18)
以下参考してcopy()なるものを知る
sensor.set_framesize(sensor.VGA)
で
img = sensor.snapshot()
img2 = img.copy((280,160,80,160))
したらM5StickCにLCDフルサイズで中央の絵を転送できた。
但し、遅い https://t.co/UcBe0G0Swr pic.twitter.com/xqi2qgc16x— HomeMadeGarbage (@H0meMadeGarbage) January 18, 2020
これでカメラ中央の絵を取り扱えるようになったが、VGA取り込んでいるので当然遅い。。。