mengineer's blog

ニッチなネタばかりですが。

JAISDK Node値の取得/変更

前回の続きです。(下記参照)

mengineer.hatenablog.com

FactoryOpen → CameraOpen → 所望の処理 → CameraClose というのが
基本的な流れでしたが、所望の処理でカメラのNode値を取得/変更しています。

下記画面の"Width", “Height”, “Gain"というのが各Node値ですね。 f:id:mengineer:20170722130655p:plain

前回と同じく、SimpleImageDisplayのサンプルで見ていきましょう。

カメラオープン確認とカメラID取得

Node値を取得する前に、指定したカメラがOpen出来たかを確認します、
以下は前回記事の4. カメラリスト更新 → カメラオープン の後です。

無事にOpen出来ていればIsOpenはTrueになります、かつNULLで無い場合に、
所望の処理を進めます、サンプルどれも基本的にこの考え方ですね。

CameraIDTextBoxは、画面の"ID of the first camera found"の部分です、
myCamera.CameraIDで、文字列としてカメラの設定情報を取得出来ます。

ちなみにIDと言っても、シリアル番号では有りません、注意して下さい、
他に"DeviceID"というNodeが有り、そちらがシリアル番号になるようです。

NumOfDataStreamはカメラの出力ストリーム数で、通常は1です、
GEポートが2つ有るカメラなどでは2になるのは?、と推測。

ストリームが有ればstart/stopボタンを有効にしているだけです。

if (null != myCamera && myCamera.IsOpen)
{
    CameraIDTextBox.Text = myCamera.CameraID;

    if (myCamera.NumOfDataStreams > 0)
    {
        StartButton.Enabled = true;
        StopButton.Enabled = true;
    }
    else
    {
        StartButton.Enabled = false;
        StopButton.Enabled = false;
    }

Node値の取得/上限、下限値の設定

以下はWidthの設定を抜粋していますが、他のNodeでも同じやり方です。

myWidthNodeは、前回記事の1. CFactory,CCamara,CNodeの定義で
あらかじめ設定しておいたNodeのひとつです。

myCamera.GetNode(Node名)で、所望のNodeを取得出来ます、
該当カメラにそのNodeが存在しなければ、NULLになります。

NULLで無ければ(→Nodeが存在すれば)、.Valueというプロパティで
現在の設定値を取得出来ます、それを数値にしてcurrentValueに一時保存。

同様にNode.MaxとNode.Minで、Nodeの上限値/下限値を取得出来ますので、
それを画面のNumericUpDownコントロールの上限/下限として設定します。

更に現在の設定値(currentValue)をNumericUpDownの現状値に設定します。

最後のSetFramegrabberValue(“Width”, (Int64)myWidthNode.Value);は、別途後述

int currentValue = 0;

// Get the Width GenICam Node
myWidthNode = myCamera.GetNode("Width");
if (myWidthNode != null)
{
    currentValue = int.Parse(myWidthNode.Value.ToString());

    // Update range for the Numeric Up/Down control
    // Convert from integer to Decimal type
    WidthNumericUpDown.Maximum = decimal.Parse(myWidthNode.Max.ToString());
    WidthNumericUpDown.Minimum = decimal.Parse(myWidthNode.Min.ToString());
    WidthNumericUpDown.Value = decimal.Parse(currentValue.ToString());

    WidthNumericUpDown.Enabled = true;
}
else
    WidthNumericUpDown.Enabled = false;

SetFramegrabberValue("Width", (Int64)myWidthNode.Value);

Node値の変更

ここもWidthの変更を抜粋しています、画面のNumericUpDownの値を変更すると、
NodeがNULLで無ければ、その値をintに変換して.Valueに入れているだけです。

private void WidthNumericUpDown_ValueChanged(object sender, EventArgs e)
{
    if (myWidthNode != null)
    {
        myWidthNode.Value = int.Parse(WidthNumericUpDown.Value.ToString());
        SetFramegrabberValue("Width", (Int64)myWidthNode.Value);
    }
}

SetFramegrabberValueとは ??

昔のJAISDK(バージョン1.4)には、この処理は入っていませんでした、
JAISDKのバージョン2.6以降、この処理が追加されたようです、あともうひとつ
SetFramegrabberPixelFormat() という処理も追加されていました。

ソースコードを見ると、J_Camera_GetLocalDeviceHandleという関数を呼んでいて、
それに対してWidth,Heightや、PixelFormatを設定しているようです。

USB3カメラの場合、LocalDeviceHandleにWidth,Height等を設定しに行った時点で、
InvalidPaeameterのエラーで、途中で処理を抜けるようになっています。

試しでコメントアウトしても、今回のUSB3カメラでは特に問題無く動きました、
よってCXP等、専用のFrameGrabberに対応させるための処理だと思われます。

カメラから取得したWidth、Height、PixelFormat等をFrameGrabberにも設定する、
FrameGrabberが無いカメラの場合(→GE,USB3等)では、途中でSkipされる、
ということのようです、機会を見てCXPカメラでも見てみたいと思います。