点群からの楕円近似
Namespace: FVIL.CGAssembly: FVILbasic (in FVILbasic.dll) Version: 3.1.0.0 (3.1.0.17)
Syntax
C# |
---|
public static CFviEllipse FitEllipse( DPNT_T_ARRAY points, FitMode fit_mode, double param ) |
Visual Basic |
---|
Public Shared Function FitEllipse ( points As DPNT_T_ARRAY, fit_mode As FitMode, param As Double ) As CFviEllipse |
Parameters
- points
- Type: FVIL..::..DPNT_T_ARRAY
入力点群 (5個以上)
- fit_mode
- Type: FVIL.CG..::..FitMode
近似モード (※注) LSM_FAST は対応していません。)
- param
- Type: System..::..Double
最適化パラメータ(ロバスト推定法で利用)
Return Value
Type: CFviEllipse算出された楕円を返します。
Remarks
与えれた座標点群から、最小二乗法または、ロバスト推定法で楕円の中心座標、主軸半径、副軸半径、主軸角度を算出します。
最適化パラメータ:
ロバスト推定法は、標準偏差によりインライアとアウトライアを判定しています。
点群の誤差は正規分布であることを前提として、標準偏差より信頼区間内の点をインライアと判定します。
param は、例外値の影響を軽減するために利用されるパラメータです。
近似モード(fit_mode)によって、パラメータの意味が異なります。
誤差の計算式は、楕円を2次曲線の式 で表すと、以下の通りとなります。
近似モード(fit_mode):
項目 | 値 | 説明 |
---|---|---|
ロバスト推定 (M推定法) | MESTIMATOR | param は 誤差の標準偏差です。
標準偏差より 95% 信頼区間内の点をインライアと判定します。
つまり、 [-1.96σ, 1.96σ] より、95%信頼区間が計算されます。
推定した、対象点群の標準偏差をパラメータとして入力してください。
例えば、以下の信頼区間内の点をインライアとして判定したい場合は、次の係数を入力してください。
|
ロバスト推定 (ランザック法) | RANSAC | 同上 |
ロバスト推定 (最小メディアン法) | LMEDS | param は無視されます。 計算結果より自動的に標準偏差を計算します。 標準偏差より95%信頼区間内の点をインライアと判定します。 |
ロバスト推定 (M推定法) 標準偏差の自動決定 | MESTIMATOR2 | param は 誤差の標準偏差の係数です。 標準偏差は、自動的に計算されます。 |
ロバスト推定 (最小メディアン法) 標準偏差の自動決定 | LMEDS2 | 同上 |
最小二乗法 | LSM | param は無視されます。 |
入力点群の個数制限:
入力点群の個数は、近似モード毎に制限があります。 この制限は、内部計算で行列演算を用いていることに起因します。
項目 | 値 | 説明 |
---|---|---|
ロバスト推定 (M推定法) | MESTIMATOR | pnt_num * 6 < 228 |
ロバスト推定 (M推定法) 標準偏差の自動決定 | MESTIMATOR2 | pnt_num * 6 < 228 |
最小二乗法 | LSM | pnt_num * 6 < 228 |
乱数:
fit_mode で、 RANSAC または LMEDS を選択した場合、 fnFIE_mtrand_real2 で発生させた擬似乱数を使用して処理をしています。 擬似乱数の初期化用シードは、現在時刻を取得して、その値にて設定をしています。 そのため、入力データが同じ点群でも、結果が異なることがあります。
処理に失敗した場合は例外を発行します。 例外の原因と発生位置を特定するには、発行された例外クラスの ErrorCode メンバと Function メンバを参照してください。
エラーコード:
値 | ErrorCode メンバ | 内容 |
---|---|---|
11 | FVIL.ErrorCode.INVALID_PARAMETER | 引数に指定された値が不正です。 |
関連する FIE 関数:
fnFIE_fit_ellipse
Examples
ソースコード:
C# | Copy |
---|---|
using System; using System.Collections.Generic; using System.Text; using fvalgcli; namespace User.SampleCode { public partial class CG { /// <summary> /// 点群からの楕円近似. /// </summary> [FvPluginExecute] public void FitEllipse() { try { double center_x = 60.0; double center_y = 70.0; double axis_x = 80.0; double axis_y = 40.0; double degree = 45.0; List<FVIL.Data.CFviPoint> srcData = getPoints_Ellipse(center_x, center_y, axis_x, axis_y, degree); // 0) 入力点群の準備. FVIL.DPNT_T_ARRAY points = new FVIL.DPNT_T_ARRAY(); points.Resize(srcData.Count); fvalgcli.DPNT_T_PTR ptr = points.Address; for (int i = 0; i < points.Count; i++) { ptr[0] = fvalgcli.DPNT_T.init(srcData[i].X, srcData[i].Y); ptr += 1; } // 1) 処理実行. FVIL.Data.CFviEllipse ellipse = FVIL.CG.Function.FitEllipse(points, FVIL.CG.FitMode.MESTIMATOR, 1.645); // E) 確認. Console.Out.WriteLine("-- Ellipse"); Console.Out.WriteLine(" Source... Center = ({0:f},{1:f}), AxisX = {2:f}, AxisY = {3:f} Angle = {4:f}", center_x, center_y, axis_x, axis_y, degree); Console.Out.WriteLine(" Result... Center = ({0:f},{1:f}), AxisX = {2:f}, AxisY = {3:f} Angle = {4:f}", ellipse.Center.X, ellipse.Center.Y, ellipse.AxisX, ellipse.AxisY, ellipse.Angle.Degree ); } catch (FVIL.CFviException ex) { Assert.Fail("{0}: ErrorCode={1} {2}", ex.Function, ex.ErrorCode, ex.Message); } } /// <summary> /// 楕円の外周上の点を取得します. /// </summary> /// <param name="center_x"></param> /// <param name="center_y"></param> /// <param name="axis_x"></param> /// <param name="axis_y"></param> /// <param name="degree"></param> /// <returns></returns> private List<FVIL.Data.CFviPoint> getPoints_Ellipse(double center_x, double center_y, double axis_x, double axis_y, double degree) { FVIL.Data.CFviEllipse src = new FVIL.Data.CFviEllipse(center_x, center_y, axis_x, axis_y, degree); FVIL.Data.CFviPolyline polyline = src.ToCFviPolyline(); return polyline.ToList(); } } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.Text Imports fvalgcli Namespace SampleCode Public Partial Class CG ''' <summary> ''' 点群からの楕円近似. ''' </summary> <FvPluginExecute> _ Public Sub FitEllipse() Try Dim center_x As Double = 60.0 Dim center_y As Double = 70.0 Dim axis_x As Double = 80.0 Dim axis_y As Double = 40.0 Dim degree As Double = 45.0 Dim srcData As List(Of FVIL.Data.CFviPoint) = getPoints_Ellipse(center_x, center_y, axis_x, axis_y, degree) ' 0) 入力点群の準備. Dim points As New FVIL.DPNT_T_ARRAY() points.Resize(srcData.Count) Dim ptr As fvalgcli.DPNT_T_PTR = points.Address For i As Integer = 0 To points.Count - 1 ptr(0) = fvalgcli.DPNT_T.init(srcData(i).X, srcData(i).Y) ptr += 1 Next ' 1) 処理実行. Dim ellipse As FVIL.Data.CFviEllipse = FVIL.CG.[Function].FitEllipse(points, FVIL.CG.FitMode.MESTIMATOR, 1.645) ' E) 確認. Console.Out.WriteLine("-- Ellipse") Console.Out.WriteLine(" Source... Center = ({0:f},{1:f}), AxisX = {2:f}, AxisY = {3:f} Angle = {4:f}", center_x, center_y, axis_x, axis_y, degree) Console.Out.WriteLine(" Result... Center = ({0:f},{1:f}), AxisX = {2:f}, AxisY = {3:f} Angle = {4:f}", ellipse.Center.X, ellipse.Center.Y, ellipse.AxisX, ellipse.AxisY, ellipse.Angle.Degree) Catch ex As FVIL.CFviException Assert.Fail("{0}: ErrorCode={1} {2}", ex.[Function], ex.ErrorCode, ex.Message) End Try End Sub ''' <summary> ''' 楕円の外周上の点を取得します. ''' </summary> ''' <param name="center_x"></param> ''' <param name="center_y"></param> ''' <param name="axis_x"></param> ''' <param name="axis_y"></param> ''' <param name="degree"></param> ''' <returns></returns> Private Function getPoints_Ellipse(center_x As Double, center_y As Double, axis_x As Double, axis_y As Double, degree As Double) As List(Of FVIL.Data.CFviPoint) Dim src As New FVIL.Data.CFviEllipse(center_x, center_y, axis_x, axis_y, degree) Dim polyline As FVIL.Data.CFviPolyline = src.ToCFviPolyline() Return polyline.ToList() End Function End Class End Namespace |
Exceptions
Exception | Condition |
---|---|
FVIL..::..CFviException | この例外の原因については、上記のエラーコード表をご参照ください。 |