取得したイメージの輝度値をCSV形式で出力する(16bit対応)
概要
8bitのカラー・モノクロ、16bitのカラー・モノクロのそれぞれの画像を取得し、bmp/tiff形式で保存し、同時にCSV形式で各ピクセルごとの輝度値を出力しています。
サンプルプログラム
Software | IC Imaging Control 3.5, Visual Studio™ 2019 |
---|---|
サンプル(C#) | Luminance_value_CSV_output_cs_3.5.zip |
インストーラファイル | Luminance_value_CSV_output_app.zip ※インストーラファイルを実行するためにはIC Imaging Control3.5をインストールしておく 必要があります。 |
実行結果
右クリックからプロパティやデバイス選択のダイアログ画面を呼び出すことも可能です。また、Ctrlキーを押しながらマウスのホイールを回すことでズームイン・ズームアウトすることができますなお、グレーで使用できないボタンは「デバイスを選択」をクリックしダイアログ画面を開いて、該当するカラーフォーマットを選択することでボタンが使えるようになります。例えば、Y16のカラーフォーマットを選択したい場合は「デバイスダイアログ画面」にて「Y16(640x480)」などのカラーフォーマットを選択する必要があります。
例:Y800の輝度値の出力結果
8bit形式の場合、0~255の間で輝度値は出力されます。
例:RGB64の輝度値の出力結果
16bit形式の場合、0~65535の間で輝度値は出力されます。ただし、TheImagingSource社のカメラはADC階調は10bitあるいは12bitまでしか対応しておりません。16bitにするためにドライバ側で10bitあるいは12bitに足りない桁数分だけ「0」を追加(ゼロパディング)しています。
Form Loadでインターフェース割り当てとコントロール初期化
private void Form1_Load(object sender, EventArgs e)
{
icImagingControl1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.icImagingControl1_MouseWheel);
// デバイス設定ダイアログを表示する。
if (!icImagingControl1.LoadShowSaveDeviceState("lastSelectedDeviceState.xml"))
{
MessageBox.Show("No device was selected.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Close();
return;
}
//カラーフォーマットによってボタンを有効化/無効化する
cmdY16.Enabled = icImagingControl1.VideoFormat.StartsWith("Y16");
cmdRGB32.Enabled = icImagingControl1.VideoFormat.StartsWith("RGB32");
cmdRGB64.Enabled = icImagingControl1.VideoFormat.StartsWith("RGB64");
icImagingControl1.OverlayBitmapPosition = TIS.Imaging.PathPositions.None;
//表示するサイズを変更するのでfalseにする
icImagingControl1.LiveDisplayDefault = false;
icImagingControl1.LiveStart();
//アスペクト比固定
intsldZoom = icImagingControl1.Height * 100 / icImagingControl1.LiveDisplayOutputHeight;
icImagingControl1.LiveDisplayZoomFactor = (float)intsldZoom / 100f;
//右クリック可能
this.ContextMenuStrip = this.contextMenuStrip1;
}
まず、System.Windows.Forms.MouseEventHandlerでマウスのホイールを回したときにイベントが発火するように宣言します。
次に、LoadShowSaveDeviceStateを使って、保存したデバイスの設定"lastSelectedDeviceState.xml"を呼び出し、その後デバイス選択ダイアログを開きます。
次に選択したカラーフォーマットによってフォーム上にあるボタンを有効化/無効化しています。これは【カメラから出力されるカラーフォーマットの型】と【輝度値を読み取るときのフレームタイプの型】を予め一致させておく必要があるからです。例えば、カメラがY800のカラーフォーマットを選択しカメラからの8bitの画像を出力しているにもかかわらず、Y16のボタンをクリックしCSV出力しようとしても、型が違うため8bitの画像を16bitのデータとして出力を変更できません。カメラの設定でY800のカラーフォーマットを選択した後に、Y16のカラーフォーマットにしたい場合には、必ずデバイスダイアログ画面のカメラの設定でカラーフォーマットをY16に変更してください。
[Ctrl]キーを押しながらスクロールでズームイン・ズームアウト機能
private void icImagingControl1_MouseWheel(object sender, MouseEventArgs e)
{
//Ctrl キーが押された状態であるか確認
if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
{
if (icImagingControl1.LiveDisplayDefault == false)
{
int value = (e.Delta * SystemInformation.MouseWheelScrollLines / 360) + intsldZoom;
if (80 >= value && 1 <= value)
{
intsldZoom = value;
icImagingControl1.LiveDisplayZoomFactor = (float)intsldZoom / 10.0f;
}
}
}
}
Ctrlキーを押しながらズームするためには、Ctrlキーが押されてなおかつ、画像のサイズの変更(LiveDisplayDefault:false)が許可する必要がありますので、if文で条件分岐させます。 スクロール分だけ拡大するように、マウスホイールを1行分回すときには360(PCの設定にもよります)として計算し、スクロールした分だけズームイン・ズームアウトできるようにスクロールした値をLiveDisplayZoomFactorにセットします。
Y800カラーフォーマットのCSV出力
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);
Cursor.Current = Cursors.WaitCursor;
txtOutput.Text = "処理中";
Refresh();
string strFormat = frame.FrameType.Name;
TIS.Imaging.FrameExtensions.SaveAsBitmap(frame, "Y800.bmp");
string strBuf = "";
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"Output" + strFormat + ".csv", false))
{
for (int i = 0; i < frame.FrameType.Height; i++)
{
strBuf = "";
for (int j = 0; j < frame.FrameType.Width; j++)
{
strBuf += "Y800(";
strBuf += buf[j, i] + "),";
}
writer.WriteLine(strBuf);
}
}
//元に戻す
Cursor.Current = Cursors.Default;
txtOutput.Text = "処理終了";
}
上記はGrabImageの関数内でSnapImageでY800の画像をイメージバッファ内に取得し、取得した画像をSaveAsBitmapでbmp形式で保存します。
Y800はモノクロ8bitのカラーフォーマットで、すべてのピクセルが1バイトで表されます。イメージバッファのピクセルは左から右へ、上から下へと構成されています。イメージバッファのデータにアクセスするために、buf[ピクセル行,ピクセル列]に関して左から右、上から下の順番でstrBuf の変数に格納し、CSVに出力しています。
Y16カラーフォーマットのCSV出力
private void cmdY16_Click(object sender, EventArgs e)
{
TIS.Imaging.IFrameQueueBuffer buf = GrabImage(TIS.Imaging.MediaSubtypes.Y16);
if (buf == null) return;
//待機状態
Cursor.Current = Cursors.WaitCursor;
txtOutput.Text = "処理中";
Refresh();
string strFormat = buf.FrameType.Name;
TIS.Imaging.FrameExtensions.SaveAsTiff(buf, "y16.tiff");
string strBuf = "";
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"Output" + strFormat + ".csv", false))
{
for (int i = 0; i < buf.FrameType.Height; i++)
{
strBuf = "";
for (int j = 0; j < buf.FrameType.Width; j++)
{
strBuf += "Y16(";
strBuf += ReadY16(buf, i, j) + "),";
}
writer.WriteLine(strBuf);
}
}
//元に戻す
Cursor.Current = Cursors.Default;
txtOutput.Text = "処理終了";
}
private unsafe UInt16 ReadY16(TIS.Imaging.IFrameQueueBuffer buf, int row, int col)
{
// Y16 is top-down, the first line has index 0
int offset = row * buf.FrameType.BytesPerLine + col * 2;
return (UInt16)System.Runtime.InteropServices.Marshal.ReadInt16(new IntPtr(buf.Ptr), offset);
}
上記はGrabImageの関数内でSnapImageでY800の画像をイメージバッファ内に取得し、取得した画像をSaveAsTiffでtiff形式で保存します。
Y16はモノクロ16bitのカラーフォーマットで、すべてのピクセルが2バイト(符号なしの16bit整数値)で表されます。
ただし、TheImagingSource社のカメラはADC階調は10bitあるいは12bitまでしか対応しておりません。16bitにするためにドライバ側で10bitあるいは12bitに足りない桁数分だけ「0」を追加(ゼロパディング)しています。
なお、イメージバッファのピクセルは左から右へ、上から下へと構成されています。イメージバッファのデータにアクセスするために、buf[ピクセル行,ピクセル列]に関して左から右、上から下の順番でstrBuf の変数に格納し、CSVに出力しています。
画像を読み込むために 16 ビット符号付き整数を読み取るための関数Marshal.ReadInt16 メソッドを使用します。
それによって16bitの符号なし整数データを取得することができます。
RGB24カラーフォーマットのCSV出力
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);
Cursor.Current = Cursors.WaitCursor;
txtOutput.Text = "処理中";
Refresh();
string strFormat = frame.FrameType.Name;
TIS.Imaging.FrameExtensions.SaveAsBitmap(frame, "RGB24.bmp");
string strBuf = "";
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"Output" + strFormat + ".csv", false))
{
for (int i = frame.FrameType.Height - 1; i >= 0; i--)
{
strBuf = "";
for (int j = 0; j < frame.FrameType.Width; j++)
{
strBuf += "RGB24(";
strBuf += buf[j * 3 + 2, i] + "/";
strBuf += buf[j * 3 + 1, i] + "/";
strBuf += buf[j * 3 + 0, i] + "),";
}
writer.WriteLine(strBuf);
}
}
//元に戻す
Cursor.Current = Cursors.Default;
txtOutput.Text = "処理終了";
}
RGB24はカラー24bitのカラーフォーマットです。
RGB24は24bit 、カラーのフォーマットです。 すべてのピクセルが3バイトで表されますが、1バイトがそれぞれ1色の値に対応します。'RGB' は それぞれRed (赤)、Green (緑)、Blue (青) を意味し、 3つのバイトがそれぞれRed, Green, Blueの値を表しているということになります。
Windowsの場合RGB データはBGRの順に並んでおりますので、最初のバイトがBlue,次にGreen, Redとなっており、イメージバッファのピクセルは左から右へ、下から上へと構成されます。そのため、イメージバッファのデータにアクセスするために、buf[ピクセル行,ピクセル列]に関して左から右、下から上の順番でRGBに並び替えてstrBuf の変数に格納し、CSVに出力しています。
RGB32カラーフォーマットのCSV出力
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);
Cursor.Current = Cursors.WaitCursor;
txtOutput.Text = "処理中";
Refresh();
string strFormat = frame.FrameType.Name;
TIS.Imaging.FrameExtensions.SaveAsBitmap(frame, "RGB32.bmp");
string strBuf = "";
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"Output" + strFormat + ".csv", false))
{
for (int i = frame.FrameType.Height - 1; i >= 0; i--)
{
strBuf = "";
for (int j = 0; j < frame.FrameType.Width; j++)
{
strBuf += "RGB32(";
strBuf += buf[j * 4 + 2, i] + "/";
strBuf += buf[j * 4 + 1, i] + "/";
strBuf += buf[j * 4 + 0, i] + "),";
}
writer.WriteLine(strBuf);
}
}
}
RGB32はカラー32bitのカラーフォーマットです。
RGB24と似ていますが、全てのピクセルがアルファ値(ピクセルの透過度を表す情報)を保持するためのバイトを余分にもっているところがRGB24と異なります。RGBに加えてアルファ値を加えると全てのピクセルは4バイトで構成されています。ただし、アルファ値はIC Imaging Control では使用されないため常に0となっています。つまりRGB24 のピクセルフォーマットの場合と全く同じ情報となります。なお、IC Imaging Control ではRGB32 のピクセルフォーマットはBGRAというバイト 順になっており、イメージバッファのピクセルは左から右へ、下から上へと構成されます。
イメージバッファのデータにアクセスするために、buf[ピクセル行,ピクセル列]に関して左から右、下から上の順番でRGBAに並び替えてstrBuf の変数に格納し、CSVに出力しています。
RGB64カラーフォーマットのCSV出力
private void cmdRGB64_Click(object sender, EventArgs e)
{
TIS.Imaging.IFrameQueueBuffer buf = GrabImage(TIS.Imaging.MediaSubtypes.RGB64);
if (buf == null) return;
Cursor.Current = Cursors.WaitCursor;
txtOutput.Text = "処理中";
Refresh();
string strFormat = buf.FrameType.Name;
TIS.Imaging.FrameExtensions.SaveAsTiff(buf, "RGB64.tiff");
string strBuf = "";
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"Output" + strFormat + ".csv", false))
{
for (int i = buf.FrameType.Height - 1; i >= 0; i--)
{
strBuf = "";
for (int j = 0; j < buf.FrameType.Width; j++)
{
strBuf += "RGB64(";
strBuf += ReadRGB64(buf, i, j * 3 + 2) + "/";
strBuf += ReadRGB64(buf, i, j * 3 + 1) + "/";
strBuf += ReadRGB64(buf, i, j * 3 + 0) + "),";
}
writer.WriteLine(strBuf);
}
}
//元に戻す
Cursor.Current = Cursors.Default;
txtOutput.Text = "処理終了";
}
private unsafe UInt16 ReadRGB64(TIS.Imaging.IFrameQueueBuffer buf, int row, int col)
{
int offset = (row * buf.FrameType.BytesPerLine + col * 2);
return (UInt16)System.Runtime.InteropServices.Marshal.ReadInt16(new IntPtr(buf.Ptr), offset);
}
上記はGrabImageの関数内でSnapImageでY800の画像をイメージバッファ内に取得し、取得した画像をSaveAsTiffでtiff形式で保存します。
RGB64はカラー64bitのカラーフォーマットで、すべてのピクセルが2バイト(符号なしの16bit整数値)で表されます。
ただし、TheImagingSource社のカメラはADC階調は10bitあるいは12bitまでしか対応しておりません。16bitにするためにドライバ側で10bitあるいは12bitに足りない桁数分だけ「0」を追加(ゼロパディング)しています。
なお、イメージバッファのピクセルは左から右へ、下から上へと構成されます。イメージバッファのデータにアクセスするために、buf[ピクセル行,ピクセル列]に関して左から右、下から上の順番でRGBに並び替えてstrBuf の変数に格納し、CSVに出力しています。
ここでは画像を読み込むために 16 ビット符号付き整数を読み取るための関数Marshal.ReadInt16メソッドを使用します。
それによって16bitの符号なし整数データを取得することができます。