射影変換の変換行列を計算

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

Syntax

C#
public static int fnFIE_geotrans_estimate_perspective_matrix(
	FMATRIX_PTR fpMat,
	DPNT_T_PTR pntspFrom,
	DPNT_T_PTR pntspTo,
	uint uiNum
)
Visual Basic
Public Shared Function fnFIE_geotrans_estimate_perspective_matrix ( 
	fpMat As FMATRIX_PTR,
	pntspFrom As DPNT_T_PTR,
	pntspTo As DPNT_T_PTR,
	uiNum As UInteger
) As Integer

Parameters

fpMat
Type: fvalgcli..::..FMATRIX_PTR
求められた射影変換の変換行列
pntspFrom
Type: fvalgcli..::..DPNT_T_PTR
射影変換前の点の座標列 (同一直線上にない4点以上の座標)
pntspTo
Type: fvalgcli..::..DPNT_T_PTR
射影変換後の点の座標列
uiNum
Type: System..::..UInt32
pntspFrom/pntspTo の点数

Return Value

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

エラーコード:
f_err内容
F_ERR_NONE正常終了
F_ERR_NOMEMORYメモリ不足エラー
F_ERR_INVALID_PARAMパラメータ異常
  • fpMat , pntspFrom , または pntspTo が IntPtr.Zero
  • 点数が4点未満、または1073741824点(2^30点)以上
F_ERR_INVALID_OBJECTfpMat が3×3の行列ではない
F_ERR_CALC_IMPOSSIBLE計算不能で異常終了
  • 関数 DGELSD 中の計算が収束できない
  • 入力点列によって作った座標行列のランクが 8未満のため、計算できない
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
    {
        /// <summary>
        /// 射影変換の変換行列の計算.
        /// </summary>
        [FvPluginExecute]
        public void fnFIE_geotrans_estimate_perspective_matrix()
        {
            int status = (int)f_err.F_ERR_NONE;

            FMATRIX_PTR fpMat = IntPtr.Zero;        // 求められた射影変換の変換行列.
            DPNT_T_PTR pntspFrom = IntPtr.Zero;    // 射影変換前の点の座標列.
            DPNT_T_PTR pntspTo = IntPtr.Zero;    // 射影変換後の点の座標列.
            uint uiNum = 0;                        // pntspFrom/pntspTo の点数.
            const int size = 256;
            const int div = size / 8;

            try
            {
                // 射影変換前後の点の座標列の確保と値の設定.
                uiNum = 4;
                pntspFrom = DPNT_T_PTR.alloc((int)uiNum);
                pntspTo = DPNT_T_PTR.alloc((int)uiNum);

                pntspFrom[0] = DPNT_T.init(0, 0);
                pntspFrom[1] = DPNT_T.init(size - 1, 0);
                pntspFrom[2] = DPNT_T.init(0, size - 1);
                pntspFrom[3] = DPNT_T.init(size - 1, size - 1);

                pntspTo[0] = DPNT_T.init(div, div * 2);
                pntspTo[1] = DPNT_T.init(size - 1 - div, div);
                pntspTo[2] = DPNT_T.init(div, size - 1 - div * 2);
                pntspTo[3] = DPNT_T.init(size - 1 - div, size - 1 - div);

                // 変換行列の確保.
                fpMat = api.fnFIE_mat_aalloc(3, 3);

                // 処理の実行.
                status = api.fnFIE_geotrans_estimate_perspective_matrix(fpMat, pntspFrom, pntspTo, uiNum);

                // エラー判定.
                Assert.IsTrue(status == (int)f_err.F_ERR_NONE, "エラーが発生しました。({0})", (f_err)status);

                // 結果出力.
                ConsoleOut.WriteFunctionName(":\t");
                {
                    // 得られた変換行列による変換前座標の変換結果が、指定した変換後の座標と同じになるか確認.
                    bool check = true;

                    FMATRIX_PTR src_mat = FMATRIX_PTR.Zero;    // 変換前座標
                    FMATRIX_PTR dst_mat = FMATRIX_PTR.Zero;    // 変換後座標

                    try
                    {
                        src_mat = api.fnFIE_mat_aalloc(3, 1);    
                        dst_mat = api.fnFIE_mat_aalloc(3, 1);

                        for (int i = 0; i < uiNum; i++)
                        {

                            src_mat[0, 0] = pntspFrom[i].x;
                            src_mat[1, 0] = pntspFrom[i].y;
                            src_mat[2, 0] = 1;

                            api.fnFIE_mat_mul_aa(fpMat, src_mat, dst_mat);

                            double w = dst_mat[2, 0];
                            double ret_x = dst_mat[0, 0] / w;
                            double ret_y = dst_mat[1, 0] / w;

                            if (!DblEqual(ret_x, pntspTo[i].x) || !DblEqual(ret_y, pntspTo[i].y))
                                check = false;
                        }

                    }
                    finally
                    {
                        src_mat.Dispose();
                        dst_mat.Dispose();
                        ConsoleOut.IsTrue(check);
                    }
                }
                ConsoleOut.WriteFMATRIX(fpMat, 3, 3);

                // 得られた変換行列による射影変換の実行と結果画像の保存.
                {
                    FHANDLE src = FHANDLE.Zero;
                    FHANDLE dst = FHANDLE.Zero;

                    try
                    {
                        src = api.fnFIE_img_root_alloc((int)f_imgtype.F_IMG_UC8, 1, size, size);
                        dst = api.fnFIE_img_root_alloc((int)f_imgtype.F_IMG_UC8, 1, size, size);

                        api.fnFIE_jaehne_testimg(src);
                        api.fnFIE_geotrans_perspective(src, dst, FHANDLE.Zero, fpMat, true, f_sampling_mode.F_SAMPLING_BILINEAR);
                        api.fnFIE_save_png(ResultDir + "/fnFIE_geotrans_estimate_perspective_matrix.png", dst, -1);

                    }
                    finally
                    {
                        src.Dispose();
                        dst.Dispose();
                    }
                }
            }
            finally
            {
                // オブジェクトの開放.
                fpMat.Dispose();
                pntspFrom.Dispose();
                pntspTo.Dispose();
            }
        }
    }
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

Imports System.Collections.Generic
Imports System.Text

Imports fvalgcli

Public Partial Class FIE
    ''' <summary>
    ''' 射影変換の変換行列の計算.
    ''' </summary>
    <FvPluginExecute> _
    Public Sub fnFIE_geotrans_estimate_perspective_matrix()
        Dim status As Integer = CInt(f_err.F_ERR_NONE)

        Dim fpMat As FMATRIX_PTR = IntPtr.Zero
        ' 求められた射影変換の変換行列.
        Dim pntspFrom As DPNT_T_PTR = IntPtr.Zero
        ' 射影変換前の点の座標列.
        Dim pntspTo As DPNT_T_PTR = IntPtr.Zero
        ' 射影変換後の点の座標列.
        Dim uiNum As UInteger = 0
        ' pntspFrom/pntspTo の点数.
        Const  size As Integer = 256
        Const  div As Integer = size \ 8

        Try
            ' 射影変換前後の点の座標列の確保と値の設定.
            uiNum = 4
            pntspFrom = DPNT_T_PTR.alloc(CInt(uiNum))
            pntspTo = DPNT_T_PTR.alloc(CInt(uiNum))

            pntspFrom(0) = DPNT_T.init(0, 0)
            pntspFrom(1) = DPNT_T.init(size - 1, 0)
            pntspFrom(2) = DPNT_T.init(0, size - 1)
            pntspFrom(3) = DPNT_T.init(size - 1, size - 1)

            pntspTo(0) = DPNT_T.init(div, div * 2)
            pntspTo(1) = DPNT_T.init(size - 1 - div, div)
            pntspTo(2) = DPNT_T.init(div, size - 1 - div * 2)
            pntspTo(3) = DPNT_T.init(size - 1 - div, size - 1 - div)

            ' 変換行列の確保.
            fpMat = api.fnFIE_mat_aalloc(3, 3)

            ' 処理の実行.
            status = api.fnFIE_geotrans_estimate_perspective_matrix(fpMat, pntspFrom, pntspTo, uiNum)

            ' エラー判定.
            Assert.IsTrue(status = CInt(f_err.F_ERR_NONE), "エラーが発生しました。({0})", CType(status, f_err))

            ' 結果出力.
            ConsoleOut.WriteFunctionName(":" & vbTab)
            If True Then
                ' 得られた変換行列による変換前座標の変換結果が、指定した変換後の座標と同じになるか確認.
                Dim check As Boolean = True

                Dim src_mat As FMATRIX_PTR = FMATRIX_PTR.Zero
                ' 変換前座標
                Dim dst_mat As FMATRIX_PTR = FMATRIX_PTR.Zero
                ' 変換後座標
                Try
                    src_mat = api.fnFIE_mat_aalloc(3, 1)
                    dst_mat = api.fnFIE_mat_aalloc(3, 1)

                    For i As Integer = 0 To CType(uiNum, Integer) - 1

                        src_mat(0, 0) = pntspFrom(i).x
                        src_mat(1, 0) = pntspFrom(i).y
                        src_mat(2, 0) = 1

                        api.fnFIE_mat_mul_aa(fpMat, src_mat, dst_mat)

                        Dim w As Double = dst_mat(2, 0)
                        Dim ret_x As Double = dst_mat(0, 0) / w
                        Dim ret_y As Double = dst_mat(1, 0) / w

                        If Not DblEqual(ret_x, pntspTo(i).x) OrElse Not DblEqual(ret_y, pntspTo(i).y) Then
                            check = False
                        End If

                    Next
                Finally
                    src_mat.Dispose()
                    dst_mat.Dispose()
                    ConsoleOut.IsTrue(check)
                End Try
            End If
            ConsoleOut.WriteFMATRIX(fpMat, 3, 3)

            ' 得られた変換行列による射影変換の実行と結果画像の保存.
            If True Then
                Dim src As FHANDLE = FHANDLE.Zero
                Dim dst As FHANDLE = FHANDLE.Zero

                Try
                    src = api.fnFIE_img_root_alloc(CInt(f_imgtype.F_IMG_UC8), 1, size, size)
                    dst = api.fnFIE_img_root_alloc(CInt(f_imgtype.F_IMG_UC8), 1, size, size)

                    api.fnFIE_jaehne_testimg(src)
                    api.fnFIE_geotrans_perspective(src, dst, FHANDLE.Zero, fpMat, True, f_sampling_mode.F_SAMPLING_BILINEAR)

                    api.fnFIE_save_png(ResultDir & "/fnFIE_geotrans_estimate_perspective_matrix.png", dst, -1)
                Finally
                    src.Dispose()
                    dst.Dispose()
                End Try
            End If
        Finally
            ' オブジェクトの開放.
            fpMat.Dispose()
            pntspFrom.Dispose()
            pntspTo.Dispose()
        End Try
    End Sub
End Class

See Also