======== 線形代数 ======== .. highlight:: cpp 行列要素の四則演算を行う ======================== サイズや要素の型が異なる配列の場合,要素同士の演算はできません. 例外発生時のメッセージは,OpenCV のバージョンによって異なります. .. literalinclude:: code/cpp/sample_mat_elem_arith_op.cpp 実行結果: .. literalinclude:: output/cpp/sample_mat_elem_arith_op.txt 行列同士の積を求める ===================== 前述の行列の「要素同士の積」とは異なり,* 演算子を利用すると,行列積を計算することができます. また,2チャンネルの行列は複素行列とみなされ,その積も複素行列積になることに注意してください. .. literalinclude:: code/cpp/sample_mat_product.cpp 実行結果: .. literalinclude:: output/cpp/sample_mat_product.txt cv::Vecの内積と外積 =================== .. literalinclude:: code/cpp/sample_vec_product.cpp 実行結果: .. literalinclude:: output/cpp/sample_vec_product.txt ノルムを求める ============== cv::Matやstd::vectorに対するL-2ノルムを計算します. また,Eigen::Matrix型に変換することで,任意のL-pノルムを簡単に求めることができます. .. literalinclude:: code/cpp/sample_vector_norm.cpp 実行結果: .. literalinclude:: output/cpp/sample_vector_norm.txt 行列式を求める ============== 要素の型が CV_32FC1 または CV_64FC1 の正方行列の,行列式を求めます. .. literalinclude:: code/cpp/sample_mat_determinant.cpp 実行結果: .. literalinclude:: output/cpp/sample_mat_determinant.txt 行列の転置 ========== 複素行列の転置は,共役転置行列( `随伴行列 `_ )にはなりません. .. literalinclude:: code/cpp/sample_mat_transpose.cpp 実行結果: .. literalinclude:: output/cpp/sample_mat_transpose.txt .. _mat_diag: 行列の対角成分を取り出す ======================== 2次元以外の Mat では, `対角成分 `_ を取り出すことはできません. .. literalinclude:: code/cpp/sample_diag.cpp 実行結果: .. literalinclude:: output/cpp/sample_diag.txt .. _mat_trace: 行列のトレースを求める ======================== 2次元以外の Mat では, `トレース `_ を求めることはできません. シングルチャンネル行列のトレース ---------------------------------- .. literalinclude:: code/cpp/sample_trace.cpp 実行結果: .. literalinclude:: output/cpp/sample_trace.txt マルチチャンネル行列のトレース ---------------------------------- 2チャンネル行列の場合,要素は複素数として扱われ,実数部と虚数部のトレースが求められます. .. マルチチャンネル行列の場合,各チャンネル毎にトレースが求められます. .. literalinclude:: code/cpp/sample_trace_multi.cpp 実行結果: .. literalinclude:: output/cpp/sample_trace_multi.txt .. _mat_inverse: 逆行列/疑似逆行列を求める ========================= 逆行列,あるいは疑似逆行列を求めます. .. literalinclude:: code/cpp/sample_inv_mat.cpp 実行結果: .. literalinclude:: output/cpp/sample_inv_mat.txt .. _cart2poalr: 2次元ベクトルの角度と大きさを求める =================================== .. literalinclude:: code/cpp/sample_cart2polar.cpp 実行結果: .. literalinclude:: output/cpp/sample_cart2polar.txt .. _polar2cart: 角度と大きさから2次元座標を求める =================================== .. literalinclude:: code/cpp/sample_polar2cart.cpp 実行結果: .. literalinclude:: output/cpp/sample_polar2cart.txt .. _mat_flip: 行列を反転する ============== 2次元以外の Mat では,flipを利用した反転行列を求めることはできません. シングルチャンネル行列の反転 ---------------------------- .. literalinclude:: code/cpp/sample_mat_flip.cpp 実行結果: .. literalinclude:: output/cpp/sample_mat_flip.txt マルチチャンネル行列の反転 --------------------------- マルチチャンネル行列の場合は,各チャンネル毎に反転が行われます. チャンネルの順番が入れ替わることはありません. .. literalinclude:: code/cpp/sample_multich_mat_flip.cpp 実行結果: .. literalinclude:: output/cpp/sample_multich_mat_flip.txt 行列要素の最小値・最大値を求める ================================= 行列要素の最小値・最大値,およびそれの位置を求めます.(例えば,最大値だけが必要で,最小値が不要な場合など)求める必要がないパラメータには NULL を渡すこともできます. また,マスクを利用して,限定された範囲内の最小値・最大値を求めることも可能です. シングルチャンネル行列の最小値・最大値 -------------------------------------- ``minMaxLoc`` に渡せる行列はシングルチャンネルのみです.つまり,1つのチャンネルの最大値のみを求めることができます.しかし,reshape() メソッドを利用することで,すべてのチャンネルの中で最大の値を求めることもできます. .. literalinclude:: code/cpp/sample_minmaxloc.cpp 実行結果: .. literalinclude:: output/cpp/sample_minmaxloc.txt .. マルチチャンネル行列の最小値・最大値 .. ------------------------------------ .. 多次元行列の最小値・最大値 .. -------------------------- 2次元点集合間の最適なアフィン変換を推定する ================================================ 2つの2次元点集合間の最適な2次元のアフィン変換を推定します. パラメータを指定することにより,並進,回転,等方スケーリングに制限されたアフィン変換(5自由度)を推定することもできます. :ref:`image_affine_transform` も参照してください. .. literalinclude:: code/cpp/sample_estimate_rigidtransform.cpp 実行結果: .. literalinclude:: output/cpp/sample_estimate_rigidtransform.txt 水色:入力点集合1,赤色:入力点集合2: 集合1から集合2へのアフィン変換を推定します. 緑色の円:制限されたアフィン変換による変換後の点,黄色の円:任意のアフィン変換による変換後の点, .. image:: image/sample_rigidtransform.png :scale: 30% 連立1次方程式を解く ==================== cv::solve() を利用する場合,右辺,左辺の係数を格納する行列の型は共に,32Fまたは64Fである必要があります. 非特異系 ---------- 独立した方程式の数が変数の数に等しく,行列式がゼロではない場合で,一意な解が存在します. .. math:: :nowrap: \begin{displaymath} \left\{ \begin{array}{l} x + y + z = 6 \\ 3x + 2y - 2z = 1 \\ 2x - y + 3z = 9 \end{array} \right. \end{displaymath} .. literalinclude:: code/cpp/sample_linear_system.cpp 実行結果: .. literalinclude:: output/cpp/sample_linear_system.txt .. 劣決定系 .. -------------- .. .. 方程式の数が変数の数より小さい場合で,解は複数存在します. 優決定系 -------------- 方程式の数が変数の数より大きい場合で,解は存在しない可能性がありますが,OpenCVでは最小二乗問題を解くことになります. .. math:: :nowrap: \begin{displaymath} \left\{ \begin{array}{l} x + y = 3 \\ 3x + 4y = 8 \\ -x - 2y = 2 \end{array} \right. \end{displaymath} .. literalinclude:: code/cpp/sample_linear_system_OD.cpp 実行結果: .. literalinclude:: output/cpp/sample_linear_system_OD.txt 特異値分解を行う ================= 特異値分解を行います. 特異値分解の実装は,OpenCV-2.3で,Lapackを利用しないものに変更されました. しかし,2.3,2.3.1 では,入力行列 A を直接変更する(ことで,多少の速度向上とメモリ節約が見込まれる)オプションフラグ ``SVD::MODIFY_A`` フラグを利用することができません. .. literalinclude:: code/cpp/sample_svd.cpp 実行結果: .. literalinclude:: output/cpp/sample_svd.txt