aravis解析 その2 [aravis]
昨日から始めたaravisの解析。昨日はaravisのライブラリとしての基本的な使い方をさらっとやった。かなり簡単に使えるようになっていることがわかる。よくできている。
今日はカメラ属性の操作とカメラ列挙とフレームバッファの使い方などについて....
このsignal/closureとは別のコールバックメカニズムが用意されていて、streamを作るarv_camera_create_stream()を呼ぶときに専用のコールバックを渡すことができる。
新しいバッファができたらそのたびにArvStream自身がコールバックを起動する。起動のタイミングはいくつか設定できる。したがってこの場合、コールバック内でもたもたしているとフレーム取りこぼしの可能性があるので注意が必要である。
こちらのコールバックは何かフラグをセットする、とかタイミングを抽出する、というような軽いもののためのようである。
まず、aravisから見えるハードウェアインターフェイスは
の2つの関数で調べることができる。実はこれはコンパイル時点で決まっていて
を呼ぶことで探索が実行される。
インターフェイスの場合と同じように
を使って接続されたカメラの名前(device ID)を得ることができる。device IDは、同じモデルが複数ある場合に備えて、ベンダ名とモデル名とカメラ本体のシリアルナンバをつなぎ合わせた文字列になっている(USB3ではモデル名を簡略化した文字列にシリアルナンバが追加された文字列になっているようである)。arv_camera_new()関数にこの文字列を渡すとそのカメラのオブジェクトを得ることができる。USB3とGigEの両方が同時に列挙される。
複数台のカメラが接続されている場合、device IDで区別してそれぞれのカメラオブジェクトを作れば独立に使うことができる。こういうところも言うまでもなくオブジェクト指向風に作られているメリットである。
得られる属性としては
payloadはGigE visionのペイロードタイプに従ってバッファの中身がなにかを表す。
この二つを調べてデータが正常で、かつ要求に従ったペイロードなら処理を継続する、ということになる。
さらに、ArvBufferの中身が一番一般的な画像データの場合は
画像データ本体は
これ以外に画像の縦横のサイズや部分転送の場合の領域などを調べることができる。
今日はカメラ属性の操作とカメラ列挙とフレームバッファの使い方などについて....
2.1.2 もうひとつのコールバックメカニズム
1フレームの転送が終わって新しいバッファオブジェクトがいっぱいになったあとコールバックが呼ばれることを書いたが、ArvStreamオブジェクトがコールバックを呼ぶわけではない。ArvStreamオブジェクトは「signal」をセットするだけで次の転送の準備をする。「signal」は最終的に設定したコールバックが呼ばれる。そこには非同期なメカニズムが備わっているらしいけど、マニュアルを読んでもよくわからなかった。signalがNSNotificationと似たようなものであれば、GmainLoopがコールバック呼び出しのタイミングを決めるはずである。このsignal/closureとは別のコールバックメカニズムが用意されていて、streamを作るarv_camera_create_stream()を呼ぶときに専用のコールバックを渡すことができる。
void (*ArvStreamCallback) (void *user_data, ArvStreamCallbackType type, ArvBuffer *buffer); ArvStream *arv_camera_create_stream (ArvCamera *camera, ArvStreamCallback callback, void *user_data);
こちらのコールバックは何かフラグをセットする、とかタイミングを抽出する、というような軽いもののためのようである。
2.1.3 デバイス列挙
複数のカメラが接続されている場合や、必要なカメラを探す場合や、あるいは正常に接続されているかを確かめる場合、デバイス列挙、つまりaravisから見えるカメラを探索して、それぞれのモデル名やベンダ名などを調べる、という作業を実行する必要がある。まず、aravisから見えるハードウェアインターフェイスは
unsigned int arv_get_n_interfaces (void); const char *arv_get_interface_id (unsigned int index);
- Fake
- USB3Vision
- GigEVision
void arv_update_device_list (void);
インターフェイスの場合と同じように
unsigned int arv_get_n_devices (void); const char *arv_get_device_id (unsigned int index);
複数台のカメラが接続されている場合、device IDで区別してそれぞれのカメラオブジェクトを作れば独立に使うことができる。こういうところも言うまでもなくオブジェクト指向風に作られているメリットである。
2.1.4 カメラの操作
カメラの特性や操作、例えばイメージャの画素数を知ったり、シャッタやゲインを変えたり、などは主にカメラオブジェクトArvCameraを通して行う。ただしごく一般的などのカメラにも備わっているものだけになっている。得られる属性としては
- イメージャの画素数
- フレームレート
- ピクセルフォーマット(ビット幅やカラーかモノクロかなど)
- シャッタ(露光時間)
- ゲイン
- トリガ
- ビニング(イメージャの解像度を落として見かけ上感度をあげる)
- その他
2.1.5 フレームバッファ
フレームバッファオブジェクトのArvBufferは汎用的で、画像データだけではなく、とにかくカメラから送られてくるデータのバッファになっている。ArvBufferはざっくり- status
- payload type
- 成功(エラー無し)
- 中身が空
- パケット全部が到達する前にタイムアウトした
- ロストしたパケットがある
- パケットIDが不正
- サイズが不正
- その他
ArvBufferStatus arv_buffer_get_status (ArvBuffer *buffer);で得られる。返された値はenumにある。
payloadはGigE visionのペイロードタイプに従ってバッファの中身がなにかを表す。
- 画像データ
- rawデータ
- ファイル
- chunkデータ
- JPEG
- JPEG2000
- H264
- multi zone画像データ
- その他
ArvBufferPayloadType arv_buffer_get_payload_type (ArvBuffer *buffer);を使って調べる必要がある。返される値は同じようにenumに定義されている。
この二つを調べてデータが正常で、かつ要求に従ったペイロードなら処理を継続する、ということになる。
さらに、ArvBufferの中身が一番一般的な画像データの場合は
ArvPixelFormat arv_buffer_get_image_pixel_format (ArvBuffer *buffer);でフォーマットを調べることができる。ArvPixelFormatはenumで定義されていて、中身は古いIIDCのPixelFormatと同じになっている(PixelFormatは32ビット符号なし整数で、直交性の悪いビットフィールドになっていて非常に汚くわかりにくいので、なんでGen<i>Cam規格がいつまでもこれを使うのか理解できない)。
画像データ本体は
const void *arv_buffer_get_data (ArvBuffer *buffer, size_t *size);で先頭へのポインタが返される。sizeには全体のサイズが設定される。自信があるならsizeポインタ引数にNULLを渡してもいいとなっている。
これ以外に画像の縦横のサイズや部分転送の場合の領域などを調べることができる。
2019-06-16 21:03
nice!(0)
コメント(0)
コメント 0