IC Imaging Control (.NET C#/Visual Basic)

  • サンプルプログラムトップページ
  • デバイスのオープンとハンドリング
    • C# VB.NET カメラの映像を既存のアプリケーションに組み込む方法
    • C# VB.NET デバイスを開く
    • C# VB.NET デバイスの開閉
    • C# VB.NET ダイアログボックスを使用してデバイスを開く
    • C# VB.NET 複数のデバイスを開く
    • C# VB.NET デバイスのシリアル番号を読み取る
    • C# VB.NET ICImagingControlの標準プロパティダイアログの使用
    • C# VB.NET デバイスプロパティ設定の保存と復元
  • ライブ表示
    • C# VB.NET ライブ表示のリサイズ
    • C# VB.NET フルスクリーン表示
    • C# VB.NET 十字マークのオーバーレイ
    • C# VB.NET WFPでvideoWindowを使ったビデオ表示
  • フレームフィルタ
    • C# VB.NET 低輝度、高輝度ピクセルの強調 その1
    • C# VB.NET 低輝度、高輝度ピクセルの強調 その2
  • ライブ表示とマルチプロセス
    • C# VB.NET ライブ表示のみ
    • C# VB.NET 静止画保存
    • C# VB.NET 任意のタイミングで画像処理と静止画保存を同時に処理
    • C# VB.NET 録画しながら任意のタイミングで静止画保存
    • C# VB.NET 全フレームリアルタイム画像処理しながら
             NG判定を静止画保存
    • C# VB.NET 全フレームリアルタイム画像処理しながら
             NG判定を静止画保存、同時に録画
  • イメージの取得
    • C# VB.NET イメージデータの取得
    • C# VB.NET 静止画ファイル保存(BMP)
    • C# VB.NET 静止画ファイル保存(JPEG)
    • C# VB.NET 静止画ファイルの連番保存
    • C# VB.NET カメラ画像保存&FTPで任意のサーバーに転送する
    • C# VB.NET リングバッファを使用したイメージシーケンスの取得と再生
    • C# VB.NET 静止画とAVI動画保存
    • C# VB.NET メモリーレコーディング
             (高速カメラで撮影した現象をRAMメモリー領域に保存)
    • C# VB.NET ソフトウェアトリガーで画像を表示・保存
    • C# VB.NET 録画時間を指定したAVIファイル保存
    • C# VB.NET 外部トリガーで録画の開始
    • C# VB.NET 取得したイメージの輝度値をCSV形式で出力する
             (16bit対応)
  • 画像処理
    • C# VB.NET イメージデータへのアクセス
    • C# VB.NET コントラストの強調 - Part 1
    • C# VB.NET コントラストの強調 - Part 2
    • C# VB.NET コントラストの強調 - Part 3
    • C# VB.NET レーザーポインタの位置を特定する
    • C# VB.NET OpenCVの画像処理
             (アナログタコメーターのデジタル化)
    • C# VB.NET AIモデルを使ったリアルタイム処理
  • Version 3.5サンプル
    • C# VB.NET 関心領域の画像更新
      Advanced Image Processing
    • C# VB.NET 2値化
      Binarization
    • C# VB.NET 明るさの調整
      BrightnessProperty
    • C# VB.NET 動画保存(MediaStreamSink)
      Capturing a Video File
    • C# VB.NET 動画保存(AviStartCapture)
      Capturing an AVI File
    • C# VB.NET 共通ファイル
      Common
    • C# VB.NET オーバーレイの作成
      Creating an Overlay
    • C# VB.NET デモアプリ
      demoapp
    • C# VB.NET VCDプロパティ:GPIOプロパティ編
      DigitalIO
    • C# VB.NET コールバック関数を使ってバッファを表示させる
      Display Buffer
    • C# VB.NET フィルターの適用
      Filter Inspector
    • C# VB.NET 静止画をキャプチャし保存する
      Grabbing an Image
    • C# VB.NET イメージバッファの輝度値を読み込み、輝度反転処理を施す
      Image Processing
    • C# VB.NET VCDプロパティ:全プロパティ一覧を表示する編
      List VCDProperties
    • C# VB.NET デバイス設定ダイアログの作成
      Making Device Settings
    • C# VB.NET イメージバッファにアクセスする
      Pixelformat
    • C# VB.NET コーデックのプロパティを保存する
      Saving Codec Properties
    • C# VB.NET スクロールとズーム
      croll And Zoom
    • C# VB.NET VCDプロパティ:露光とゲイン編
      StandardProperties
    • C# VB.NET VCDプロパティ:ストロボアウト編
      Strobe
    • C# VB.NET VCDプロパティ:
             プロパティダイアログ画面のカスタマイズ編
      VCD Property Page
    • C# VB.NET VCDプロパティ:明るさとホワイトバランス編
      VCD Simple Property
    • C# VB.NET VCDプロパティ:オートフォーカス編
    • C# VB.NET デバイスの再接続方法とフレーム落ちの確認
  • リンク集

    ICImagingControl WEB APIリファレンスマニュアル/サンプルプログラム

    :日本語対応済み :日本語化準備中
    開発言語 APIリファレンスマニュアル サンプルプログラム
    C 4.0
    ()
    - - 4.0
    ()
    - -
    C++ 4.0
    ()
    3.5
    ()
    3.4
    ()
    4.0
    ()
    3.5 3.4
    ()
    C#/VB.NET 4.0
    ()
    3.5
    ()
    3.4
    ()
    4.0
    ()
    3.5
    ()
    3.4
    ()
    Python 4.0
    ()
    3.5 3.4
    ()
    4.0
    ()
    3.5 3.4
    ()

イメージバッファにアクセスする

概要

ビット深度8bitのモノクロ、ビット深度16bitのモノクロ、ビット深度24bit(3byte)のカラー、ビット深度32bit(4byte)のカラーそれぞれの画像を保存とイメージバッファーにアクセスし輝度値を操作する方法について説明します。

サンプルプログラム

Software IC Imaging Control 3.5, Visual Studio™ 2019
サンプル(C#) pixelformat_cs_3.5.zip

実行結果

Y800(Y800.bmp),Y16(y16.tiff)で保存した画像を拡大すると、左上のピクセルが黒、グレー、白の順で配列されているのが分かります。

RGB24(RGB24.bmp)、RGB32(RGB32.bmp)で保存した画像を拡大すると、左上のピクセルが黒、グレー、白の順で配列されているのが分かります。

Visual Studioのプログラム上ではすでにボタンの設置や関数は定義済ですので、IC Imaging Contorl3.5をインストールされていれば、実行ボタンだけですぐにデバッグで動作確認することができます。
画面にあるそれぞれのボタンなどのコントローラの機能は下記の通りです。

[Y800]ボタン ビット深度8bitのモノクロのフォーマットでbmp形式の画像を保存します。
[Y16]ボタン ビット深度16bitのモノクロのフォーマットでbmp形式の画像を保存します。カメラ自体は10bitか12bitまでしか対応していませんので、残り4bit分の精度の保証はしておりません。
[RGB24]ボタン ビット深度24bit(3byte)のカラーのフォーマットでbmp形式の画像を保存します。(RGB(赤・青・緑)のそれぞれの色情報を1byte分として保持しています。)
[RGB32]ボタン ビット深度32bit(4byte)のカラーのフォーマットでbmp形式の画像を保存します。(RGB(赤・青・緑)のそれぞれの色情報を1byte分と、アルファ値(透明度)の情報を1byte分保持しています。なお、アルファ値はIC Imaging Controlでは使用されておりません。)

初期設定

 private void Form1_Load(object sender, EventArgs e)
{

    if( !icImagingControl1.LoadShowSaveDeviceState("lastSelectedDeviceState.xml") )
    {
        MessageBox.Show("No device was selected.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        this.Close();
        return;
    }
    icImagingControl1.LiveDisplayDefault = false;
    icImagingControl1.LiveDisplaySize = icImagingControl1.Size;
    //設定したカラーフォーマットがY16だった場合にはY16ボタンが使えるように許可
    cmdY16.Enabled = icImagingControl1.VideoFormat.StartsWith("Y16");
    //OverlayBitmapオブジェクトを使用しない
    icImagingControl1.OverlayBitmapPosition = TIS.Imaging.PathPositions.None;
    icImagingControl1.LiveStart();
}

BufferAccessHelperクラスを使ってIFrame.Ptrをサポートするデータへの配列を制御するため、Form1がロードされたタイミングでOverlayBitmapPositionを無効化します。

Y800ボタンクリック時の処理

private void cmdY800_Click(object sender, EventArgs e)
{
    TIS.Imaging.IFrameQueueBuffer frame = GrabImage(TIS.Imaging.MediaSubtypes.Y800);
    if ( frame == null) return;

    BufferAccessHelper buf = new BufferAccessHelper( frame );

    // Y800は 上の行から読み込む
    int y = 0;

    txtOutput.Text = "Image buffer pixel format is Y800\r\n";
    txtOutput.Text += "Pixel 1: " + buf[0, y] + "\r\n";
    txtOutput.Text += "Pixel 2: " + buf[1, y];


    // (0,0)ピクセルの座標位置の輝度値を0 (黒)にする
    buf[0, y] = 0;
    // (1,0)ピクセルの座標位置の輝度値を0 (グレー)にする
    buf[1, y] = 128;
    // (2,0)ピクセルの座標位置の輝度値を255 (白)にする
    buf[2, y] = 255;

    //Bitmap形式で画像を保存する
    TIS.Imaging.FrameExtensions.SaveAsBitmap(frame, "Y800.bmp");

}

GrabImageメソッドを使って新しいフレームを取得します。
BufferAccessHelperクラスをインスタンス化することでポインタにアクセスできるようになります。
Y800のイメージバッファのピクセルは左から右へ、上から下へと割り当てられているので、取得したフレームの左上の座標は(0,0)となります。
buf変数の配列に輝度値の数値を入れることでピクセル単位で輝度値を変更することができます。

RGB24ボタンクリック時の処理

private void cmdRGB24_Click(object sender, EventArgs e)
{
    TIS.Imaging.IFrameQueueBuffer frame = GrabImage(TIS.Imaging.MediaSubtypes.RGB24);
    if ( frame == null) return;

    BufferAccessHelper buf = new BufferAccessHelper(frame);


    // RGB24は 下の行から読み込む
    int y = frame.FrameType.Height - 1;

    txtOutput.Text = "Image buffer pixel format is RGB24\r\n";
    txtOutput.Text += "Pixel 1: ";
    txtOutput.Text += "R=" + buf[0 * 3 + 2, y] + ", ";
    txtOutput.Text += "G=" + buf[0 * 3 + 1, y] + ", ";
    txtOutput.Text += "B=" + buf[0 * 3 + 0, y] + "\r\n";
    txtOutput.Text += "Pixel 2: ";
    txtOutput.Text += "R=" + buf[1 * 3 + 2, y] + ", ";
    txtOutput.Text += "G=" + buf[1 * 3 + 1, y] + ", ";
    txtOutput.Text += "B=" + buf[1 * 3 + 0, y];


    // (0,y)ピクセルの座標位置の輝度値を赤にする
    buf[0 * 3 + 2, y] = 255;
    buf[0 * 3 + 1, y] = 0;
    buf[0 * 3 + 0, y] = 0;
    // (1,y)ピクセルの座標位置の輝度値を緑にする
    buf[1 * 3 + 2, y] = 0;
    buf[1 * 3 + 1, y] = 255;
    buf[1 * 3 + 0, y] = 0;
    // (2,y)ピクセルの座標位置の輝度値をblueにする
    buf[2 * 3 + 2, y] = 0;
    buf[2 * 3 + 1, y] = 0;
    buf[2 * 3 + 0, y] = 255;
    //Bitmap形式で画像を保存する
    TIS.Imaging.FrameExtensions.SaveAsBitmap(frame, "RGB24.bmp");

}

GrabImageメソッドを使って新しいフレームを取得します。
BufferAccessHelperクラスをインスタンス化することでポインタにアクセスできるようになります。
RGB24のイメージバッファのピクセルは左から右へ、下から上へと割り当てられているので、取得したフレームの左上の座標は(0,フレームの高さ分-1)となります。
buf変数の配列に輝度値の数値を入れることでピクセル単位で輝度値を変更することができます。

RGB32ボタンクリック時の処理

private void cmdRGB32_Click(object sender, EventArgs e)
{
    TIS.Imaging.IFrameQueueBuffer frame = GrabImage(TIS.Imaging.MediaSubtypes.RGB32);
    if( frame == null ) return;

    BufferAccessHelper buf = new BufferAccessHelper( frame );


    // RGB32は 下の行から読み込む
    int y = frame.FrameType.Height - 1;

    txtOutput.Text = "Image buffer pixel format is RGB32\r\n";
    txtOutput.Text += "Pixel 1: ";
    txtOutput.Text += "R=" + buf[0 * 4 + 2, y] + ", ";
    txtOutput.Text += "G=" + buf[0 * 4 + 1, y] + ", ";
    txtOutput.Text += "B=" + buf[0 * 4 + 0, y] + "\r\n";
    txtOutput.Text += "Pixel 2: ";
    txtOutput.Text += "R=" + buf[1 * 4 + 2, y] + ", ";
    txtOutput.Text += "G=" + buf[1 * 4 + 1, y] + ", ";
    txtOutput.Text += "B=" + buf[1 * 4 + 0, y];


    // (0,y)ピクセルの座標位置の輝度値をredにする
    buf[0 * 4 + 2, y] = 255;
    buf[0 * 4 + 1, y] = 0;
    buf[0 * 4 + 0, y] = 0;
    // (1,y)ピクセルの座標位置の輝度値をgreenにする
    buf[1 * 4 + 2, y] = 0;
    buf[1 * 4 + 1, y] = 255;
    buf[1 * 4 + 0, y] = 0;
    // (2,y)ピクセルの座標位置の輝度値をblueにする
    buf[2 * 4 + 2, y] = 0;
    buf[2 * 4 + 1, y] = 0;
    buf[2 * 4 + 0, y] = 255;

    //Bitmap形式で画像を保存する
    TIS.Imaging.FrameExtensions.SaveAsBitmap(frame, "RGB32.bmp");

}

GrabImageメソッドを使って新しいフレームを取得します。
BufferAccessHelperクラスをインスタンス化することでポインタにアクセスできるようになります。
RGB32のイメージバッファのピクセルは左から右へ、下から上へと割り当てられているので、取得したフレームの左上の座標は(0,フレームの高さ分-1)となります。
buf変数の配列に輝度値の数値を入れることでピクセル単位で輝度値を変更することができます。

Y16ボタンクリック時の処理

private void cmdY16_Click(object sender, EventArgs e)
{
    TIS.Imaging.IFrameQueueBuffer buf = GrabImage(TIS.Imaging.MediaSubtypes.Y16);
    if (buf == null) return;

    //2ピクセルを取得
    UInt32 val0 = ReadY16(buf, 0, 0);
    UInt32 val1 = ReadY16(buf, 0, 1);

    txtOutput.Text = "Image buffer pixel format is Y16\r\n";
    txtOutput.Text += "Pixel 1: " + val0 + "\r\n";
    txtOutput.Text += "Pixel 2: " + val1;
    // (0,0)ピクセルの座標位置の輝度値をBlack)にする
    WriteY16(buf, 0, 0, 0x0000); 
    // (0,1)ピクセルの座標位置の輝度値をGrayにする
    WriteY16(buf, 0, 1, 0x8000); 
    // (0,2)ピクセルの座標位置の輝度値をWhiteにする
    WriteY16(buf, 0, 2, 0xFFFF);
    //Tiff形式で画像を保存する
    TIS.Imaging.FrameExtensions.SaveAsTiff( buf, "y16.tiff");

}


//イメージデータの輝度値の書き込み
private unsafe UInt16 ReadY16(TIS.Imaging.IFrameQueueBuffer buf, int row, int col)
{
     // Y16は 上の行から読み込む (画像幅に依存した、ライン当たりのBytes量を取得)
    int offset = row * buf.FrameType.BytesPerLine + col * 2;
     //メモリから 16 ビット符号付き整数を読み取り
    return (UInt16)System.Runtime.InteropServices.Marshal.ReadInt16(new IntPtr(buf.Ptr), offset);
}

private unsafe void WriteY16(TIS.Imaging.IFrameQueueBuffer buf, int row, int col, UInt16 value)
{
    int offset = row * buf.FrameType.BytesPerLine + col * 2;
     //メモリに 16 ビット符号付き整数を書き込み
    System.Runtime.InteropServices.Marshal.WriteInt16( new IntPtr( buf.Ptr ), offset, (short)value);
}

GrabImageメソッドを使って新しいフレームを取得します。
イメージバッファのデータにアクセスするために、BufferAccessHelperクラスではなく、新たに16bitの符号なし整数データとして取得する必要があります。System.Runtime.InteropServices.Marshal.ReadInt16を 使用することによりヘルパー関数のReadY16が使えます。
RGB32のイメージバッファのピクセルは左から右へ、下から上へと割り当てられているので、取得したフレームの左上の座標は(0,フレームの高さ分-1)となります。
buf変数の配列に16進数の輝度値の数値を入れることでピクセル単位で輝度値を変更することができます。

イメージバッファへのアクセス方法

private TIS.Imaging.IFrameQueueBuffer GrabImage(Guid colorFormat)
{
    bool wasLive = icImagingControl1.LiveVideoRunning;
    //ライブストリーミング停止
    icImagingControl1.LiveStop();
    //現在設定中のシンクオブジェクトを保存する
    TIS.Imaging.BaseSink oldSink = icImagingControl1.Sink;
    //ビデオストリームから不定期に、1枚、または複数の画像を取得する際に使用します。
    TIS.Imaging.FrameSnapSink sink = new TIS.Imaging.FrameSnapSink( new TIS.Imaging.FrameType( colorFormat ) );
    //シンク設定
    icImagingControl1.Sink = sink;

    try
    {
        icImagingControl1.LiveStart();
    }
    catch (TIS.Imaging.ICException ex)
    {
        MessageBox.Show(ex.Message);
        icImagingControl1.Sink = oldSink;
        return null;
    }

    //FrameSnapSinkで取得したイメージバッファを参照する
    TIS.Imaging.IFrameQueueBuffer rval = null;

    try
    {
        //フレームを取得する
        rval = sink.SnapSingle( TimeSpan.FromSeconds( 1 ) );
    }
    catch (TIS.Imaging.ICException ex)
    {
        MessageBox.Show(ex.Message);
    }

    icImagingControl1.LiveStop();
    //古いシンクを復元する
    icImagingControl1.Sink = oldSink;

    if (wasLive)
        icImagingControl1.LiveStart();

    return rval;
}

イメージバッファへのアクセスはIFrameQueueBufferインターフェースを使います。
イメージバッファ内には何もありませんので、画像をキャプチャするためにFrameSnapSink.SnapSingleメソッドを呼び出しフレームを取得します。イメージバッファにアクセスしたのちにライブストリーミングをディスプレイに表示するために保存しておいたシンクオブジェクトを復元しています。

class BufferAccessHelper
{
    TIS.Imaging.IFrameQueueBuffer buf;

    public BufferAccessHelper( TIS.Imaging.IFrameQueueBuffer buf )
    {
        this.buf = buf;
    }

    public unsafe byte this[int x,int y]
    {
        get
        {
            byte* ptr = buf.Ptr + y * buf.FrameType.BytesPerLine + x;
            return *ptr;
        }
        set
        {
            byte* ptr = buf.Ptr + y * buf.FrameType.BytesPerLine + x;
            *ptr = value;
        }
    }
}

イメージバッファのデータにアクセスするために、BufferAccessHelperのクラスを定義しています。
IFrame.Ptrプロパティで画像データへのポインタにアクセスすることができます。そうすることで、イメージバッファー内にbuf[column,line]として個別のデータにアクセスできます。

下記のAPIリファレンスマニュアルにもその他関数などの説明があります。

プログラマーズガイド:イメージバッファにアクセスする
IC Imaging Control_Ver3.5(C#/VB.NET) APIリファレンスマニュアル

▲ このページの先頭に戻る

Copyright © ARGO Corporation. All Rights Reserved.