偏光カメラからAoLPカラー画像を取得し、HSIカラーの角度を算出
概要
偏光カメラで取得したAoLP(Angle of Linear Polarization:偏光角)画像を読み取り、各ピクセルの偏光角を数値としてCSVファイルに出力する処理を行っています。偏光カメラは、光の向き(振動方向)を検出できる特殊なカメラで、たとえば金属やガラスの表面の反射光の向きの違いを可視化することができます。
サンプルプログラム
利用した開発環境 | Visual Studio™ 2022 |
---|---|
SDK | IC Imaging Control 3.5(Python, C#, VB.NET) |
デバイスドライバ | Cam33U_setup,gigecam_setup |
デバイス | DYK33UX250/DZK33UX250、DYK33GX250/DZK33GX250 |
サンプル(C#) | AoLP_value_CSV_output_cs_3.5.zip |
サンプル(VB.NET) | ー |
exeファイル アプリケーション |
ー |
別途ファイル | ー |
関連参照URL | ー |
実行結果

下記のCSVファイルはRGB32ボタンを実行後に下記に格納されます。
\AoLP_value_CSV_output\bin\x86\Debug\OutputRGB32 (1224x1024).csv

Form起動時の処理
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;
}
icImagingControl1.VideoFormat = "RGB32 (1224x1024)"; // RGB32に設定
//AoLPにする
icImagingControl1.VCDPropertyItems.Find<VCDMapStringsProperty>(new Guid("{15DD5A42-673C-468D-B1B8-059C114191DB}"), VCDGUIDs.VCDElement_Value).Value = 2;
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;
}
フォームの読み込み時に偏光カメラの初期設定を行う処理です。偏光カメラでは、光の偏光方向(偏光角:AoLP)を可視化するために、各ピクセルにおける偏光情報を色で表現した画像を出力するモードが用意されています。この処理では、カメラをAoLPモードに切り替えることで、偏光角に対応する色(赤〜青など)を持ったカラー画像を取得できるようにしています。
RGB32ボタンを押下したとき、カラーフォーマットAoLPの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++)
{
int b = buf[j * 4 + 0, i]; // B値を取得
int g = buf[j * 4 + 1, i]; // G値を取得
int r = buf[j * 4 + 2, i]; // R値を取得
int a = buf[j * 4 + 3, i]; // アルファ値は使用しないが、RGB32なので読み取る
// AoLP
double aolp = GetAoLPFromRGB(r, g, b);
// 出力フォーマット: AoLP(deg)
strBuf += $"{aolp:F2},";
}
writer.WriteLine(strBuf.TrimEnd(','));
}
}
//元に戻す
Cursor.Current = Cursors.Default;
txtOutput.Text = "処理終了";
}
偏光カメラで取得したRGB32形式の画像から、各ピクセルに対応する偏光角(AoLP)を計算し、CSV形式で出力する処理を行います。RGB32ボタンが押されると、まずカメラからRGB32形式の画像を1フレーム取得し、それを「RGB32.bmp」として保存します。 取得した画像は、ICImagingControlのバッファに格納されており、このバッファには各ピクセルの色情報がBGRAの順で格納されています。RGB32形式は1ピクセルあたり4バイトで構成され、青(B)、緑(G)、赤(R)、アルファ(A)の順で並んできます。ただし、ICImagingControlではアルファ値は使用されておらず、常に0となっています。また、ピクセルの並び順は左から右、下から上で構成されているため、読み取り時にはこの順序で読み取る必要があります。
各ピクセルのRGB値を正しく取り出したあと、それを使って下記のGetAoLPFromRGB関数で偏光角を計算します。この関数では、RGBのバランスからHSIカラーマップの色相方向(色の向き)をベクトル解析し、その角度をAoLP(0〜180度)として算出します。AoLPの数値は、各行ごとに文字列として整形され、CSVファイルに書き出されます。このようにして、AoLP画像から、偏光角の値を取り出すことができます。
double GetAoLPFromRGB(int r, int g, int b)
{
// RGB正規化
double rN = r / 255.0;
double gN = g / 255.0;
double bN = b / 255.0;
// 角度を求める
double angleRad = Math.Atan2(Math.Sqrt(3) * (gN - bN), 2 * rN - gN - bN);
if (angleRad < 0)
angleRad += 2 * Math.PI;
double aolpDeg = angleRad * 90.0 / Math.PI; // πで180→AoLP(0〜180)
return aolpDeg;
}
偏光角を色で表現した画像(例えば、赤が0°、緑が60°、青が120°といったようなHSIカラーマップ)では、各ピクセルの色が角度を表しています。

このときRGBは単なる3成分の値としてではなく、ベクトルとして捉えることができます。このベクトルを角度として取り出すために、HSI色空間におけるHue(色相)導出式(HSI Hue calculation formula)を使って角度を計算します。

※上記の式は下記と等価な式です。

RGBにおいては、緑(G)と青(B)の差をy軸方向、赤(R)と緑青(GB)のバランスをx軸方向と見なし、そこから導かれるベクトルの向きを計算することで、角度を得ることができます。角度は本来0〜360度の円で表されますが、偏光角(AoLP)は180度周期で同じ偏光状態とみなされるため、算出された角度を「double aolpDeg = angleRad * 90.0 / Math.PI;」という式で0〜180度の範囲に正規化しています。このangleRadはラジアン単位で表された角度であり、それを180度スケールに変換するためにこの式が用いられています。
検証
本検証では、偏光カメラを0度、45度、90度、135度の各角度に回転させて設置し、同じ被写体(モニター画面)を撮影して比較を行いました。その結果、カメラを回転させるごとに、同じ位置の画素に対応する色相が変化し、たとえば0度で赤く見えていた部分が、45度回転させると緑や青に変化するなど、画像全体の色調が設置角度に応じて回転していく様子が確認できます。
カメラの設置角度:0度![]() |
カメラの設置角度:45度![]() |
カメラの設置角度:90度![]() |
カメラの設置角度:135度![]() |