コンテンツにスキップ

siso_genicam#

ライブラリ siso_genicam は、GenICam標準に準拠したカメラの検出、カメラパラメータへのアクセス、およびカメラコマンドの実行を管理します。パラメータとコマンドは、このマニュアル全体を通じてフィーチャーと呼ばれます。

ライブラリを使用するには、インクルードファイル siso_genicam.h をソースコードに追加する必要があります。

#include <siso_genicam.h>

さらに、 siso_genicam.lib をMicrosoft Visual Studioプロジェクトに追加するか、 libsiso_genicam.so Linuxプロジェクトに追加します。CMakeを使用している場合、パッケージ名は SisoGenicam で、ライブラリは次の変数に格納されます: ${SisoGenicam_LIBRARIES}。プロジェクトの詳細およびCMakeの使用方法については、 前提条件 を参照してください。

このライブラリは、常にフレームグラバーライブラリfglib5と組み合わせて使用されます。プロジェクトへのライブラリfglib5の追加方法の詳細については、The Frame Grabber Library fglib5を参照してください。

Camera Control Libraryにおけるエラーハンドリング#

const char * Sgc_getErrorDescription(
    int result);

API のほとんどの関数は int 結果コードを返します。関数呼び出しが正常に実行された場合、戻り値は SGC_OK または、一部の機能ではゼロ以上の値になります。ほとんどの場合、負の値はエラー状態を示します。Error Codes は次のヘッダーファイルで定義されています。 siso_genicam_error.h。これは次のファイルに自動的にインクルードされます: siso_genicam.h.

関数 Sgc_getErrorDescription() を使用すると、特定の結果コードの文字列表現を取得できます。

このマニュアルの残りの部分にあるコード例には、アプリケーションの要件に固有のものであるためエラー処理は含まれていません。ただし、関数の正常終了を確認するため、可能な限りリターンコードがチェックされます。

Camera Control Libraryの初期化#

int Sgc_initBoard(
    Fg_Struct * fg,
    unsigned int flags,
    SgcBoardHandle ** board);

void Sgc_freeBoard(
    SgcBoardHandle * board);

siso_genicamライブラリを使用した作業を開始するには、まず記載されているようにフレームグラバーを初期化する必要があります。 The Frame Grabber Library fglib5。次に、関数 Sgc_initBoard() を、アプリケーションで使用するすべてのフレームグラバーに対して呼び出す必要があります。パラメーター flags は将来の拡張用に予約されており、アプリケーションは常に 0 を渡す必要があります。初期化が成功した場合、ボードハンドルは次のパラメーターで渡された変数に格納されます: board.

アプリケーションで siso_genicam ライブラリの使用が終了したら、正常に取得したすべてのボードハンドルを次を呼び出して解放する必要があります: Sgc_freeBoard() (それぞれに対して)。

次の例は、ライブラリの使用を開始するためのボードハンドルを取得する方法を示しています:

SgcBoardHandle * board = nullptr;
int result = Sgc_initBoard(fg, 0, &board);
if (result != SGC_OK) {
    // handle error ...
}

// use board, start discovery ...

Sgc_freeBoard(board);

カメラの検出#

int Sgc_scanPorts(
    SgcBoardHandle * board,
    unsigned int portMask,
    int timeout,
    int speed);

int Sgc_getCameraCount(
    SgcBoardHandle * board);

int Sgc_getCameraByIndex(
    SgcBoardHandle * board,
    unsigned int index,
    SgcCameraHandle ** camera);

int Sgc_getCamera(
    SgcBoardHandle * board,
    unsigned int port,
    SgcCameraHandle ** camera);

情報

Framegrabber API バージョン 5.9 では、関数 Sgc_scanPorts() の動作と、関数 Sgc_getCameraCount() の戻り値の両方が変更されました。

アプリケーションでカメラを使用する前に、カメラを検出する必要があります。検出手順では、フレームグラバーの物理ポートで接続のスキャンを行います。複数のポートで接続が検出された場合、次のステップでは、接続されているカメラの数と、各カメラが使用している物理接続の数を調べます。物理接続および使用されている伝送速度などのプロパティは、リンクと呼ばれます。カメラは1つ以上のリンク構成をサポートしています。たとえば、CoaXPress カメラはさまざまなリンク構成をサポートしている場合があります。4つの物理ポートを持つカメラの場合、CoaXPress 2.0 のリンク速度(3.125、5、6.25、10、12.5 Gbit/s)のサブセットを使用して、1つ、2つ、または4つのリンクを持つ構成をサポートしている場合があります。したがって、このカメラは合計15種類の異なるリンク構成をサポートすることになります。

カメラ検出手順を開始するには、関数 Sgc_scanPorts() を呼び出す必要があります。この関数には、以前の呼び出しからのボードハンドル Sgc_initBoard() パラメータ内で board、検出を実行する物理ポートを指定するビットマスク(パラメーター portMask 内)、および少なくとも1台のカメラが検出されるまで待機する時間(ミリ秒単位、パラメーター timeoutを呼び出すことで、イベントソースのグループからのイベントを同期的に待機できます。 speed 内)が必要です。ほとんどの場合 LINK_SPEED_NONE にする必要があります。オプションで、カメラが検出されると予想されるリンク速度のヒントを検出処理に与えるために使用できます。

1つまたは複数のフレームグラバーに対して単一のプロセスを使用するアプリケーションでは、ポートマスクは常に 0xf。このようにして、フレームグラバーのすべてのポートでカメラがスキャンされます。アプリケーションがフレームグラバーに対して複数のプロセスを使用する場合は、次の章をお読みください。 複数プロセスからのカメラ検出のサポート.

カメラが検出された後、使用されるアプレットとカメラのデフォルト設定に従って、最終的なリンク構成がネゴシエーションされます。検出されたカメラがアプリケーションにどのような状態で提示されるかを理解するには、このプロセスの制限を知ることが役立ちます。検出アルゴリズムは、カメラによって提供される GenICam XML を使用しません。代わりに、カメラのデフォルト設定によって、カメラの検出手順で使用できる最大リンク速度とリンク数が決まります。一部のカメラでは、デフォルト設定がカメラが使用できる最高リンク速度や最大リンク数とは限りません!一方、アプレットのレイアウトは、カメラの最大数と、アプレットの検出手順で使用できる各カメラの最大リンク数を決定します。検出アルゴリズムは、一方で見つかったカメラと、他方のアプレットのレイアウトを最適に一致させようとします。使用する予定のカメラのセットアップと機能に最も適したアプレットを見つけるには、アプレットのドキュメントおよびカメラのドキュメントを参照してください。

(また、アプレットのレイアウトを示す図については、章Understanding Image Data Flowも参照してください。フレームグラバーに接続された各カメラに対し、アプレットには対応するカメラオペレーターが必要です。カメラオペレーターの数は、各アプレットの固定Propertyです。フレームグラバーに接続されたカメラに適したアプレットを選択する方法を理解するために、パートThe Frame Grabber Library fglib5の章Frame Grabber Initializationの最後にあるコメントを確認することをお勧めします。)

の呼び出しが Sgc_scanPorts() は SGC_OKであった場合、指定された時間内に少なくとも1台のカメラが見つかり、アプレットとカメラを一致させることができました。戻り値が ERR_SGC_TOPOLOGY_MISMATCHである場合、少なくとも1台のカメラが見つかりましたが、アプレットとカメラを一致させることができず、カメラとの通信は可能な状態である一方で、カメラからアプレットへ画像データを正常に転送することができません。

が正常に呼び出された後、 Sgc_scanPorts()、関数 Sgc_getCameraCount() を呼び出して見つかったカメラの数を取得し、どちらかを使用して Sgc_getCameraByIndex() または Sgc_getCamera() からカメラハンドルを取得できます。どちらの関数も同様の動作をし、3つのパラメータを受け取ります。最初のパラメータはボードハンドルです。 Sgc_getCameraByIndex()の場合、2番目のパラメータは0から Sgc_getCameraCount() によって報告されたカメラの数から1を引いた数までの間の番号でカメラを識別します。そのため、この関数を使用すると検出されたすべてのカメラを簡単に反復処理できますが、カメラが検出される順序、したがってインデックスは、 Sgc_scanPorts()。ハードウェアでは、符号付きの場合 Sgc_getCamera()の2回の呼び出し間で変更される可能性があります。 Sgc_getCameraByIndex()の場合、2番目のパラメータはカメラが接続されている物理ポートによってカメラを識別します。物理ポートには、0から使用されているフレームグラバーの物理ポート数から1を引いた数まで番号が付けられています。常に同じ物理配線が使用される場合、この関数を使用すると、

で前述した曖昧さを回避できます。3番目のパラメータは、カメラハンドルを格納する変数へのポインタです。

const unsigned int portMask = 0xf;
const int timeoutInMs = 10000;

int result = Sgc_scanPorts(board, portMask, timeoutInMs, LINK_SPEED_NONE);
if (result != SGC_OK) {
    // handle error ...
}

SgcCameraHandle * camera = nullptr;
result = Sgc_getCameraByIndex(board, index, &camera);
if (result == SGC_OK) {
        // use camera ...
}

次の例は、最大10秒間カメラを検索し、対応するカメラハンドルを取得する方法を示しています。

1台を超えるカメラを処理するアプリケーションの場合、検出を処理する推奨方法は、章で説明されているようにコールバック関数を登録することです。 検出イベント用のコールバック関数の登録、そして呼び出し Sgc_scanPorts() 複数のカメラを使用するアプリケーションの場合、検出を処理する推奨される方法は、「Registering a Callback Function for Discovery Events」の章で説明されているようにコールバック関数を登録し、

をタイムアウト0で呼び出して検出プロセスを開始することです。コールバックハンドラー内から、アプリケーションはたとえば、新しいカメラが検出されたときに個別の集録スレッドを開始できます。 Sgc_scanPorts() あるいは、アプリケーションは期待されるすべてのカメラが見つかるまで

const unsigned int portMask = 0xf;
const int timeoutInSeconds = 10;
const int numberOfCamerasExpected = 4;

int result = SGC_OK;
int numberOfCamerasFound = 0;
auto start = std::chrono::steady_clock::now();
do {
    result = Sgc_scanPorts(board, portMask, 1000, LINK_SPEED_NONE);
    if (result == SGC_OK) {
        numberOfCamerasFound = Sgc_getCameraCount(board);
    }
} while ((numberOfCamerasFound < numberOfCamerasExpected) && (std::chrono::steady_clock::now() - start < std::chrono::seconds(timeoutInSeconds)));
if (numberOfCamerasFound < numberOfCamerasExpected) {
    // handle error ...
}

// use cameras ...

カメラ検出の再起動#

int Sgc_scanPortsEx(
    SgcBoardHandle * board,
    unsigned int portMask,
    int timeout,
    int speed,
    unsigned int flags);

情報

を繰り返し呼び出すこともできます。次の例では、処理を続行する前に4台のカメラが検出されるのを待機します。 Sgc_scanPortsEx() Framegrabber APIのバージョン5.9で変更されました。

関数 Sgc_scanPorts() および Sgc_scanPortsEx() 関数 flags のデフォルトの動作では、パラメータに0を渡して呼び出された場合、 Sgc_scanPortsEx() を使用して呼び出すことができます SGC_SP_FLAG_RESET_DISCOVERY_INFOS パラメータ内で flags.

カメラPropertyの操作#

カメラが検出されると、アプリケーションはカメラPropertyの使用を開始できます。これらのProperty、カメラのパラメータ、およびコマンドは、標準化されたPropertyインターフェースを介してカメラからダウンロード用に提供できるXMLドキュメント、またはカメラメーカーがその他の方法(たとえば、XMLドキュメントをダウンロードできるウェブサイトを提供しているカメラメーカーもあるなど)で提供するXMLドキュメント内で定義されています。XMLドキュメントの構造は、GenICam標準で定義されています。GenICamの詳細については、European Machine Vision AssociationのGenICamウェブサイトをご覧ください。カメラが提供するPropertyの詳細については、カメラのマニュアルを参照してください。

のGenICam この規格では、GenApi を介してカメラ機能を制御する方法も定義されています。 GenICamリファレンス実装の使用」の章では、siso_genicam ライブラリと GenApi の接続について説明します。

GenICam規格では、GenApiを介してカメラ機能を制御する方法も定義されています。「Using the GenICam Reference Implementation」の章では、siso_genicamライブラリとGenApiの接続について説明します。

カメラ接続#

int Sgc_connectCamera(
    SgcCameraHandle * camera);

int Sgc_connectCameraWithExternalXml(
    SgcCameraHandle * cameraHandle,
    const char * file);

int Sgc_disconnectCamera(
    SgcCameraHandle * camera);

この章では、GenApiをラップして使いやすくし、Framegrabber APIから直接カメラ機能を使用できるようにする一連の関数について説明します。説明されているAPIは、機能が既知である場合にカメラパラメータの取得と設定、およびコマンドの実行に使用できますが、XMLの高度な機能はサポートされておらず、アプリケーション側でGenApiを使用する必要があります。 Sgc_connectCamera() 検出手順において、検出されたカメラへの物理的接続が確立されました。カメラ機能を使用するには、論理的接続を確立する必要があります。この論理的接続は、GenICam XMLを読み取り、Framegrabber SDKによって内部で使用されるGenApi環境を準備することによって確立されます。カメラによって提供されるXMLを使用して論理的接続を確立するには、関数 Sgc_connectCameraWithExternalXml() を呼び出す必要があります。メーカーのWebサイトからダウンロードしたXMLファイル、またはその他の手段で取得したXMLファイルを使用する場合は、関数 camera。関数 Sgc_connectCameraWithExternalXml() パラメータでXMLファイルのパスを指定する必要があります file さらに。

アプリケーションがカメラ機能の使用を終了したら、次を呼び出して論理接続を閉じることができます Sgc_disconnectCamera().

カメラPropertyの取得と設定#

int Sgc_getIntegerValue(
    SgcCameraHandle * camera,
    const char * feature,
    int64_t * value);

int Sgc_getBooleanValue(
    SgcCameraHandle * camera,
    const char * feature,
    unsigned int * value);

int Sgc_getFloatValue(
    SgcCameraHandle * camera,
    const char * feature,
    double * value);

int Sgc_getStringValue(
    SgcCameraHandle * camera,
    const char * feature,
    const char ** value);

int Sgc_getEnumerationValue(
    SgcCameraHandle * camera,
    const char * feature,
    int64_t * value);

int Sgc_getEnumerationValueAsString(
    SgcCameraHandle * camera,
    const char * feature,
    const char ** value);

int Sgc_clearStringCache(
    SgcCameraHandle * camera);
int Sgc_setIntegerValue(
    SgcCameraHandle * camera,
    const char * feature,
    int64_t value);

int Sgc_setBooleanValue(
    SgcCameraHandle * camera,
    const char * feature,
    unsigned int value);

int Sgc_setFloatValue(
    SgcCameraHandle * camera,
    const char * feature,
    double value);

int Sgc_setStringValue(
    SgcCameraHandle * camera,
    const char * feature,
    const char * value);

int Sgc_setEnumerationValue(
    SgcCameraHandle * camera,
    const char * feature,
    const char * value);

数値表現を持つカメラパラメータの値を取得するには、次の関数を使用できます Sgc_getIntegerValue(), Sgc_getBooleanValue(), Sgc_getFloatValue() および Sgc_getEnumerationValue() 。これらの関数には、パラメータでのカメラハンドルが必要です camera、パラメータでの機能名 feature および値が格納される対応する型の変数へのポインタをパラメータに指定します value.

文字列表現を持つカメラパラメータの値を取得するための関数 Sgc_getStringValue() および Sgc_getEnumerationValueAsString()には、次の型の変数へのポインタが必要です char * パラメータ内で value。この変数には、文字列値へのポインタが格納されます。

文字列値は割り当てられ、内部キャッシュに格納されます。キャッシュは、アプリケーションが文字列値を要求するたびに大きくなり、キャッシュから単一の文字列値を直接解放する方法はありません。ただし、次を呼び出すことでキャッシュをクリアできます Sgc_clearStringCache()これにより、以前に割り当てられたすべての文字列値が解放され、無効化されます。

値を設定するには、次の関数を呼び出すことができます Sgc_setIntegerValue(), Sgc_setBooleanValue(), Sgc_setFloatValue(), Sgc_setStringValue() および Sgc_setEnumerationValue() 。これらの関数には、パラメータでのカメラハンドルが必要です camera、パラメータでの機能名 feature およびパラメータでの値 value.

次の例は、カメラをカメラXMLに接続し、転送する画像の幅と高さを設定する方法を示しています。

int result = Sgc_connectCamera(camera);
if (result == SGC_OK) {
    result = Sgc_setIntegerValue(camera, "Width", 1920);
}
if (result == SGC_OK) {
    result = Sgc_setIntegerValue(camera, "Height", 1080);
}

カメラコマンドの実行#

int Sgc_executeCommand(
    SgcCameraHandle * camera,
    const char* feature);

int Sgc_isCommandDone(
    SgcCameraHandle * camera,
    const char* feature,
    unsigned int * value);
int Sgc_startAcquisition(
    SgcCameraHandle * camera,
    unsigned int start);

int Sgc_stopAcquisition(
    SgcCameraHandle * camera,
    unsigned int stop);

コマンドを実行するには、次の関数を呼び出すことができます Sgc_executeCommand() 。この関数には、パラメータでのカメラハンドルが必要です camera およびパラメータでの機能名 feature。関数 Sgc_isCommandDone() を使用して、コマンドの実行が完了したかどうかを確認できます。パラメータでのカメラハンドルが必要です camera、パラメータでの機能名 feature および次の型の変数へのポインタ unsigned int パラメータ内で value。コマンドの実行が完了している場合は変数に値1が格納され、コマンドがまだ実行中の場合は値0が格納されます。

関数 Sgc_startAcquisition() および Sgc_stopAcquisition() は、標準機能のショートカットです AcquisitionStart および AcquisitionStop。この関数は、パラメータの場合にのみ実行されます start または stop の評価結果が true:

int Sgc_startAcquisition(SgcCameraHandle * camera, unsigned int start)
{
    int result = SGC_OK;
    if (start) {
        result = Sgc_executeCommand(camera, "AcquisitionStart");
    }
    return result;
}

カメラ情報#

int Sgc_getCameraPropertyWithType(
    SgcCameraHandle * camera,
    const char * property,
    void * value,
    unsigned int * type,
    void * additionalValue);

int Sgc_updateCameraInfos(
    SgcCameraHandle * camera);

情報

Framegrabber APIのバージョン5.9では、次の関数から取得できる情報が拡張されました。 Sgc_getCameraPropertyWithType() また、次の関数が追加されました。 Sgc_updateCameraInfos()

検出手順でカメラへの物理的接続が確立された後、カメラと接続に関するさまざまな情報を取得して要求できるようになります。

関数 Sgc_getCameraPropertyWithType() を呼び出してカメラ接続に関する情報を要求できます。この関数には、パラメータ内のカメラハンドルが必要です。 camera、パラメータ内の接続Property property、値が格納される変数へのポインタ、および次の型の変数へのポインタが必要です。 unsigned int (これはPropertyの型を反映するように初期化する必要があります)。パラメータ additionalValue は、以下に文書化されているように、一部のPropertyに必要です。

Property 説明 タイプ
CAM_PROP_MASTERID カメラのマスターIDa uint32_t
CAM_PROP_NROFLINKS 画像転送に使用される物理リンクの数 uint32_t
CAM_PROP_LINKSPEED 現在のリンク速度(Mbit/s単位) uint32_t
CAM_PROP_DISCOVERYSPEED カメラが検出されたときのリンク速度(Mbit/s単位) uint32_t
CAM_PROP_FGPORT リンクが接続されている物理ポート(additionalValue:リンクインデックス) uint32_t
CAM_PROP_MASTERPORT マスターリンクが接続されている物理ポート(リンク0の場合はFGPORTと同じ) uint32_t
CAM_PROP_APPLETMASTERID アプレットカメラポートのマスターIDa uint32_t
CAM_PROP_APPLETOPERATORINDEX アプレットカメラオペレーターのインデックス uint32_t
CAM_PROP_APPLETOPERATORSIZE アプレットカメラオペレーターのリンク数 uint32_t
CAM_PROP_APPLETPORT リンクが接続されている論理ポート(additionalValue:リンクインデックス) uint32_t
CAM_PROP_CONTROLPACKETSIZE コントロールパケットの最大サイズ uint32_t
CAM_PROP_STREAMPACKETSIZE ストリームパケットの最大サイズ uint32_t
CAM_PROP_ISCONNECTED 0: 物理的な接続はありません
1: 物理的な接続が確立されました
uint32_t
CAM_PROP_ISGENICAMCONNECTED 0: 論理的な接続はありません
1: 論理的な接続が確立されました
uint32_t
CAM_PROP_ISTRANSCEIVERLOCKED 0: 伝送エラーが多すぎます
1: 伝送が安定しています
uint32_t
CAM_PROP_XML_DATA ゼロ終端文字列形式のカメラのXMLデータ(additionalValue:バッファサイズ) char *
CAM_PROP_VENDOR_NAME ゼロ終端文字列形式のカメラベンダー名(additionalValue:バッファサイズ) char *
CAM_PROP_MODEL_NAME ゼロ終端文字列形式のカメラモデル名(additionalValue:バッファサイズ) char *
CAM_PROP_FAMILY_NAME ゼロ終端文字列形式のカメラファミリー名(additionalValue:バッファサイズ) char *
CAM_PROP_VERSION ゼロ終端文字列形式のカメラバージョン(additionalValue:バッファサイズ) char *
CAM_PROP_FIRMWARE_VERSION ゼロ終端文字列形式のカメラファームウェアバージョン(additionalValue:バッファサイズ) char *
CAM_PROP_MANUFACTURER_INFO ゼロ終端文字列形式のカメラメーカー情報(additionalValue:バッファサイズ) char *
CAM_PROP_SERIAL_NUMBER ゼロ終端文字列形式のカメラシリアルナンバー(additionalValue:バッファサイズ) char *
CAM_PROP_USER_ID ゼロ終端文字列形式のカメラユーザーID(additionalValue:バッファサイズ) char *

上記のリストは網羅的なものではなく、アプリケーションに役立つ情報のプロパティのみが含まれています。API のその他のユースケースについては、Framegrabber API リファレンスを参照してください。

Propertyでパラメータが使用される場合、 additionalValue リンクインデックスの場合、次の場合のデフォルトのリンクインデックスは0になります nullptr が次に渡される場合: additionalValue 呼び出し時。リンクインデックス0は、カメラのマスターリンクです。

対応する型の値を要求するには、次の値を使用する必要があります。

Property Type C/C++ Type
SGC_PROPERTY_TYPE_UINT uint32_t
SGC_PROPERTY_TYPE_DOUBLE double
SGC_PROPERTY_TYPE_STRING char *

次の例は、カメラの接続速度とリンク数を取得する方法を示しています。

unsigned int numberOfLinks = 0;
unsigned int linkSpeed = 0;
int type = SGC_PROPERTY_TYPE_UINT;
int result =
    Sgc_getCameraPropertyWithType(camera, CAM_PROP_NROFLINKS,
                                  &linkSpeed, &type, nullptr);
if (result == SGC_OK) {
    result =
        Sgc_getCameraPropertyWithType(camera, CAM_PROP_LINKSPEED,
                                      &numberOfLinks, &type, nullptr);
}
if (result == SGC_OK) {
    std::cout << "Link configuration: " << numberOfLinks
              << " x " << (1e-3 * linkSpeed)
              << " Gbit/s" << std::endl;
}

型のPropertyを要求するには、 SGC_PROPERTY_TYPE_STRING、2回の呼び出し Sgc_getCameraPropertyWithType() が必要です。パラメータにnullptrを渡すことで、 value および次の型の変数へのポインタ unsigned int を渡したときのデフォルトの動作は、 additionalValue、終端を含む文字列に必要なバッファサイズ \0 文字を要求でき、変数に格納されます。2回目の呼び出しでは、割り当てられたバッファへのポインタがパラメータで渡されます。 value パラメータ内のサイズの変数へのポインタとともに additionalValue。必要以上に多くのスペースを使用してバッファが割り当てられた場合、戻り時にバッファサイズの変数には、終端を含むデータの長さが含まれます。 \0 文字。

次の例は、次を使用してデバイスモデル名を要求する方法を示しています。 Sgc_getCameraPropertyWithType(): (この例ではC++ヘッダーファイルが必要です。 memory の std::unique_ptr タイプ。)

// get size of model name
unsigned int size = 0;
unsigned int propertyType = SGC_PROPERTY_TYPE_STRING;
result =
    Sgc_getCameraPropertyWithType(camera, CAM_PROP_MODEL_NAME,
                                  nullptr, &propertyType, &size);
if (result == SGC_OK && size > 0) {
    // create buffer and request camera model name
    std::unique_ptr<char[]> modelName(new char[size]);
    result =
        Sgc_getCameraPropertyWithType(camera, CAM_PROP_MODEL_NAME,
                                      modelName.get(), &propertyType, &size);
    if (result == SGC_OK) {
        std::cout << "Camera model name: " << modelName.get() << std::endl;
    }
}

アプリケーションがカメラの機能を使用し、それによって以下の利用可能な情報に変更が生じる場合: Sgc_getCameraPropertyWithType()(たとえば、ユーザーID文字列の設定やカメラのファームウェアバージョンの更新など)、関数 Sgc_updateCameraInfos() を呼び出してFramegrabber API内のデータの更新を要求する必要があります。

画像データの流れの理解#

カメラからの画像データが、フレームグラバー内のアプレットを経由してアプリケーションのメモリに流れる仕組みを理解するために、まず、2台のカメラがアプレット内の対応するカメラオペレーターにストレートに接続されているシンプルなセットアップを見てみましょう:

Data Flow Straight

この例のアプレットとしては、例えば Acq_DualCXP12Areaまたはそれに類するアプレットが挙げられます。カメラインデックス0、マスターID 1のカメラからの画像データは、フレームグラバーの物理ポート0および1を経由して、オペレーターインデックス0、マスターID 1のカメラオペレーターに送られ、そこでアプレット固有の画像パイプラインで処理された後、インデックス0のDMAオペレーターを介してアプリケーションのメモリに送信されます(マスターIDはカメラまたはオペレーターが接続されているポートに基づいているため、2台目のカメラとオペレーターのマスターIDは2ではなく3になり、インデックスは1になります)。

アプリケーションの観点から見ると、重要な情報は、どのDMAチャネルでカメラの画像データを期待すべきかという点です。例のアプレットレイアウトの場合、正しいDMAチャネルを把握するために必要なカメラのプロパティは CAM_PROP_APPLETOPERATORINDEXのみです。Framegrabber SDKのインストールに含まれるすべてのアプレットは、この原則に従って設計されています。VisualAppletsで設計されたアプレットについても、同様のアプローチを採用し、レイアウトを文書化することを強くお勧めします。

次に、カメラがクロスケーブルで接続されている、より複雑な例を見てみましょう:

Data Flow Crossed

画像転送が正常に機能するためには、検出手順によってフレームグラバーの物理ポートが、上図のようにカメラオペレーターの論理ポートに接続されている必要があります(図を見ると、マスターID 2のカメラがマスターID 0のカメラオペレーターに接続されているという2つ目の可能性もあります。これは、検出手順を最初に実行したときにカメラが1台のみ接続されており、2台目のカメラが後から追加された場合などに発生する可能性があります)。

それでも、正しいDMAチャネルを把握するには、同じカメラプロパティである CAM_PROP_APPLETOPERATORINDEXだけで十分です。

検出イベント用のコールバック関数の登録#

struct SgcEventInfo {
  uint16_t eventID;
  union SgcEventData data;
}

typedef int (* Sgc_BoardEventCallbackFunc_t)(
    SgcBoardHandle * board,
    const struct SgcEventInfo * info,
    void * data);

int Sgc_registerBoardEventCallback(
    SgcBoardHandle * board,
    Sgc_BoardEventCallbackFunc_t func,
    void * data);
int Sgc_scanPortsEx(
    SgcBoardHandle * board,
    unsigned int portMask,
    int timeout,
    int speed,
    unsigned int flags);

情報

関数 Sgc_registerBoardEventCallback() は、Framegrabber APIのバージョン5.9で追加されました。

を使用して、 Sgc_registerBoardEventCallback()型の関数 SgcEventCallback_t を登録すると、ライブラリによってイベントが生成されたときにコールバックされるようにすることができます。この関数は指定されたボードハンドルに対して登録され、呼び出し時に3つのパラメータが渡されます。コールバック関数の最初のパラメータはボードハンドルです。2番目のパラメータは struct SgcEventInfo へのポインタであり、イベントに関する情報を格納するために使用されます。最後のパラメータは、 Sgc_registerBoardEventCallback() の呼び出し時に指定されたポインタであり、コンテキスト構造体やクラスへのポインタ(例えば、画像処理を実装するクラスインスタンスの this ポインタなど)として使用できます。

の呼び出し時に指定されたポインタです。

ボードハンドルごとに登録できるコールバック関数は1つだけです。 Sgc_scanPorts() または Sgc_scanPortsEx() 関数が呼び出された場合にのみ、カメラに関する検出情報が更新されます。 Sgc_scanPortsEx() 情報を更新するためだけに、コールバック関数から SGC_SP_FLAG_UPDATE_DISCOVERY_INFOS_ONLY パラメータ内で flags.

コールバック関数が不要になった後は、以下を呼び出すことで登録を解除できます。 Sgc_registerBoardEventCallback()を呼び出すことができます。その際、 nullptr パラメータへ func および data.

イメージ struct SgcEventInfo インスタンスには、メンバー内にイベントの識別子が含まれています eventID および、unionメンバー内の追加データ data。ライブラリによって生成されるイベントには、次のイベント識別子が使用されます。

Event 説明
SGC_EVENT_DISCOVERY_STATE_CAMERA_ADDED 新しいカメラが検出されました
SGC_EVENT_DISCOVERY_STATE_CAMERA_LOST カメラとの接続が切れました
SGC_EVENT_DISCOVERY_STATE_CAMERA_PROPERTY_CHANGE カメラ接続のPropertyが変更されました

次の例は、アプリケーションにとって有用な情報を保持できるシンプルな構造体を使用して、コールバック関数を登録する方法を示しています。

struct DiscoveryUserCallbackData
{
    // ...
};

int DiscoveryUserCallback(SgcBoardHandle * board,
                          const struct SgcEventInfo * info, void * data)
{
    auto context = reinterpret_cast<DiscoveryUserCallbackData *>(data);

    // update discovery infos
    Sgc_scanPortsEx(board, 0xf, 0, LINK_SPEED_NONE,
                    SGC_SP_FLAG_UPDATE_DISCOVERY_INFOS_ONLY);

    // process event ...

    return 0;
}

void SetupDiscoveryUserCallback(SgcBoardHandle * board,
                                DiscoveryUserCallbackData * context)
{
    // register callback function
    int result =
        Sgc_registerBoardEventCallback(board, &DiscoveryUserCallback, context);
    if (result != SGC_OK) {
        throw std::runtime_error("Failed to register callback function");
    }
}

コンテキスト構造体の割り当てと管理はこの例には示されていません。ポインタは、コールバック関数が登録されている間、有効である必要があります。解決策の1つは、すべてをC++クラス内にまとめておくことです。C++クラスのコンテキストでコールバック関数を使用するには、静的関数を使用してコールバックハンドラを登録し、 this pointerは、クラスポインタにキャストしてそれに応じて使用できるコンテキストデータポインタとして使用する必要があります。

検出状態変更情報#

struct SgcEventData_DiscoveryStateChanged {
    uint32_t id;
    uint32_t properties_int_count;
    char ** properties_int_key;
    uint32_t * properties_int_value;
    uint32_t properties_string_count;
    char ** properties_string_key;
    char ** properties_string_value;
};

情報

検出状態変更イベントは、Framegrabber APIのバージョン5.9で追加されました。

ボードイベントの場合、 struct SgcEventData_DiscoveryStateChanged は、イベントで影響を受けたカメラ接続に関する情報を提供するために使用されます。この構造体には、次のメンバーにカメラマスターIDが含まれています。 id および2つのキーと値のマップ(整数値用と文字列用が1つずつ)が含まれます。キーは、次の項目を通じて利用可能なPropertyと同じです。 Sgc_getCameraPropertyWithType()ただし、イベントやカメラインターフェイス技術によっては、すべてのPropertyがイベント情報に含まれるとは限りません。アプリケーションは、イベントが生成された変更に関連するPropertyがマップ内に存在することを期待できます。これを超えて、アプリケーションはPropertyの存在やマップ内のPropertyの順序について仮定するべきではありません。

構造体内のすべてのデータは、イベントコールバック関数内でのみ有効です。情報を保持する必要がある場合は、関連する部分をコピーする必要があります。

次の例は、 SGC_EVENT_DISCOVERY_STATE_CAMERA_PROPERTY_CHANGE イベントからリンク速度とリンク数を抽出する方法を示しています。

int DiscoveryUserCallback(SgcBoardHandle * board,
                          const struct SgcEventInfo * info, void * data)
{
    auto context = reinterpret_cast<DiscoveryUserCallbackData *>(data);

    // update discovery infos
    Sgc_scanPortsEx(board, 0xf, 0, LINK_SPEED_NONE,
                    SGC_SP_FLAG_UPDATE_DISCOVERY_INFOS_ONLY);

    // process event ...
    if (info->eventID == SGC_EVENT_DISCOVERY_STATE_CAMERA_PROPERTY_CHANGE) {
        int newNumOfLinks = 0;
        int newLinkSpeed = LINK_SPEED_NONE;
        for (int i = 0; i < info->data.discovery_state.properties_int_count; ++i) {
            if (strcmp(info->data.discovery_state.properties_int_keys[i],
                       CAM_PROP_NROFLINKS) == 0) {
                newNumOfLinks = info->data.discovery_state.properties_int_values[i];
            }
            if (strcmp(info->data.discovery_state.properties_int_keys[i],
                       CAM_PROP_LINKSPEED) == 0) {
                newLinkSpeed = info->data.discovery_state.properties_int_values[i];
            }
        }

        // ...
    }

    return 0;
}

GenICamリファレンス実装の使用#

GenICamリファレンス実装の使用は、章に記載されているFramegrabber APIによって提供されるGenApiラッパーを使用する代わりの方法です カメラPropertyの操作。アプリケーションでGenICamリファレンス実装を使用する場合、関数は Sgc_connectCamera() または Sgc_connectCameraWithExternalXml() を呼び出してはなりません。代わりに、アプリケーションはGenApiヘッダーファイル GenICam.hをインクルードし、GenICamライブラリ GCBase および GenApi に対してリンクし、対応するGenApiコンテキストを初期化する必要があります。

#include <GenICam.h>

Framegrabber SDKのインストールに含まれているGenICamリファレンス実装を使用するには、次の手順を実行する必要があります。

  • アプリケーションがWindows上の64ビットFramegrabber SDKを使用する場合:
  • システム環境変数に追加します %BASLER_FG_SDK_DIR%\bin プロジェクトのインクルードディレクトリに追加します PATH
  • システム環境変数に追加します %BASLER_FG_SDK_DIR%\include プロジェクトのライブラリディレクトリに追加します
  • システム環境変数に追加します %BASLER_FG_SDK_DIR%\library\visualc ライブラリを追加します
  • プロジェクトのリンクライブラリに追加します GCBase_MD_VC141_v3_1_Basler_pylon_v3.lib および GenApi_MD_VC141_v3_1_Basler_pylon_v3.lib アプリケーションがLinux上の64ビットFramegrabber SDKを使用する場合:
  • 環境変数に追加します
  • システム環境変数に追加します $BASLER_FG_SDK_DIR\lib64 プロジェクトのインクルードディレクトリに追加します LD_LIBRARY_PATH およびプロジェクトライブラリディレクトリ
  • システム環境変数に追加します $BASLER_FG_SDK_DIR\include プロジェクトのライブラリディレクトリに追加します
  • プロジェクトのリンクライブラリに追加します libGCBase_gcc_v3_1_Basler_pylon_v3.so および libGenApi_gcc_v3_1_Basler_pylon_v3.so アプリケーションがLinux上の64ビットFramegrabber SDKを使用する場合:
  • システム環境変数に追加します #define GENICAM_NO_AUTO_IMPLIB 以下の前で #include <GenICam.h>

CMakeを使用してプロジェクトファイルを生成する場合、パッケージ SisoGenicam はFramegrabber SDKのインストールに含まれているGenICamライブラリも検索し、それらを次の変数に追加します。 ${SisoGenicam_LIBRARIES}。GenICamのインクルードパスは次の変数に格納されます。 ${GENICAM_INCLUDE_DIR} 。これは以下に追加する必要があります。 INCLUDE_DIRECTORIES.

IPortラッパーの作成#

int Sgc_memoryReadFromCamera(
    SgcCameraHandle * camera,
    void * buffer,
    uint64_t address,
    size_t length);

int Sgc_memoryWriteToCamera(
    SgcCameraHandle * camera,
    const void * buffer,
    uint64_t address,
    size_t length);

GenICamリファレンス実装を使用するには、 GENAPI_NAMESPACE::IPort ラッパーが必要です。これにより、Framegrabber APIとGenApiの間でのカメラレジスタへのアクセスが変換されます。次の関数 Sgc_memoryReadFromCamera() および Sgc_memoryWriteToCamera() を使用すると、シンプルで分かりやすいラッパー クラスを作成できます:

class DevicePort: virtual public GENAPI_NAMESPACE::IPort
{
    SgcCameraHandle * camera;

public:
    DevicePort(SgcCameraHandle * camera)
        : camera(camera)
    {}

    GENAPI_NAMESPACE::EAccessMode GetAccessMode() const override
    {
        return GENAPI_NAMESPACE::RW;
    }

    void Read(void * buffer, int64_t address, int64_t length) override
    {
        int result = Sgc_memoryReadFromCamera(camera, buffer, address, length);
        if (result != SGC_OK) {
            // handle error ...
        }
    }

    void Write(const void * buffer, int64_t address, int64_t length) override
    {
        int result = Sgc_memoryWriteToCamera(camera, buffer, address, length);
        if (result != SGC_OK) {
            // handle error ...
        }
    }
};

ノードマップの初期化と接続#

int Sgc_loadCameraXml(
    SgcCameraHandle * camera);

GenICamリファレンス実装をFramegrabber APIに接続するための最終ステップは、カメラのGenICam XMLドキュメントの取得、ノードマップの作成、およびそれをXMLに接続することです。

カメラからXMLドキュメントをダウンロードして抽出するには、次の関数を使用できます。 Sgc_loadCameraXml() および Sgc_getCameraPropertyWithType() まず、カメラからXMLドキュメントをダウンロードするために、関数 Sgc_loadCameraXml() を呼び出す必要があります。次に、XMLドキュメントの抽出に必要なバッファのサイズを要求するために、関数 Sgc_getCameraPropertyWithType() を呼び出して渡すことができます CAM_PROP_XML_DATA を渡したときのデフォルトの動作は、 property および nullptr を渡したときのデフォルトの動作は、 value を使用します。必要なサイズのバッファを割り当てた後、 Sgc_getCameraPropertyWithType() を再度呼び出し、パラメータ value にバッファへのポインタを渡してXMLドキュメントを抽出します。

次の例は、カメラからXMLドキュメントをダウンロードして抽出し、ノードマップを初期化して接続し、転送する画像の幅と高さを設定する方法を示しています。(この例では、C++ヘッダーファイル memory の std::unique_ptr 型と stdexcept の std::runtime_error および std::exception 型が必要です。)

try {
    // download camera XML
    int result = Sgc_loadCameraXml(camera);
    if (result != SGC_OK)
        throw std::runtime_error("Failed to download camera XML");

    // get size of XML
    unsigned int size = 0;
    unsigned int propertyType = SGC_PROPERTY_TYPE_STRING;
    result =
        Sgc_getCameraPropertyWithType(camera, CAM_PROP_XML_DATA,
                                      nullptr, &propertyType, &size);
    if (result != SGC_OK || size == 0)
        throw std::runtime_error("Failed to determine size of camera XML");

    // create buffer and extract camera XML
    std::unique_ptr<char[]> xml(new char[size]);
    result =
        Sgc_getCameraPropertyWithType(camera, CAM_PROP_XML_DATA,
                                      xml.get(), &propertyType, &size);
    if (result != SGC_OK)
        throw std::runtime_error("Failed to extract camera XML");

    // create device port and node map
    DevicePort port(camera);
    GENAPI_NAMESPACE::CNodeMapRef nodeMap;

    // initialize and connect node map
    nodeMap._LoadXMLFromString(xml.get());
    if (!nodeMap._Connect(&port, "Device"))
        throw std::runtime_error("Failed to connect node map to device port");

    // use node map to access camera features ...

    // set width
    GENAPI_NAMESPACE::CIntegerPtr width = nodeMap._GetNode("Width");
    if (width != nullptr) {
        width->SetValue(1920);
    }

    // set height
    GENAPI_NAMESPACE::CIntegerPtr height = nodeMap._GetNode("Height");
    if (height != nullptr) {
        height->SetValue(1080);
    }

} catch (GENICAM_NAMESPACE::GenericException & x) {
    // handle GenICam exceptions ...
} catch (std::exception & x) {
    // handle C++ standard exceptions ...
}

カメラ接続の変更#

int Sgc_setCameraPropertyWithType(
    SgcCameraHandle * camera,
    const char * property,
    const void * value,
    unsigned int type,
    void * additionalValue);

リンク速度またはカメラで使用されるリンク数を変更するには、関数 Sgc_setCameraPropertyWithType() を呼び出すことができます。これは、「カメラ情報」の章で説明されている関数 Sgc_getCameraPropertyWithType() 章で説明されている カメラ情報.

変更できるPropertyには、次の2つがあります:

Property 説明 タイプ
CAM_PROP_LINKSPEED 現在のリンク速度(Mbit/s単位) uint32_t
CAM_PROP_NROFLINKS 画像転送に使用される物理リンクの数 uint32_t

複数プロセスからのカメラ検出のサポート#

int Sgc_initBoardEx(
    Fg_Struct * fg,
    unsigned int flags,
    SgcBoardHandle ** board,
    unsigned int portMask,
    unsigned int mode);
int Sgc_scanPortsEx(
    SgcBoardHandle * board,
    unsigned int portMask,
    int timeout,
    int speed,
    unsigned int flags);

情報

複数のプロセスからのカメラ検出のサポートは、Framegrabber APIのバージョン5.9で追加されました。

アプリケーションが複数のプロセスを使用して単一のフレームグラバー上のカメラにアクセスする場合、Framegrabber APIでサポートされるのは、フレームグラバー上の物理ポートあたり1つのプロセスのみです。単一のプロセスで複数の物理ポートにアクセスすることはできますが、どの物理ポートも複数のプロセスからFramegrabber APIを介してアクセスしてはなりません。

マルチプロセスアプリケーションでは、物理ポートへのアクセスを制限するために、以下の呼び出しを置き換えることができます。 Sgc_initBoard() および Sgc_scanPorts() を Sgc_initBoardEx() および Sgc_scanPortsEx() およびポートマスクを使用して行います。さらに、 SGC_SP_FLAG_SKIP_AUTO_PORTADJUSTMENT の呼び出しで使用する必要があります。 Sgc_scanPortsEx() パラメータ内で flags 物理ポートのマッピング解除を抑制します。

ポートマスクには物理ポートあたり1ビットを使用し、ビットが1の場合はポートへのアクセスを有効にし、0の場合は無効にします。ビット0は物理ポート0に対応し、以下同様です。デフォルトのポートマスクでは、 0xf 4つのポートすべてのビットが1であるため、4つのポートすべてへのアクセスが有効になります。

最も理解しやすいシナリオは、1つのフレームグラバーと4台のカメラがあり、各カメラが1つの物理ポートに接続されているセットアップです。最初のプロセスはポートマスク 0x1、2番目のプロセスは 0x2、3番目のプロセスは 0x4 、4番目のプロセスは 0x8を使用できます。各プロセスは、1つの物理ポートでの初期化と検出を担当します。

複数のリンクで接続されたカメラを検討する場合、カメラは常に正しい物理ポートに接続されている必要があるため、少し複雑になります。たとえば、最初のプロセスがポートマスク 0x3 を使用し、2番目のプロセスがポートマスク 0xcを使用する場合、カメラのケーブルはいかなる場合でも、1台目のカメラはポート0と1に、2台目のカメラはポート2と3に接続されている必要があります。もし何らかの理由でカメラが異なる方法で接続された場合、検出プロシージャは失敗します。


  1. カメラおよびアップレット内のカメラオペレータは、マスターIDによって識別できます。有効な最小のマスターIDは1です。カメラマスターIDは、フレームグラバーボードのインデックスと、カメラマスターポートが接続されている物理ポート番号から生成される値です。カメラオペレータマスターIDは、オペレータマスターポートが接続されている論理ポートから生成される値です。 ↩↩