点群からの直線近似

Namespace: FVIL.CG
Assembly: FVILbasic (in FVILbasic.dll) Version: 3.1.0.0 (3.1.0.17)

Syntax

C#
public static CFviLine FitLine(
	DPNT_T_ARRAY points,
	FitMode fit_mode,
	double param
)
Visual Basic
Public Shared Function FitLine ( 
	points As DPNT_T_ARRAY,
	fit_mode As FitMode,
	param As Double
) As CFviLine

Parameters

points
Type: FVIL..::..DPNT_T_ARRAY
入力点群 (2個以上)
fit_mode
Type: FVIL.CG..::..FitMode
近似モード
param
Type: System..::..Double
最適化パラメータ(ロバスト推定法で利用)

Return Value

Type: CFviLine
算出された直線係数を返します。

Remarks

与えれた座標点群から、最小二乗法または、ロバスト推定法で直線の係数を算出します。


最適化パラメータ:

ロバスト推定法は、標準偏差によりインライアとアウトライアを判定しています。 点群の誤差は正規分布であることを前提として、標準偏差より信頼区間内の点をインライアと判定します。 param は、例外値の影響を軽減するために利用されるパラメータです。 近似モード(fit_mode)によって、パラメータの意味が異なります。
誤差の計算式は、直線の式 ax+by+c=0 で表すと、以下の通りとなります。

なお、得られる直線は、傾きが [ -PI / 4 , PI / 4 ] または、 [ 3PI / 4 , 5PI / 4 ] の場合、 係数 b を 1.0 に正規化します。 それ以外の傾きでは、係数 a を 1.0 に正規化します。


近似モード(fit_mode):
項目説明
ロバスト推定 (M推定法)MESTIMATORparam は 誤差の標準偏差です。 標準偏差より 95% 信頼区間内の点をインライアと判定します。 つまり、 [-1.96σ, 1.96σ] より、95%信頼区間が計算されます。 推定した、対象点群の標準偏差をパラメータとして入力してください。 例えば、以下の信頼区間内の点をインライアとして判定したい場合は、次の係数を入力してください。
  • 90.0%信頼区間内:1.645
  • 95.0%信頼区間内:1.960
  • 99.0%信頼区間内:2.567
  • 99.9%信頼区間内:3.291
ロバスト推定 (ランザック法)RANSAC 同上
ロバスト推定 (最小メディアン法)LMEDSparam は無視されます。 計算結果より自動的に標準偏差を計算します。 標準偏差より95%信頼区間内の点をインライアと判定します。
ロバスト推定 (M推定法)
標準偏差の自動決定
MESTIMATOR2param は 誤差の標準偏差の係数です。 標準偏差は、自動的に計算されます。
ロバスト推定 (最小メディアン法)
標準偏差の自動決定
LMEDS2 同上
最小二乗法LSMparam は無視されます。
最小二乗法 (旧ライブラリ互換)LSM_FASTparam は無視されます。

入力点群の個数制限:

入力点群の個数は、近似モード毎に制限があります。 この制限は、内部計算で行列演算を用いていることに起因します。

項目説明
ロバスト推定 (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 メンバ内容
11FVIL.ErrorCode.INVALID_PARAMETER引数に指定された値が不正です。

関連する FIE 関数:

fnFIE_fit_line

Examples

ソースコード:
C# Copy imageCopy
using System;
using System.Collections.Generic;
using System.Text;
using fvalgcli;

namespace User.SampleCode
{
    public partial class CG
    {
        /// <summary>
        /// 点群からの直線近似.
        /// </summary>
        [FvPluginExecute]
        public void FitLine()
        {
            try
            {
                double a = 1.0;
                double b = 0.5;
                double c = -5.0;
                List<FVIL.Data.CFviPoint> srcData = getPoints_Line(a, b, c);

                // 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.CFviLine line = FVIL.CG.Function.FitLine(points, FVIL.CG.FitMode.MESTIMATOR, 1.645);

                // E) 確認.
                Console.Out.WriteLine("-- Line");
                Console.Out.WriteLine(" Source... a = {0:f}, b = {1:f}, c = {2:f}",
                    a, b, c);
                Console.Out.WriteLine(" Result...  a = {0:f}, b = {1:f}, c = {2:f}",
                    line.a, line.b, line.c);
            }
            catch (FVIL.CFviException ex)
            {
                Assert.Fail("{0}: ErrorCode={1} {2}", ex.Function, ex.ErrorCode, ex.Message);
            }
        }

        /// <summary>
        /// 直線上の点を取得します.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        private List<FVIL.Data.CFviPoint> getPoints_Line(    double a,
                                                            double b,
                                                            double c )
        {
            List<FVIL.Data.CFviPoint> list = new List<FVIL.Data.CFviPoint>(5);

            for (int i = 0; i < 5; i++)
            {
                list.Add(new FVIL.Data.CFviPoint(i, -1 * (a * i + c) / b));
            }

            return list;
        }
    }
}


Visual Basic Copy imageCopy
Imports System.Collections.Generic
Imports System.Text
Imports fvalgcli

Namespace SampleCode
    Public Partial Class CG
        ''' <summary>
        ''' 点群からの直線近似.
        ''' </summary>
        <FvPluginExecute> _
        Public Sub FitLine()
            Try
                Dim a As Double = 1.0
                Dim b As Double = 0.5
                Dim c As Double = -5.0
                Dim srcData As List(Of FVIL.Data.CFviPoint) = getPoints_Line(a, b, c)

                ' 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 line As FVIL.Data.CFviLine = FVIL.CG.[Function].FitLine(points, FVIL.CG.FitMode.MESTIMATOR, 1.645)

                ' E) 確認.
                Console.Out.WriteLine("-- Line")
                Console.Out.WriteLine(" Source... a = {0:f}, b = {1:f}, c = {2:f}", a, b, c)
                Console.Out.WriteLine(" Result...  a = {0:f}, b = {1:f}, c = {2:f}", line.a, line.b, line.c)
            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="a"></param>
        ''' <param name="b"></param>
        ''' <param name="c"></param>
        ''' <returns></returns>
        Private Function getPoints_Line(a As Double, b As Double, c As Double) As List(Of FVIL.Data.CFviPoint)
            Dim list As New List(Of FVIL.Data.CFviPoint)(5)

            For i As Integer = 0 To 4
                list.Add(New FVIL.Data.CFviPoint(i, -1 * (a * i + c) / b))
            Next

            Return list
        End Function
    End Class
End Namespace

Exceptions

ExceptionCondition
FVIL..::..CFviExceptionこの例外の原因については、上記のエラーコード表をご参照ください。

See Also