airpocket が 2022年12月20日17時39分13秒 に編集
初版
タイトルの変更
USB音カメラ
タグの変更
MaixBit
MaixPy
Sipeed
Python
micropython
マイクアレイ
メイン画像の変更
記事種類の変更
製作品
ライセンスの変更
(MIT) The MIT License
本文の変更
# はじめに 以前、Sipeed の Maix Bit というマイコンボードと 6+1 Microphon Array と言うボードを使って音を可視化する装置を制作しました。せみ捕りに使うとものすごいパフォーマンスを発揮するデバイスなのですが、聴覚支援用の端末としても役立ちそうな面白いデバイスになりました。今回はこのデバイスをPC接続して使用できるUSB音カメラとして再開発しました。 # できたもの 完成品はこのようなものになりました。 筐体は試作初号機です。あまりきれいではないため、設計変更する予定です。 ![キャプションを入力できます](https://camo.elchika.com/f1eb2cba6cd13ef8e05caa98c3740dca3804be85/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666662353561372d373433312d346234382d383832642d3565323665663534343465652f37343034386334632d333661612d343537612d383437302d313861356566336633313330/) このデバイスは、マイクアレイで採取した音データをMaix Bitで解析して16×16pixel のグレースケール画像として出力します。データはUSB Serialでpython list形式のデータとして出力します。PC側の受信用ツールとしては高橋さんが開発したImage Processing Node Editorを使用しました。 USB音カメラで撮影した音画像と、PCに接続しているWebCamなどの画像を合成すると、WebCam上に音の発生元が表示されます。 # デバイス制作 3Dプリント部品のデータとコードは[こちら](https://github.com/airpocket-soundman/SoundCamera) ## 部品 |部品|個数| |-|-| |[Maix Bit](https://www.switch-science.com/products/5702?_pos=1&_sid=8f5e5537f&_ss=r)|1個| |[6+1 Mic Array](https://ja.aliexpress.com/item/1005003514456324.html)|1| |M3x5 screw|4| |M3 nut|4| |M3x10 screw|3| |M2x5 screw|2| |M2x5 spacer|2| |female to famale jumper pin|10| |3Dプリンターパーツ|1式| maix bitはswitch scienceさんにもまだ在庫がありますが、6+1 mic array は在庫切れのままなのでaliexpressあたりで購入するのが良いかもしれません。 3D プリンターで筐体を制作しています。3Dプリンター部品にはM3ネジ、M2ネジ、カメラ用1/4ネジの下穴をあけていますが、プリンタ設定や材料の特性の違いにより穴サイズがへんかするので注意してください。 ## 組み立て M3x5ネジとナットⅹ4で、マイクアレイを筐体の6角形の凹み部に固定します。 M2スペーサーとM2x5ネジで、Mais Bitを固定します。 MaixBit と Mic Arryaをジャンパケーブルで接続し、M3x10ネジ3本で、筐体を組み立てます。 ジャンパケーブルは次の通り接続します。 | Maix Bit | Mic Array | |:---:|:---:| |PIN23|MIC_D0| |PIN22|MIC_D1| |PIN21|MIC_D2| |PIN20|MIC_D3| |PIN19|MIC_WS |PIN18|MIC_BCK| |PIN17|LED_CK| |PIN15|LID_DA| |3V3|VIN| |GND|GND| ## プログラム Maix Bit用のプログラムは次の様な内容です。 以前、Maix Bit単体で制作した音を可視化する装置から、カメラやディスプレイの制御をなくし、16×16ピクセルの音源マップをUSBシリアルから出力する内容となっています。音源マップはpythonのlist形式のデータをそのまま出力しています。受け側でデコードして文字列からlist にパースすればそのまま利用できます。 文字列からlist形式の変換はpythonならjsonモジュールがやってくれます。 コメントアウトしている行は、音源マップの重心座標を計算しています。マップではなく、座標でよい場合はこちらを。 ```python #v100 sound camera ver1.0.0 from Maix import MIC_ARRAY as mic from Maix import FPIOA from fpioa_manager import fm import lcd import sensor import gc from Maix import utils #heap mem使用量確認及び設定用 utils.gc_heap_size(2500000) #Heap mem山盛り設定 soundmap画像を480*480に引き伸ばし処理するため増量必要。 mic.init() Fpioa = FPIOA() LEDdir = (0,0,0) #マイクアレイモジュールのLEDインジケーター表示。RGBの輝度を0-255で設定。まぶしいのでいらない。 #Maxi Bit用のピン設定。 Fpioa.set_function(23, fm.fpioa.I2S0_IN_D0); Fpioa.set_function(22, fm.fpioa.I2S0_IN_D1); Fpioa.set_function(21, fm.fpioa.I2S0_IN_D2); Fpioa.set_function(20, fm.fpioa.I2S0_IN_D3); Fpioa.set_function(19, fm.fpioa.I2S0_WS); Fpioa.set_function(18, fm.fpioa.I2S0_SCLK); Fpioa.set_function(17, fm.fpioa.GPIOHS28); Fpioa.set_function(15, fm.fpioa.GPIOHS27); while True: soundmap = mic.get_map() #マイクアレイから音源の推定位置を16*16pixelのgrayscaleで求める。 # sumM = 0 # sumMx = 0 # sumMy = 0 grayMap = [] for mapx in range(16): grayLine = [] for mapy in range(16): # sumM = sumM + soundmap.get_pixel(mapx,mapy) # sumMx = sumMx + (mapx * soundmap.get_pixel(mapx,mapy)) # sumMy = sumMy + (mapy * soundmap.get_pixel(mapx,mapy)) grayLine.append(soundmap.get_pixel(mapx,mapy)) # print(grayLine) grayMap.append(grayLine) # if sumM > 0: # print(sumMx/sumM,sumMy/sumM) print(grayMap) sounddir = mic.get_dir(soundmap) #soundmapから音源方向を求める? mic.set_led(sounddir,(LEDdir)) #マイクアレイモジュールのLEDを光らせる。 mic.deinit() ``` ## プログラムの書き込みなど Maix Bitでこのプログラムを実行するには、ファイル名をmain.pyとしてフラッシュメモリに書き込むか、microSDカードに書き込んで挿入する必要があります。 フラッシュメモリに書き込む場合は、[upyloader](https://github.com/BetaRavener/uPyLoader/releases/tag/v0.1.4)を使用します。 USBシリアルでデータを出力している間は、フラッシュへの書き込みに失敗する事が多かったので、[maixpyIDE](https://dl.sipeed.com/shareURL/MAIX/MaixPy/ide/v0.2.5)のターミナルツールなどを使って接続し、プログラムを停止してから接続した方が良いかもしれません。 どうしても書き込みができない場合は [kflash gui](https://github.com/sipeed/kflash_gui/releases/tag/v1.8.1) を使って、[maixpyのファーム](https://dl.sipeed.com/MAIX/MaixPy/release/master/)を書き換えてからupyloader で main.pyを書き込むという流れが一番安定していました。 ファームにもいろいろありますが、標準ファームを使用します。バージョンはどれでもOKです。 # Image Processing Node Editor Image Processing Node Editor は、pythonのdearpyguiモジュールで作られたノードベースの画像処理ツールです。@KzhtTkhs さん作成の神ツールだったので、USB音カメラ用のノードを作って動かしています。 Image Processing Node Editor のオリジナルのリポジトリは[こちら](https://github.com/Kazuhito00/Image-Processing-Node-Editor) 怖くて本家にプルリクしてないフォークしたリポジトリは[こちら](https://github.com/airpocket-soundman/Image-Processing-Node-Editor)。USB音カメラのノードは、まだ本家には入ってません。 インストール方法までしっかり説明していただいています。Win10及びWin11環境で動作確認しています。 私の環境だと、Build Tools for Visual Studio 2019が足りないと言われたので、[こちらのサイト](https://www.kkaneko.jp/tools/win/buildtool2019.html)などを参考にインストールしました。 # デバイスの使い方 ## 接続 USB音カメラとPCをUSBケーブルで接続します。 音画像とUSBカメラ画像を重ね合わせる場合はUSBカメラもPCに接続します。 ## 配置 USB音カメラは、カメラ正面より若干上寄りの画像を表示する様に設定しています。USB音カメラの上にUSBカメラを設置すると画角の調節がしやすくなります。 ## Image Processing Node Editorの使い方 Image Processing Node Editorのmain.pyを実行します。 上部メニューから、WebCam、SoundCam、AlphaBlend、resultの4つのノードを引き出します。 WebCamノードのRGB出力チャンネルとSoundCamのRGB出力チャンネルをそれぞれ、AlphaBlendノードのRGB入力チャンネルに接続すると、合成された画像がAlphaBlendノードに表示されます。 WebCam と SoundCamの画像がずれる場合は、カメラの位置と向きを調節して、画像の中心位置と向きを調整します。画像のスケールが合わない場合は、それぞれのカメラノードとAlphaBlendノードの間にCropノードを挿入して、画角の調整をして下さい。 うまくできると、このように動きます。 @[twitter](https://twitter.com/AirpocketRobot/status/1603366032290115584)