obnizのフォーラムは新しいシステムに移行しております。

新しいフォーラムはこちらになります

ArduCAMMini の画像取得時間についての質問



  • https://github.com/obniz/obniz-python-sdk/blob/master/obniz/parts/Camera/ArduCAMMini/README-ja.md
    を参考にArduCAMMini のサンプルソースを試していますが、データ取得の時間が非常に大きいように思います。短縮する方法があれば知りたいです。

    from obniz import Obniz
    import asyncio
    import time
    
    class ElapsedTime:
    
    	def __init__(self):
    		self.t0 = 0
    
    	def record(self, subject):
    		t1 = time.time()	
    		print("elapsed_time[", subject, "]:", t1-self.t0)
    
    		self.t0 = t1
    
    async def onconnect(obniz):
    
    	elapsed_time = ElapsedTime()
    	elapsed_time.record("init")
    
    	cam = obniz.wired("ArduCAMMini", {
    		"cs": 0, "mosi": 1, "miso": 2, "sclk": 3, "gnd": 4, "sda": 6, "scl": 7, "spi_frequency": 1000000
    	})
    
    	count = 0
    
    	await cam.startup_wait()
    	cam.set_size('640x480')
    	await obniz.wait(1000)
    
    	while True:
    
    		print("-------->", count)
    		count+=1
    
    		cam.flush_fifo()
    		cam.flush_fifo()		
    		cam.start_capture()
    
    
    		while True:
    			if await cam.is_capture_done_wait():
    				break
    
    		elapsed_time.record("point1")
    
    		data = await cam.read_fifo_wait()
    
    		elapsed_time.record("point2")
    
    		print("length", len(data))
    
    obniz = Obniz(OBNIZ_ID_HERE)
    obniz.onconnect = onconnect
    
    loop = asyncio.get_event_loop()
    loop.run_forever()
    

    まず、連続で画像取得するにはこのようにflush_fifo(), start_capture() を毎回呼ぶことで正しいでしょうか。バーストのようなイメージでこの両関数は最初の1回だけ呼ぶようにもしてみましたが、正しいJPEG画像が得られませんでした。

    このときの実行結果は以下の通りでした。

     elapsed_time[ init ]: 1582947734.134159
    --------> 0
    elapsed_time[ point1 ]: 2.937614917755127
    elapsed_time[ point2 ]: 2.2012341022491455
    length 18436
    --------> 1
    elapsed_time[ point1 ]: 0.2885429859161377
    elapsed_time[ point2 ]: 2.251394748687744
    length 18436
    --------> 2
    elapsed_time[ point1 ]: 0.37395405769348145
    elapsed_time[ point2 ]: 2.2908759117126465
    length 18436
    --------> 3
    elapsed_time[ point1 ]: 0.3581712245941162
    elapsed_time[ point2 ]: 2.2948689460754395
    length 18436
    --------> 4
    elapsed_time[ point1 ]: 0.2237389087677002
    elapsed_time[ point2 ]: 2.193325996398926
    length 18436
    --------> 5
    elapsed_time[ point1 ]: 0.21819806098937988
    elapsed_time[ point2 ]: 2.2313148975372314
    length 18437
    

    point1 はOV2640内でのfifoに書き終えるまでの時間かと思いますが、ネットで調べたOV2640の仕様によるとSVGA 30 fpsという記載があるのでだいぶ遅いように思います。JPEG出力の場合は変換に時間がかかって速度が落ちるということなのかもしれませんがそれにしても3〜4fpsというのは遅いように思います。

    point2はread_fifo_wait()の時間ですので、ドキュメントから解釈するとカメラのFIFOに入っている撮影されたデータを取り出す時間になるかと思います。2秒以上かかっているので非常に遅いですが、カメラのFIFO 読み出しに加えて、obnizからWifiを経由してPCにデータが到達するまでの時間ということになるでしょうか。

    トータルで3〜4fpsを目標にしたいのですが、何か良い方法があれば教えて欲しいです。



  • @津久井-陽司
    こんにちは。

    速度に関してですが、obnizはspi等のやり取りがインターネット経由となるためマイコン上にプログラムを書き込むのと異なり頻繁なやり取りは特に速度が遅くなってしまいます。
    特にpythonの場合はobniz.jsのようにlocal connectが提供されていないため必ずクラウド経由の通信となり同一Wi-Fiだとしても低速となってしまいます。

    すぐできてある程度効果的と思われるのが解像度を下げることですが、
    それ以外にも既に試していただいているような方法やstart_capture()なしで行けないのかやis_capture_done_wait()よるpollingをなしで行けないのかなどで速度改善を試すこととなります。(毎度撮影でなく、streamingモードのようなものがあればそのような動作が可能そうです。)。
    一方的な送信・受信操作であればインターネットの帯域のみに依存するためlatencyのみの問題となります。
    データシートを見てみたのですが、そのようなsequenceの例が載っていなかったためできるかどうかまだわからないです。



  • ご回答ありがとうございます。

    解像度の変更も既に試みていますが、160x120の解像度でも満足できるフレームレートは得られていません。カメラの性能をある程度使えるようにしたいというのがやりたいことになります。

    pythonはクラウドを経由し、obniz.jsはlocal connectを使えるということですね。
    python の豊富な画像処理ライブラリを使いたいので、画像取得はjavascriptを使い、画像処理はpythonを使うというシステムも一つの選択肢として検討してみます。

    ただ、画像キャプチャ自体にかかっている時間も短縮が必要ですので、これが今は実現できていないということであれば、そもそもobnizを使うということ自体を見直した方が早いかもしれませんね。カメラのデータシートを見てドライバレベルの実装をするというのはなかなか時間がかかるので最終手段にしたいところです。

    やりたいことは、ArudCAMミニのようなコンパクトサイズのカメラモジュールから15fps以上のレートで画像をできるだけ簡単に取得して、pythonで画像処理したいですが、ラズベリーパイなどを使った方が早いのかもしれませんね。

    検討し直します。



  • @津久井-陽司
    なるほど。
    確かにRaspberrypiであればpythonもその上で動くので速いかもしれません。
    組み合わせとしてArduino+Aruducamで撮影したのをuartでobniz経由で取得する方法もありますが、15fpsとなるとArduinoがそもそも間に合わないかもしれないですね。mpegではなく連続したjpeg写真なので難しいものがありますね。

    動画レベルのfpsで転送できると新しい使い方もできそうなのでobnizOSにそのような機能が入れられないか検討してみたいと思います。



  • @Yuki-Sato said in ArduCAMMini の画像取得時間についての質問:

    Arduino+Aruducamで撮影したのをuartでobniz経由で取得する方法

    Arduino使ったことはないですが、UART、SPIの速度をフルに出せないということはないように思います。DMAもあるでしょうし。カメラのドライバがきちんとできていればインターフェースの速度はフルに出せるのではないでしょうか。ただ、UARTで115.2kbpsとかだとさすがにJPEG動画は厳しいかと思います。

    ちなみに今回のサンプルは一方向の送信ですが、それでもフレームレートは落ちてしまうのでしょうか。クラウドが間に入るということなのでなんとなく、そういうものかと思いますが、実際にはクラウドを介した実装を経験したことがないので、あまりピンと来ない部分もあります。単に640x480のJPEGをインターネットに流すだけでここまで遅いというのも感覚的には違和感がありまして、obnizくらい小さい基板だとそのWifiの実効帯域が小さいのではなどと思ったりしてみたり。すみません、古いエンジニアなので。最近はそんなことはないのでしょうが。

    いずれにせよサーバー経由だと遅延が出てよろしくないので、obnizは諦めた方が良いと思っていまして単なる興味本意の感想です。すみません。

    Raspberry Piを調べてみましたが私の要求はさっくりいけそうですのでそちらを試すことになりそうです。



  • @津久井-陽司

    ちなみに今回のサンプルは一方向の送信ですが、それでもフレームレートは落ちてしまうのでしょうか。

    上記の場合SPI通信ですのでobnizでは一方向ではないです。
    1byte通信するとしてもプログラムが動いているマシンからSPI通信の要求がインターネット経由で送られて、SPIで通信し、その結果を受け取るという流れになるためSPI,I2Cなどは書き込みにしても読み取りにしても双方向通信と受信までの待機が発生します。

    いずれにせよサーバー経由だと遅延が出てよろしくないので、obnizは諦めた方が良いと思っていまして単なる興味本意の感想です。すみません。

    Raspberry Piを調べてみましたが私の要求はさっくりいけそうですのでそちらを試すことになりそうです。

    RaspberryPiで実装された際に、インターネット経由での操作やブラウザでUIとして結果の表示や操作ボタンの表示などを行われたい際にはぜひobnizをRaspberryPiなどにつないでご利用いただければと思います。



  • なるほど、SPIの制御までをサーバーを介して行うという仕様ですか。想像もできませんでした。てっきりファームウェアを無線でobnizに送信してその上で実行しているのかと思っていましたが全く違うのですね。なかなかユニークな基板ですね。ワイヤレスIOと思えば良いでしょうか。
    だいたいイメージわかってきまして、今回の用途で使うには違うということはわかりました。
    ありがとうございます。



  • @津久井-陽司

    ワイヤレスIOと思えば良いでしょうか。

    はい。その通りです。
    プログラムはブラウザやサーバーで動くため、データベースやUIなどとの自由な連携ができます。
    SPI通信などの中で細かくブレークポイントを置くこともできます。

    いわゆるIoTに非常に向いていますので、ぜひ何か作ってみていただければと思います。



SUGGESTED TOPICS