Classes
Class | Description | |
---|---|---|
CFviPolarTrans | 極座標変換クラス | |
CFviPolarTransParam | 極座標変換パラメータ構造クラス | |
ErrorCode | エラーコード(極座標変換関連) | |
Function | 極座標変換関連関数群 |
Enumerations
Enumeration | Description | |
---|---|---|
CoordinateMode | 基準座標モード | |
SamplingMode | 濃度補間方法 |
Remarks
極座標変換関連のクラス、関数、定数等を局所化するネームスペースです。
トピック:
解説:
本ライブラリでの極座標とは、2次元ユークリッド空間での極座標であり、
円座標(Circular Polar Coordinate)です。
下図に座標系を示します。
変換式は、以下の通りです。
構成:
この機能は、極座標変換を行う本体のクラスと関数、極座標変換パラメータを保有するデータ構造クラスで構成されます。
関数は、FVIL.PolarTrans.Function クラスに集約しています。
-
本体(クラス):
クラス 内容 CFviPolarTrans 画像の極座標変換(または逆変換)を行うクラスです。 - 関数:
-
データ構造:
クラス データID 内容 CFviPolarTransParam 1700 極座標変換(または逆変換)を行う際に使用するパラメータです。
極座標変換と逆変換:
本ライブラリでは矩形から円形への変換を極座標変換と定義します。
下図の左から右への変換が極座標変換、右から左が逆変換です。
変換方向は、CFviPolarTrans クラスの
Invert プロパティで設定できます。
極座標変換パラメータ:
極座標変換パラメータは、CFviPolarTransParam に集約しています。 詳細については、このクラスの説明をご参照ください。
基準座標モード:
基準座標モードは、処理対象の領域(矩形)のどの位置を基準位置とするかを示します。 CoordinateMode 定数に定義された以下の4種類から指定することができます。
- Left ... 矩形の左辺が回転方向です。左上角と円中心、上辺と円半径が対応します。
- Right ... 矩形の右辺が回転方向です。右下角と円中心、下辺と円半径が対応します。
- Upper ... 矩形の上辺が回転方向です。右上角と円中心、右辺と円半径が対応します。
- Lower ... 矩形の下辺が回転方向です。左下角と円中心、左辺と円半径が対応します。
基準座標モードによって、処理対象領域(矩形)と出力領域(円形)を示すパラメータの対応関係が変化します。 詳細については、CFviPolarTransParam の説明をご参照ください。
下図に基準座標モードの指定例を示します。
- 橙色枠 ... 処理対象領域(矩形)を示します。
- 緑色×印 ... 処理対象領域(矩形)の基準位置を示します。出力領域(円形)の中心に対応します。
- 赤色線 ... 出力領域の回転開始角を示します。
下図は、上図左の処理対象領域(矩形)を極座標変換した例を示します。 基準座標モードは、FVIL.PolarTrans.CoordinateMode.Left を選択しているものとします。
- 基準となる例です。回転開始角を 0°、回転範囲を 360°、処理対象領域(矩形)の幅と高さを 100,300 と指定しています。
- 前述(1)の 回転範囲を 180°にした例です。
- 前述(1)の 回転範囲を 180°にし、処理対象領域(矩形)の高さを半分にした例です。
- 前述(1)の 処理対象領域(矩形)の高さを半分にした例です。
- 前述(1)の 回転範囲を -360°にした例です。文字列が反転しています。
- 前述(1)の 回転範囲を -180°にした例です。文字列が反転しています。
- 前述(1)の 回転開始角を 270°にした例です。
- 前述(1)の 処理対象領域(矩形)の幅を 0.8 倍にした例です。
濃度補間方法:
濃度補間法は、以下の3つから指定することができます。 詳細については、SamplingMode の説明をご参照ください。
- NearestNeighbor ... 最近傍法により濃度補間を行います。
- Bilinear ... 共一次線形補間により濃度補間を行います。
- Cubic ... 三次畳み込み法により濃度補間を行います。
処理対象画像の画像種別が BIN の場合は、濃度補間法は無効です。 常に NearestNeighbor で処理されます。
Examples
サンプルコード (極座標変換):
極座標変換の処理例:
回転するCD−ROMをラインセンサで撮像した画像(下図【入力画像】)を極座標変換して、
元の円形の状態(下図【出力画像】)に復元する処理例を示します。
【入力画像】
【出力画像】
ソースコード:
C# | Copy |
---|---|
// $Revision: 1.3 $ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using fvalgcli; // FvPluginXXXX attribute requires fvalgcli namespace User.SampleCode { public partial class PolarTrans { // ============================================================ /// <summary> /// 極座標変換クラス. /// </summary> [FvPluginExecute] public void PolarTransClass() { // 1) インスタンスの準備. FVIL.PolarTrans.CFviPolarTrans parser = new FVIL.PolarTrans.CFviPolarTrans(); FVIL.Data.CFviImage src = new FVIL.Data.CFviImage(); FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage(); // 2) 処理対象画像の取り込み. FVIL.File.Function.LoadImageFile(Defs.TestImageDir + "/disk_left.png", src, FVIL.PixelMode.Unpacking); // 3) 処理対象画像の有効性検査. int valid = FVIL.PolarTrans.CFviPolarTrans.CheckValidity(src); if (valid != FVIL.ErrorCode._SUCCESS) throw new FVIL.CFviException(valid, "FVIL.PolarTrans.CFviPolarTrans.CheckValidity"); // 4) 画像処理準備 (共通) parser.SrcImages[0] = src; parser.DstImages[0] = dst; // 5) パラメータ設定. parser.Invert = false; // false: 矩形→円形. parser.ClearBackMode = true; parser.SamplingMode = FVIL.PolarTrans.SamplingMode.Bilinear; parser.Param.CoordinateMode = FVIL.PolarTrans.CoordinateMode.Left; FVIL.PolarTrans.CFviPolarTransParam param = parser.Param; param.CoordinateMode = FVIL.PolarTrans.CoordinateMode.Left; param.OriginIn = new FVIL.Data.CFviPoint(src.Window.X,src.Window.Y); param.Width = src.Window.Width; param.Height = src.Window.Height; param.OriginOut = new FVIL.Data.CFviPoint(param.Width,param.Width); param.Radius = param.Width; param.StartAngle = new FVIL.Data.CFviAngle(270.0); param.RangeAngle = new FVIL.Data.CFviAngle(360.0); // 5-2) 出力画像の有効化. parser.Validate(1); // 有効化. // 6) 画像処理実行. parser.Execute(); // E) 処処理結果画像の保存. FVIL.File.Function.SaveImageFile(Defs.ResultDir + "/PolarTrans.PolarTrans.png", dst); } } } |
Visual Basic | Copy |
---|---|
' $Revision: 1.1 $ Imports System.Collections.Generic Imports System.Text Imports System.Drawing Imports fvalgcli ' FvPluginXXXX attribute requires fvalgcli Namespace SampleCode Public Partial Class PolarTrans ' ============================================================ ''' <summary> ''' 極座標変換クラス. ''' </summary> <FvPluginExecute> _ Public Sub PolarTransClass() ' 1) インスタンスの準備. Dim parser As New FVIL.PolarTrans.CFviPolarTrans() Dim src As New FVIL.Data.CFviImage() Dim dst As New FVIL.Data.CFviImage() ' 2) 処理対象画像の取り込み. FVIL.File.[Function].LoadImageFile(Defs.TestImageDir & "/disk_left.png", src, FVIL.PixelMode.Unpacking) ' 3) 処理対象画像の有効性検査. Dim valid As Integer = FVIL.PolarTrans.CFviPolarTrans.CheckValidity(src) If valid <> FVIL.ErrorCode._SUCCESS Then Throw New FVIL.CFviException(valid, "FVIL.PolarTrans.CFviPolarTrans.CheckValidity") End If ' 4) 画像処理準備 (共通) parser.SrcImages(0) = src parser.DstImages(0) = dst ' 5) パラメータ設定. parser.Invert = False ' false: 矩形→円形. parser.ClearBackMode = True parser.SamplingMode = FVIL.PolarTrans.SamplingMode.Bilinear parser.Param.CoordinateMode = FVIL.PolarTrans.CoordinateMode.Left Dim param As FVIL.PolarTrans.CFviPolarTransParam = parser.Param param.CoordinateMode = FVIL.PolarTrans.CoordinateMode.Left param.OriginIn = New FVIL.Data.CFviPoint(src.Window.X, src.Window.Y) param.Width = src.Window.Width param.Height = src.Window.Height param.OriginOut = New FVIL.Data.CFviPoint(param.Width, param.Width) param.Radius = param.Width param.StartAngle = New FVIL.Data.CFviAngle(270.0) param.RangeAngle = New FVIL.Data.CFviAngle(360.0) ' 5-2) 出力画像の有効化. parser.Validate(1) ' 有効化. ' 6) 画像処理実行. parser.Execute() ' E) 処処理結果画像の保存. FVIL.File.[Function].SaveImageFile(Defs.ResultDir & "/PolarTrans.PolarTrans.png", dst) End Sub End Class End Namespace |
サンプルコード (逆変換):
逆変換の処理例:
CD−ROMの中心に円形状に刻印された文字を直線状に変換する処理例を示します。
変換を行う前に処理対象(円形)の中心位置を取得する必要があります。
ここでは、円ハフ検出 を用いています。
極座標変換の逆変換処理については、ソースコード(1) をご参照ください。
円ハフ検出による中心位置の取得処理については、ソースコード(2)をご参照ください。
【入力画像】
【中心位置】
【出力画像】
ソースコード(1): 円形から矩形への逆変換
C# | Copy |
---|---|
// $Revision: 1.3 $ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using fvalgcli; // FvPluginXXXX attribute requires fvalgcli namespace User.SampleCode { public partial class PolarTrans { // ============================================================ /// <summary> /// 極座標変換クラス. /// </summary> [FvPluginExecute] public void PolarTransInvert() { // 1) インスタンスの準備. FVIL.PolarTrans.CFviPolarTrans parser = new FVIL.PolarTrans.CFviPolarTrans(); FVIL.Data.CFviImage src = new FVIL.Data.CFviImage(); FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage(); // 2) 処理対象画像の取り込み. FVIL.File.Function.LoadImageFile(Defs.TestImageDir + "/disk_cd_01.png", src, FVIL.PixelMode.Unpacking); // 3) 処理対象画像の有効性検査. if( FVIL.ErrorCode._SUCCESS != FVIL.PolarTrans.CFviPolarTrans.CheckValidity( src ) ) return; // 4) 画像処理準備. parser.SrcImages[0] = src; parser.DstImages[0] = dst; // 5-1) パラメータ設定. parser.Invert = true; // true: 円形→矩形. parser.ClearBackMode = true; parser.SamplingMode = FVIL.PolarTrans.SamplingMode.NearestNeighbor; // --- 円形領域の中心位置の取得. double target = 91/2.0; // 目標の円半径 (画像によって調整が必要) double tie = 24; // 目標の円の帯幅 (画像によって調整が必要) FVIL.Data.CFviPoint center = new FVIL.Data.CFviPoint(); // 検出した円中心. double radius; // 変換する円半径. try { center = get_center( src, target-(tie/4.0), target+(tie/4.0) ); radius = (center.X<center.Y) ? center.X : center.Y; } catch( FVIL.CFviException ex ) { throw new FVIL.CFviException(ex.ErrorCode, "get_center", "Failed to get a center point of circle."); } // --- パラメータ構造クラス. FVIL.PolarTrans.CFviPolarTransParam param = parser.Param; param.CoordinateMode = FVIL.PolarTrans.CoordinateMode.Lower; // --- 入力: 円形領域の設定. param.OriginOut = center; param.Radius = radius; param.StartAngle = new FVIL.Data.CFviAngle(235.0); // (!) 画像によって調整が必要. param.RangeAngle = new FVIL.Data.CFviAngle(360.0); // --- 出力: 矩形領域の設定. param.OriginIn = new FVIL.Data.CFviPoint(0,radius-1); param.Width = 2 * FVIL.Math.Pi * (target+(tie/2.0)); // 目標の円の円周よりやや外側. param.Height = radius; // 5-2) 出力画像の有効化. parser.Validate(1); // 有効化. // 6) 画像処理実行. parser.Execute(); // E) 処理結果画像の保存. FVIL.File.Function.SaveImageFile(Defs.ResultDir + "/PolarTrans.PolarTransInvert.png", dst); } } } |
Visual Basic | Copy |
---|---|
' $Revision: 1.1 $ Imports System.Collections.Generic Imports System.Text Imports System.Drawing Imports fvalgcli ' FvPluginXXXX attribute requires fvalgcli Namespace SampleCode Public Partial Class PolarTrans ' ============================================================ ''' <summary> ''' 極座標変換クラス. ''' </summary> <FvPluginExecute> _ Public Sub PolarTransInvert() ' 1) インスタンスの準備. Dim parser As New FVIL.PolarTrans.CFviPolarTrans() Dim src As New FVIL.Data.CFviImage() Dim dst As New FVIL.Data.CFviImage() ' 2) 処理対象画像の取り込み. FVIL.File.[Function].LoadImageFile(Defs.TestImageDir & "/disk_cd_01.png", src, FVIL.PixelMode.Unpacking) ' 3) 処理対象画像の有効性検査. If FVIL.ErrorCode._SUCCESS <> FVIL.PolarTrans.CFviPolarTrans.CheckValidity(src) Then Return End If ' 4) 画像処理準備. parser.SrcImages(0) = src parser.DstImages(0) = dst ' 5-1) パラメータ設定. parser.Invert = True ' true: 円形→矩形. parser.ClearBackMode = True parser.SamplingMode = FVIL.PolarTrans.SamplingMode.NearestNeighbor ' --- 円形領域の中心位置の取得. Dim target As Double = 91 / 2.0 ' 目標の円半径 (画像によって調整が必要) Dim tie As Double = 24 ' 目標の円の帯幅 (画像によって調整が必要) Dim center As New FVIL.Data.CFviPoint() ' 検出した円中心. Dim radius As Double ' 変換する円半径. Try center = get_center(src, target - (tie / 4.0), target + (tie / 4.0)) radius = If((center.X < center.Y), center.X, center.Y) Catch ex As FVIL.CFviException Throw New FVIL.CFviException(ex.ErrorCode, "get_center", "Failed to get a center point of circle.") End Try ' --- パラメータ構造クラス. Dim param As FVIL.PolarTrans.CFviPolarTransParam = parser.Param param.CoordinateMode = FVIL.PolarTrans.CoordinateMode.Lower ' --- 入力: 円形領域の設定. param.OriginOut = center param.Radius = radius param.StartAngle = New FVIL.Data.CFviAngle(235.0) ' (!) 画像によって調整が必要. param.RangeAngle = New FVIL.Data.CFviAngle(360.0) ' --- 出力: 矩形領域の設定. param.OriginIn = New FVIL.Data.CFviPoint(0, radius - 1) param.Width = 2 * FVIL.Math.Pi * (target + (tie / 2.0)) ' 目標の円の円周よりやや外側. param.Height = radius ' 5-2) 出力画像の有効化. parser.Validate(1) ' 有効化. ' 6) 画像処理実行. parser.Execute() ' E) 処理結果画像の保存. FVIL.File.[Function].SaveImageFile(Defs.ResultDir & "/PolarTrans.PolarTransInvert.png", dst) End Sub End Class End Namespace |
ソースコード(2): 円ハフ検出による中心位置の取得
C# | Copy |
---|---|
// $Revision: 1.2 $ using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace User.SampleCode { public partial class PolarTrans { // ============================================================ /// <summary> /// ディスクの中心座標の取得. /// </summary> internal FVIL.Data.CFviPoint get_center(FVIL.Data.CFviImage image, double radius_min, double radius_max) { FVIL.Data.CFviPoint center = new FVIL.Data.CFviPoint(0,0); // -) 有効性の検査. int valid = FVIL.Hough.CFviCircleHoughSobelEdge.CheckValidity(image); if( valid != FVIL.ErrorCode._SUCCESS ) throw new FVIL.CFviException(valid,"FVIL.Hough.CFviCircleHoughSobelEdge.CheckValidity"); // -) インスタンスの準備. FVIL.Hough.CFviCircleHoughSobelEdge parser = new FVIL.Hough.CFviCircleHoughSobelEdge(); // -) 画像処理準備. parser.SrcImages[0] = image; // -) パラメータ設定 (本体) FVIL.Hough.CFviCircleHoughParam param = parser.Param; param.Resolution = 1.0; param.RadiusMin = radius_min; param.RadiusMax = radius_max; param.QRange = 30; param.EdgePercent = 20; param.MinScore = 8; param.ObjectColor = FVIL.Hough.ObjectColor.BlackOrWhite; param.MergeCenter = 2; param.MergeRadius = 1; // -) パラメータ設定 (エッジ検出部分) FVIL.Edge.CFviEdge2DSobelParam param_edge = parser.ParamEdge; param_edge.EdgeThreshold = 120; param_edge.NmsLength = 1; // -) 画像処理実行. parser.Execute(); // -) スコア最大値の円を取得. FVIL.Data.CFviCircle max_circle = new FVIL.Data.CFviCircle(); int max_score = 0; for(int i = 0; i < parser.Result.Count; i++ ) { FVIL.Hough.CFviCircleHoughData data = parser.Result[i]; if( max_score < data.Score ) { max_score = data.Score; max_circle.Center = data.Center; max_circle.Radius = data.Radius; } } center = max_circle.Center; // E) 確認用. { // 画像表示の準備. FVIL.GDI.CFviDisplay display = new FVIL.GDI.CFviDisplay(); display.Image = image; display.DisplayRect = image.Window; // オーバレイの生成. FVIL.GDI.CFviOverlay pOverlay0 = new FVIL.GDI.CFviOverlay(); pOverlay0.Scaling = true; display.Overlays.Add(pOverlay0); // 描画図形の生成と追加. // --- 円データ生成. FVIL.GDI.CFviGdiCircle circle = new FVIL.GDI.CFviGdiCircle(max_circle); circle.Pen.Color = System.Drawing.Color.Red; FVIL.GDI.CFviGdiPoint point = new FVIL.GDI.CFviGdiPoint(circle.Center); point.Pen.Color = System.Drawing.Color.Red; point.Style = FVIL.GDI.FigureStyle.Cross; point.Size = new System.Drawing.Size( 10, 10 ); // --- オーバレイへ追加. pOverlay0.Figures.Add( circle ); pOverlay0.Figures.Add( point ); // 画像保存. FVIL.Data.CFviImage canvas = new FVIL.Data.CFviImage(); display.SaveImage( canvas, display.DisplayRect, 1.0 ); FVIL.File.Function.SaveImageFile(Defs.ResultDir + "/PolarTrans.get_center.png", canvas); } return center; } } } |
Visual Basic | Copy |
---|---|
' $Revision: 1.1 $ Imports System.Collections.Generic Imports System.Text Imports System.Drawing Namespace SampleCode Public Partial Class PolarTrans ' ============================================================ ''' <summary> ''' ディスクの中心座標の取得. ''' </summary> Friend Function get_center(image As FVIL.Data.CFviImage, radius_min As Double, radius_max As Double) As FVIL.Data.CFviPoint Dim center As New FVIL.Data.CFviPoint(0, 0) ' -) 有効性の検査. Dim valid As Integer = FVIL.Hough.CFviCircleHoughSobelEdge.CheckValidity(image) If valid <> FVIL.ErrorCode._SUCCESS Then Throw New FVIL.CFviException(valid, "FVIL.Hough.CFviCircleHoughSobelEdge.CheckValidity") End If ' -) インスタンスの準備. Dim parser As New FVIL.Hough.CFviCircleHoughSobelEdge() ' -) 画像処理準備. parser.SrcImages(0) = image ' -) パラメータ設定 (本体) Dim param As FVIL.Hough.CFviCircleHoughParam = parser.Param param.Resolution = 1.0 param.RadiusMin = radius_min param.RadiusMax = radius_max param.QRange = 30 param.EdgePercent = 20 param.MinScore = 8 param.ObjectColor = FVIL.Hough.ObjectColor.BlackOrWhite param.MergeCenter = 2 param.MergeRadius = 1 ' -) パラメータ設定 (エッジ検出部分) Dim param_edge As FVIL.Edge.CFviEdge2DSobelParam = parser.ParamEdge param_edge.EdgeThreshold = 120 param_edge.NmsLength = 1 ' -) 画像処理実行. parser.Execute() ' -) スコア最大値の円を取得. Dim max_circle As New FVIL.Data.CFviCircle() Dim max_score As Integer = 0 For i As Integer = 0 To parser.Result.Count - 1 Dim data As FVIL.Hough.CFviCircleHoughData = parser.Result(i) If max_score < data.Score Then max_score = data.Score max_circle.Center = data.Center max_circle.Radius = data.Radius End If Next center = max_circle.Center ' E) 確認用. If True Then ' 画像表示の準備. Dim display As New FVIL.GDI.CFviDisplay() display.Image = image display.DisplayRect = image.Window ' オーバレイの生成. Dim pOverlay0 As New FVIL.GDI.CFviOverlay() pOverlay0.Scaling = True display.Overlays.Add(pOverlay0) ' 描画図形の生成と追加. ' --- 円データ生成. Dim circle As New FVIL.GDI.CFviGdiCircle(max_circle) circle.Pen.Color = System.Drawing.Color.Red Dim point As New FVIL.GDI.CFviGdiPoint(circle.Center) point.Pen.Color = System.Drawing.Color.Red point.Style = FVIL.GDI.FigureStyle.Cross point.Size = New System.Drawing.Size(10, 10) ' --- オーバレイへ追加. pOverlay0.Figures.Add(circle) pOverlay0.Figures.Add(point) ' 画像保存. Dim canvas As New FVIL.Data.CFviImage() display.SaveImage(canvas, display.DisplayRect, 1.0) FVIL.File.[Function].SaveImageFile(Defs.ResultDir & "/PolarTrans.get_center.png", canvas) End If Return center End Function End Class End Namespace |