点群からの楕円近似

Namespace: fvalgcli
Assembly: fvalgcli (in fvalgcli.dll) Version: 3.1.0.0 (3.1.0.11)

Syntax

C#
public static int fnFIE_fit_ellipse(
	DPNT_T_PTR pnts,
	int pnt_num,
	f_fit_mode fitting_mode,
	double param,
	ref DPNT_T center,
	ref double major,
	ref double minor,
	ref double theta
)
Visual Basic
Public Shared Function fnFIE_fit_ellipse ( 
	pnts As DPNT_T_PTR,
	pnt_num As Integer,
	fitting_mode As f_fit_mode,
	param As Double,
	ByRef center As DPNT_T,
	ByRef major As Double,
	ByRef minor As Double,
	ByRef theta As Double
) As Integer

Parameters

pnts
Type: fvalgcli..::..DPNT_T_PTR
入力点群
pnt_num
Type: System..::..Int32
入力点群の個数( pnt_num ≧ 5 )
fitting_mode
Type: fvalgcli..::..f_fit_mode
近似モード
  • F_FIT_LSM :最小二乗法
  • F_FIT_MESTIMATOR :ロバスト推定法(M推定法)
  • F_FIT_RANSAC :ロバスト推定法(ランザック法)
  • F_FIT_LMEDS :ロバスト推定法(最小メディアン法)
  • F_FIT_MESTIMATOR2 :ロバスト推定法(M推定法)...標準偏差を自動決定
  • F_FIT_LMEDS2 :ロバスト推定法(最小メディアン法)...標準偏差を自動決定
param
Type: System..::..Double
最適化パラメータ(ロバスト推定法で利用)
center
Type: fvalgcli..::..DPNT_T%
楕円の中心点
major
Type: System..::..Double%
楕円の主軸半径
minor
Type: System..::..Double%
楕円の副軸半径
theta
Type: System..::..Double%
楕円の主軸角度( -PI / 2 ≦ theta ≦ +PI / 2 )

Return Value

Type: Int32
以下のエラーコードを返します。

エラーコード:
f_err内容
F_ERR_NONE正常終了
F_ERR_NOMEMORYメモリ不足エラー
F_ERR_CALC_IMPOSSIBLE計算不可
F_ERR_INVALID_PARAMパラメータ異常
F_ERR_NO_LICENCEライセンスエラー、または未初期化エラー

Examples

C# Copy imageCopy
//    $Revision: 1.1 $

using System;
using System.Collections.Generic;
using System.Text;
using fvalgcli;

namespace TC
{
    public partial class FIE
    {
        [FvPluginExecute]
        public void fnFIE_fit_ellipse()
        {
            int status = (int)f_err.F_ERR_NONE;

            // 定数.
            const int WIDTH = 256;        // 出力画像の幅.
            const int HEIGHT = 256;        // 出力画像の高さ.
            const int PNTS_NUM = 64;    // 入力点数.
            const double PER = 0.75;        // 円周の何%に点群を配置するか(1で全周).

            // ルート画像.
            FHANDLE hdst = FHANDLE.Zero;    // 結果画像.

            DOUBLE_PTR val = DOUBLE_PTR.Zero;    // 画像に描画する際の濃度値.

            F_RANDDESC  r = new F_RANDDESC();    // 擬似乱数列生成用データ.
            uint seed = 777;                    // 乱数因子(適当な値).
            double random;                        // 乱数.

            // 近似楕円生成パラメータ.
            DPNT_T f_center = new DPNT_T();        // 近似円の中心座標.
            double f_major = 0;                    // 長軸.
            double f_minor = 0;                    // 短軸.
            double f_theta = 0;                    // 回転角.

            // 点列の作成.
            DPNT_T_PTR pnts = DPNT_T_PTR.Zero;

            // 楕円のノイズ付加点群生成パラメータ.
            double major = 100;            // 長軸.
            double minor = 80;            // 短軸.
            double radian = Math.PI;    // 角度.
            DPNT_T center;                // 中心座標.

            center.x = WIDTH / 2;     // 画像中心X座標.
            center.y = HEIGHT / 2;    // 画像中心Y座標.

            try
            {
                // 点列描画用変数初期化.
                val = DOUBLE_PTR.alloc(3);

                // 乱数生成子の初期化.
                api.fnFIE_mtrand_init(seed, ref r);

                // 点列領域確保.
                pnts = DPNT_T_PTR.alloc(PNTS_NUM);

                // 出力画像の領域を確保します.
                hdst = api.fnFIE_img_root_alloc( (int)f_imgtype.F_IMG_UC8, 3, WIDTH, HEIGHT );

                // 出力画像を白色(255)で塗りつぶす.
                api.fnFIE_img_clear(hdst, 255);

                // 濃度値の設定.
                val[0] = 0;        //R.
                val[1] = 0;        //G.
                val[2] = 0;        //B.

                // 入力点列の生成.
                for(int i = 0; i < PNTS_NUM; i++)
                {
                    // 角度.
                    radian += ((2 * Math.PI) * (PER)) / PNTS_NUM;

                    // 初期座標.
                    pnts[i] = DPNT_T.init(center.x + (major * Math.Cos(radian)), center.y + (minor * Math.Sin(radian)));

                    // 乱数の生成.
                    random = api.fnFIE_mtrand_real2(ref r);

                    // 乱数を付加.
                    pnts[i] = DPNT_T.init( pnts[i].x + 10 * (random - 0.5) , pnts[i].y + 10 * (random - 0.5) );

                    // 点列を描画する(点描画では小さいので,円で描画).
                    api.fnFIE_draw_circle(hdst, val, f_draw_fill_mode.F_DRAW_FILL_IN, pnts[i], 1);
                }

                // 近似楕円の計算(最小二乗法).
                status = api.fnFIE_fit_ellipse(pnts, PNTS_NUM, f_fit_mode.F_FIT_LSM, 0, ref f_center, ref f_major, ref f_minor, ref f_theta);
                Assert.IsTrue(status == (int)f_err.F_ERR_NONE, "エラーが発生しました。({0})", (f_err)status);

                // 近似楕円を描画する.
                val[0] = 255;    //R
                api.fnFIE_draw_ellipse(hdst, val, f_draw_fill_mode.F_DRAW_LINE, f_center, f_major, f_minor, f_theta);

                // 画像をPNG形式で保存する.
                api.fnFIE_save_png(ResultDir + "/fnFIE_fit_ellipse.png", hdst, -1);

                // 結果を出力する.
                ConsoleOut.WriteFunctionName(":\t");
                Console.Write(" ...");
                ConsoleOut.IsTrue(hdst != FHANDLE.Zero);
            }
            finally
            {
                // 解放.
                val.Dispose();
                hdst.Dispose();
                pnts.Dispose();
            }
        }
    }
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

Imports System.Collections.Generic
Imports System.Text
Imports fvalgcli

Public Partial Class FIE
    <FvPluginExecute> _
    Public Sub fnFIE_fit_ellipse()
        Dim status As Integer = CInt(f_err.F_ERR_NONE)

        ' 定数.
        Const  WIDTH As Integer = 256
        ' 出力画像の幅.
        Const  HEIGHT As Integer = 256
        ' 出力画像の高さ.
        Const  PNTS_NUM As Integer = 64
        ' 入力点数.
        Const  PER As Double = 0.75
        ' 円周の何%に点群を配置するか(1で全周).
        ' ルート画像.
        Dim hdst As FHANDLE = FHANDLE.Zero
        ' 結果画像.
        Dim val As DOUBLE_PTR = DOUBLE_PTR.Zero
        ' 画像に描画する際の濃度値.
        Dim r As New F_RANDDESC()
        ' 擬似乱数列生成用データ.
        Dim seed As UInteger = 777
        ' 乱数因子(適当な値).
        Dim random As Double
        ' 乱数.
        ' 近似楕円生成パラメータ.
        Dim f_center As New DPNT_T()
        ' 近似円の中心座標.
        Dim f_major As Double = 0
        ' 長軸.
        Dim f_minor As Double = 0
        ' 短軸.
        Dim f_theta As Double = 0
        ' 回転角.
        ' 点列の作成.
        Dim pnts As DPNT_T_PTR = DPNT_T_PTR.Zero

        ' 楕円のノイズ付加点群生成パラメータ.
        Dim major As Double = 100
        ' 長軸.
        Dim minor As Double = 80
        ' 短軸.
        Dim radian As Double = Math.PI
        ' 角度.
        Dim center As DPNT_T
        ' 中心座標.
        center.x = WIDTH \ 2
        ' 画像中心X座標.
        center.y = HEIGHT \ 2
        ' 画像中心Y座標.
        Try
            ' 点列描画用変数初期化.
            val = DOUBLE_PTR.alloc(3)

            ' 乱数生成子の初期化.
            api.fnFIE_mtrand_init(seed, r)

            ' 点列領域確保.
            pnts = DPNT_T_PTR.alloc(PNTS_NUM)

            ' 出力画像の領域を確保します.
            hdst = api.fnFIE_img_root_alloc(CInt(f_imgtype.F_IMG_UC8), 3, WIDTH, HEIGHT)

            ' 出力画像を白色(255)で塗りつぶす.
            api.fnFIE_img_clear(hdst, 255)

            ' 濃度値の設定.
            val(0) = 0
            'R.
            val(1) = 0
            'G.
            val(2) = 0
            'B.
            ' 入力点列の生成.
            For i As Integer = 0 To PNTS_NUM - 1
                ' 角度.
                radian += ((2 * Math.PI) * (PER)) / PNTS_NUM

                ' 初期座標.
                pnts(i) = DPNT_T.init(center.x + (major * Math.Cos(radian)), center.y + (minor * Math.Sin(radian)))

                ' 乱数の生成.
                random = api.fnFIE_mtrand_real2(r)

                ' 乱数を付加.
                pnts(i) = DPNT_T.init(pnts(i).x + 10 * (random - 0.5), pnts(i).y + 10 * (random - 0.5))

                ' 点列を描画する(点描画では小さいので,円で描画).
                api.fnFIE_draw_circle(hdst, val, f_draw_fill_mode.F_DRAW_FILL_IN, pnts(i), 1)
            Next

            ' 近似楕円の計算(最小二乗法).
            status = api.fnFIE_fit_ellipse(pnts, PNTS_NUM, f_fit_mode.F_FIT_LSM, 0, f_center, f_major, _
                f_minor, f_theta)
            Assert.IsTrue(status = CInt(f_err.F_ERR_NONE), "エラーが発生しました。({0})", CType(status, f_err))

            ' 近似楕円を描画する.
            val(0) = 255
            'R
            api.fnFIE_draw_ellipse(hdst, val, f_draw_fill_mode.F_DRAW_LINE, f_center, f_major, f_minor, _
                f_theta)

            ' 画像をPNG形式で保存する.
            api.fnFIE_save_png(ResultDir & "/fnFIE_fit_ellipse.png", hdst, -1)

            ' 結果を出力する.
            ConsoleOut.WriteFunctionName(":" & vbTab)
            Console.Write(" ...")
            ConsoleOut.IsTrue(hdst <> FHANDLE.Zero)
        Finally
            ' 解放.
            val.Dispose()
            hdst.Dispose()
            pnts.Dispose()
        End Try
    End Sub
End Class

See Also