#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 3x3 の行列
cv::Mat m1 = (cv::Mat_<double>(3,3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
std::cout << "m1=" << m1 << std::endl << std::endl;
// 行列とスカラ
cv::Mat m2 = m1+3;
cv::Mat m3 = m1*3; // スケーリング
cv::Mat m4 = m1/3;
std::cout << "m2=" << m2 << std::endl << std::endl;
std::cout << "m3=" << m3 << std::endl << std::endl;
std::cout << "m4=" << m4 << std::endl << std::endl;
// 行列と行列
cv::Mat m5 = m1+m1;
cv::Mat m6 = m1.mul(m2); // m1*m2 とは違う
cv::Mat m7 = m1.mul(m2, 2); // スケールファクタ追加
std::cout << "m5=" << m5 << std::endl << std::endl;
std::cout << "m6=" << m6 << std::endl << std::endl;
std::cout << "m7=" << m7 << std::endl << std::endl;
// 要素の型が違う
cv::Mat m8 = (cv::Mat_<int>(3,3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
try {
std::cout << m1/m8 << std::endl;
} catch(cv::Exception e) {
// ...
std::cout << std::endl;
}
// 行列のサイズが違う
cv::Mat m9 = (cv::Mat_<double>(2,2) << 1, 2, 3, 4);
try {
std::cout << m9/m1 << std::endl;
} catch(cv::Exception e) {
// ...
std::cout << std::endl;
}
}
実行結果:
m1=[1, 2, 3;
4, 5, 6;
7, 8, 9]
m2=[4, 5, 6;
7, 8, 9;
10, 11, 12]
m3=[3, 6, 9;
12, 15, 18;
21, 24, 27]
m4=[0.3333333333333333, 0.6666666666666666, 1;
1.333333333333333, 1.666666666666667, 2;
2.333333333333333, 2.666666666666667, 3]
m5=[2, 4, 6;
8, 10, 12;
14, 16, 18]
m6=[4, 10, 18;
28, 40, 54;
70, 88, 108]
m7=[8, 20, 36;
56, 80, 108;
140, 176, 216]
OpenCV Error: Assertion failed (src1.size() == src2.size() && src1.type() == src2.type() && func != 0) in divide, file arithm.cpp, line 885
OpenCV Error: Assertion failed (src1.size() == src2.size() && src1.type() == src2.type() && func != 0) in divide, file arithm.cpp, line 885
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// シングルチャンネル,3x3 の行列
cv::Mat m1 = (cv::Mat_<double>(3,3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat m2 = m1+3;
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "m2=" << m2 << std::endl << std::endl;
// 行列の積
std::cout << "m1*m2=" << m1*m2 << std::endl << std::endl;
cv::Mat m3 = (cv::Mat_<double>(3,3) << -1, 2, -3, 4, -5, 6, -7, 8, -9);
cv::Mat m4 = m3-3;
std::cout << "m3=" << m3 << std::endl << std::endl;
std::cout << "m4=" << m4 << std::endl << std::endl;
// 行列の積
std::cout << "m2*m4=" << m3*m4 << std::endl << std::endl;
// 2チャンネル,3x3 の行列
cv::Mat m13, m24;
std::vector<cv::Mat> ms(2);
ms[0] = m1;
ms[1] = m3;
cv::merge(ms, m13);
ms[0] = m2;
ms[1] = m4;
cv::merge(ms, m24);
// 複素行列の積
std::cout << "m13*m24=" << m13*m24 << std::endl;
}
実行結果:
m1=[1, 2, 3;
4, 5, 6;
7, 8, 9]
m2=[4, 5, 6;
7, 8, 9;
10, 11, 12]
m1*m2=[48, 54, 60;
111, 126, 141;
174, 198, 222]
m3=[-1, 2, -3;
4, -5, 6;
-7, 8, -9]
m4=[-4, -1, -6;
1, -8, 3;
-10, 5, -12]
m2*m4=[36, -30, 48;
-81, 66, -111;
126, -102, 174]
m13*m24=[12, -52, 84, -24, 12, -60;
192, -30, 60, 32, 252, -30;
48, -172, 300, -96, 48, -204]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
cv::Vec3d v1(1,2,3);
cv::Vec3d v2(3,4,5);
// 内積
double v_dot = v1.dot(v2);
// 外積(3次元ベクトルのみ計算可能)
cv::Vec3d v_cross = v1.cross(v2);
std::cout << "v_dot=" << v_dot << std::endl;
cv::Mat tmp(v_cross);
std::cout << "v_cross=" << tmp << std::endl;
}
実行結果:
v_dot=26
v_cross=[-2; 4; -2]
#include <iostream>
#include <Eigen/Core>
#include <opencv2/core/core.hpp>
#include <opencv2/core/eigen.hpp>
int
main(int argc, char *argv[])
{
// 6x1 の行列
cv::Mat m1 = (cv::Mat_<double>(6,1) << 1, 5, 3, -1,-3,-5);
// 2x3 の行列
cv::Mat m2 = (cv::Mat_<double>(2,3) << 1, 5, 3, -1,-3,-5);
// ベクトル(1,2,...,9)
std::vector<double> v1;
m1.copyTo(v1);
// ベクトル(3,4)
cv::Point p1(3,4);
Eigen::VectorXd em1;
cv::cv2eigen(m1, em1);
double norm_m1 = cv::norm(m1); // 6次元ベクトルのL-2ノルム
double norm_m2 = cv::norm(m2); // 実数行列のフロベニウスノルム
// OpenCV>=2.3ならば, cv::norm(v1); で OK
double norm_v1 = cv::norm(cv::Mat(v1)); // 6次元ベクトルのL-2ノルム
double norm_p1 = cv::norm(p1); // 2次元ベクトルのL-2ノルム
double lpnorm1 = em1.lpNorm<1>(); // L-1ノルム
double lpnorm2 = em1.lpNorm<2>(); // L-2ノルム
double lpnorm3 = em1.lpNorm<3>(); // L-3ノルム
std::cout << "norm(m1)=" << norm_m1 << std::endl;
std::cout << "norm(m2)=" << norm_m2 << std::endl;
std::cout << "norm(v1)=" << norm_v1 << std::endl;
std::cout << "norm(p1)=" << norm_p1 << std::endl << std::endl;
std::cout << "L-1 norm=" << lpnorm1 << std::endl;
std::cout << "L-2 norm=" << lpnorm2 << std::endl;
std::cout << "L-3 norm=" << lpnorm3 << std::endl;
}
実行結果:
norm(m1)=8.3666
norm(m2)=8.3666
norm(v1)=8.3666
norm(p1)=5
L-1 norm=18
L-2 norm=8.3666
L-3 norm=6.73866
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 正方行列
cv::Mat m1 = (cv::Mat_<double>(3,3) << 1, 0, 3, 4, 5, 6, 7, 0, 9);
CV_Assert(m1.cols==m1.rows && (m1.type()==CV_32FC1 || m1.type()==CV_64FC1));
double d1 = cv::determinant(m1);
std::cout << "m1=" << m1 << std::endl;
std::cout << "det=" << d1 << std::endl << std::endl;
}
実行結果:
m1=[1, 0, 3;
4, 5, 6;
7, 0, 9]
det=-60
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 3x1 行列
cv::Mat m1 = (cv::Mat_<double>(3,1) << 1, 2, 3);
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "m1.t()=" << m1.t() << std::endl << std::endl;
// 3x1 複素行列
std::complex<double> c1(1,2);
std::complex<double> c2(3,4);
std::complex<double> c3(5,6);
cv::Mat m2 = (cv::Mat_<std::complex<double> >(3, 1) << c1, c2, c3);
std::cout << "m2=" << m2 << std::endl << std::endl;
// 共役にはならない
std::cout << "m2.t()=" << m2.t() << std::endl << std::endl;
}
実行結果:
m1=[1; 2; 3]
m1.t()=[1, 2, 3]
m2=[1, 2; 3, 4; 5, 6]
m2.t()=[1, 2, 3, 4, 5, 6]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 5x5 の行列
cv::Mat m1 = (cv::Mat_<double>(5,5) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, \
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25);
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "diag(0)=" << m1.diag(0) << std::endl << std::endl; // 主対角線上の成分
std::cout << "diag(1)=" << m1.diag(1) << std::endl << std::endl; // 主対角線の1つ上の成分
std::cout << "diag(-1)=" << m1.diag(-1) << std::endl << std::endl; // 主対角線の1つ下の成分
}
実行結果:
m1=[1, 2, 3, 4, 5;
6, 7, 8, 9, 10;
11, 12, 13, 14, 15;
16, 17, 18, 19, 20;
21, 22, 23, 24, 25]
diag(0)=[1; 7; 13; 19; 25]
diag(1)=[2; 8; 14; 20]
diag(-1)=[6; 12; 18; 24]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
cv::Mat m1 = (cv::Mat_<int>(3,3) << 1,2,3,4,5,6,7,8,9);
std::cout << "m1=" << m1 << std::endl;
cv::Scalar traces = cv::trace(m1);
std::cout << "trace=" << traces[0] << std::endl << std::endl;
}
実行結果:
m1=[1, 2, 3;
4, 5, 6;
7, 8, 9]
trace=15
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
cv::Mat m0 = (cv::Mat_<int>(3,6) << 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18);
// channels=2, 3x3 の行列
cv::Mat m1 = m0.reshape(2);
std::cout << "m1=" << m1 << std::endl << std::endl;
std::vector<cv::Mat> planes;
cv::Scalar traces = cv::trace(m1);
cv::split(m1, planes);
for(int i=0; i<m1.channels(); ++i) {
std::cout << planes[i] << std::endl;
std::cout << "trace[" << i << "]=" << traces[i] << std::endl << std::endl;
}
}
実行結果:
m1=[1, 2, 3, 4, 5, 6;
7, 8, 9, 10, 11, 12;
13, 14, 15, 16, 17, 18]
[1, 3, 5;
7, 9, 11;
13, 15, 17]
trace[0]=27
[2, 4, 6;
8, 10, 12;
14, 16, 18]
trace[1]=30
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 逆行列 (LU分解)
cv::Mat m1 = (cv::Mat_<double>(3,3) << 10, -9, -12, 7, -12, 11, -10, 10, 3);
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "inverse matrix (LU decompression):" << std::endl << std::endl;
std::cout << "m1^-1=" << m1.inv() << std::endl << std::endl;
std::cout << "m1*m1^-1=" << m1*m1.inv() << std::endl << std::endl;
// 逆行列 (SVD)
std::cout << "inverse matrix (SVD):" << std::endl << std::endl;
std::cout << "m1^-1=" << m1.inv(cv::DECOMP_SVD) << std::endl << std::endl;
std::cout << "m1*m1^-1=" << m1*m1.inv(cv::DECOMP_SVD) << std::endl << std::endl;
// 擬似逆行列
cv::Mat m2 = (cv::Mat_<double>(2,3) << 10, -9, -12, 7, -12, 11);
std::cout << "m2=" << m2 << std::endl << std::endl;
std::cout << "m2^-1=" << m2.inv(cv::DECOMP_SVD) << std::endl << std::endl;
std::cout << "m2*m2^-1=" << m2*m2.inv(cv::DECOMP_SVD) << std::endl << std::endl;
}
実行結果:
m1=[10, -9, -12;
7, -12, 11;
-10, 10, 3]
inverse matrix (LU decompression):
m1^-1=[-0.4576802507836991, -0.2915360501567398, -0.7617554858934169;
-0.4106583072100313, -0.2821316614420062, -0.6081504702194357;
-0.1567398119122257, -0.03134796238244514, -0.1786833855799373]
m1*m1^-1=[1, -4.996003610813204e-16, -3.33066907387547e-16;
-4.163336342344337e-16, 0.9999999999999996, -2.775557561562891e-16;
1.942890293094024e-16, 4.996003610813204e-16, 1]
inverse matrix (SVD):
m1^-1=[-0.4576802507837005, -0.2915360501567407, -0.7617554858934192;
-0.4106583072100324, -0.282131661442007, -0.6081504702194376;
-0.1567398119122261, -0.03134796238244537, -0.1786833855799379]
m1*m1^-1=[0.9999999999999998, 4.996003610813204e-16, 6.661338147750939e-16;
-1.165734175856414e-15, 0.9999999999999998, -6.661338147750939e-16;
2.442490654175344e-15, 9.020562075079397e-16, 1.000000000000003]
m2=[10, -9, -12;
7, -12, 11]
m2^-1=[0.02819861108331499, 0.01816198691136149;
-0.02275501831208597, -0.03488302279504472;
-0.04276822702983969, 0.04129725618908479]
m2*m2^-1=[1, -1.387778780781446e-17;
-1.040834085586084e-17, 0.9999999999999998]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
cv::Mat x = (cv::Mat_<double>(4,1) << 0, 1, 4, 1);
cv::Mat y = (cv::Mat_<double>(4,1) << 1, 1, 3, 1.7320504);
// 2次元座標から,大きさと角度を求める.
cv::Mat magnitude, angle;
cv::cartToPolar(x, y, magnitude, angle, true); // in degrees
for(int i=0; i<4; ++i) {
std::cout << "(" << x.at<double>(i) << ", " << y.at<double>(i) << ") ";
std::cout << "mag=" << magnitude.at<double>(i) << ", angle=" << angle.at<double>(i) << "[deg]" << std::endl;
}
}
実行結果:
(0, 1) mag=1, angle=90
(1, 1) mag=1.41421, angle=44.7623
(4, 3) mag=5, angle=37.1247
(1, 1.73205) mag=2, angle=59.7441
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
cv::Mat magnitude = (cv::Mat_<double>(4,1) << 1, 1.41421, 5, 2);
cv::Mat angle = (cv::Mat_<double>(4,1) << 90, 45, 36.8699, 60);
// 大きさと角度から,2次元座標を求める.
cv::Mat x, y;
cv::polarToCart(magnitude, angle, x, y, true); // in degrees
for(int i=0; i<4; ++i) {
std::cout << "(" << x.at<double>(i) << ", " << y.at<double>(i) << ") ";
std::cout << "mag=" << magnitude.at<double>(i) << ", angle=" << angle.at<double>(i) << "[deg]" << std::endl;
}
}
実行結果:
(2.65358e-17, 1) mag=1, angle=90[deg]
(0.999997, 0.999997) mag=1.41421, angle=45[deg]
(4, 3) mag=5, angle=36.8699[deg]
(1, 1.73205) mag=2, angle=60[deg]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 3x3 の行列
cv::Mat m1 = (cv::Mat_<double>(3,3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat mv, mh, mb;
cv::flip(m1, mv, 0); // 水平軸で反転
cv::flip(m1, mh, 1); // 垂直軸で反転
cv::flip(m1, mb, -1); // 両方の軸で反転
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "mv=" << mv << std::endl << std::endl;
std::cout << "mh=" << mh << std::endl << std::endl;
std::cout << "mb=" << mb << std::endl << std::endl;
}
実行結果:
m1=[1, 2, 3;
4, 5, 6;
7, 8, 9]
mv=[7, 8, 9;
4, 5, 6;
1, 2, 3]
mh=[3, 2, 1;
6, 5, 4;
9, 8, 7]
mb=[9, 8, 7;
6, 5, 4;
3, 2, 1]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// CV32SC2, 3x3 行列(m1)
cv::Mat m0 = (cv::Mat_<int>(3,6) << 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18);
cv::Mat m1 = m0.reshape(2);
cv::Mat mv, mh, mb;
cv::flip(m1, mv, 0); // 水平軸で反転
cv::flip(m1, mh, 1); // 垂直軸で反転
cv::flip(m1, mb, -1); // 両方の軸で反転
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "mv=" << mv << std::endl << std::endl;
std::cout << "mh=" << mh << std::endl << std::endl;
std::cout << "mb=" << mb << std::endl << std::endl;
}
実行結果:
m1=[1, 2, 3, 4, 5, 6;
7, 8, 9, 10, 11, 12;
13, 14, 15, 16, 17, 18]
mv=[13, 14, 15, 16, 17, 18;
7, 8, 9, 10, 11, 12;
1, 2, 3, 4, 5, 6]
mh=[5, 6, 3, 4, 1, 2;
11, 12, 9, 10, 7, 8;
17, 18, 15, 16, 13, 14]
mb=[17, 18, 15, 16, 13, 14;
11, 12, 9, 10, 7, 8;
5, 6, 3, 4, 1, 2]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 3x3 の行列
cv::Mat m1 = (cv::Mat_<double>(3,3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
double minVal, maxVal;
cv::Point minLoc, maxLoc;
cv::minMaxLoc(m1, &minVal, &maxVal, &minLoc, &maxLoc);
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "min=" << minVal << ", " << minLoc << std::endl << std::endl;
std::cout << "max=" << maxVal << ", " << maxLoc << std::endl << std::endl;
// 最小値・最大値が複数あると...
m1.at<double>(0,1) = 1;
m1.at<double>(2,1) = 9;
// 最初に見つかった位置が返される
cv::minMaxLoc(m1, &minVal, &maxVal, &minLoc, &maxLoc);
std::cout << "m1=" << m1 << std::endl << std::endl;
std::cout << "min=" << minVal << ", " << minLoc << std::endl << std::endl;
std::cout << "max=" << maxVal << ", " << maxLoc << std::endl << std::endl;
}
実行結果:
m1=[1, 2, 3;
4, 5, 6;
7, 8, 9]
min=1, [0, 0]
max=9, [2, 2]
m1=[1, 1, 3;
4, 5, 6;
7, 9, 9]
min=1, [0, 0]
max=9, [1, 2]
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> //
#include <opencv2/video/tracking.hpp> // for 2.3 or later
int
main(int argc, char *argv[])
{
cv::Size img_size(500, 500);
cv::Mat img = cv::Mat::zeros(img_size, CV_8UC3);
// 3x3 の行列
int rand_num = 10;
cv::Mat_<float> points(rand_num, 3);
cv::Mat src_points(points, cv::Rect(0,0,2,rand_num));
cv::randu(points, cv::Scalar(100), cv::Scalar(400));
for(int i=0; i<rand_num; ++i) {
points(i, 2) = 1.0;
// 変換前の座標点を描画(水色の点)
cv::circle(img, cv::Point(points(i,0), points(i,1)), 2, cv::Scalar(200,200,0), -1, CV_AA);
}
cv::Mat affine_matrix = (cv::Mat_<float>(2, 3) << 0.7660,-0.8428,214.1616,0.6428,0.9660,-108.4043);
cv::Mat dst_points = points * affine_matrix.t();
// 変換後の座標点を描画(赤色の点)
for(int i=0; i<rand_num; ++i) {
cv::circle(img, cv::Point(dst_points.at<float>(i,0), dst_points.at<float>(i,1)), 2, cv::Scalar(50,50,255), -1, CV_AA);
}
// 2次元アフィン変換の推定(回転,並進,拡大縮小の拘束あり)
cv::Mat est_matrix = cv::estimateRigidTransform(src_points.reshape(2), dst_points.reshape(2), false);
// 2次元アフィン変換の推定(拘束なし)
cv::Mat est_matrix_full = cv::estimateRigidTransform(src_points.reshape(2), dst_points.reshape(2), true);
std::cout << "Affine Transformation Matrix:" << std::endl;
std::cout << affine_matrix << std::endl << std::endl;
std::cout << "Estimated Matrix:" << std::endl;
std::cout << est_matrix << std::endl << std::endl;
std::cout << "Estimated Matrix (full):" << std::endl;
std::cout << est_matrix_full << std::endl << std::endl;
/// 元の点を推定した変換行列で変換する
cv::Mat est_matrixF, est_matrixF_full;
est_matrix.convertTo(est_matrixF, CV_32F);
est_matrix_full.convertTo(est_matrixF_full, CV_32F);
cv::Mat_<float> est_points = points * est_matrixF.t();
cv::Mat_<float> est_points_full = points * est_matrixF_full.t();
for(int i=0; i<rand_num; ++i) {
// 拘束ありのアフィン変換で変換した点集合を描画(緑色の円)
cv::circle(img, cv::Point(est_points(i,0), est_points(i,1)), 5, cv::Scalar(50,255,50), 1, CV_AA);
// 拘束なしのアフィン変換で変換した点集合を描画(黄色の円)
cv::circle(img, cv::Point(est_points_full(i,0), est_points_full(i,1)), 5, cv::Scalar(50,255,255), 1, CV_AA);
}
cv::namedWindow("image", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
cv::imshow("image", img);
cv::waitKey(0);
}
実行結果:
Affine Transformation Matrix:
[0.76599997, -0.84280002, 214.16161;
0.64279997, 0.96600002, -108.4043]
Estimated Matrix:
[0.8995064623862854, -0.8670171167356711, 198.2603717112048;
0.8670171167356711, 0.8995064623862854, -128.2613453078639]
Estimated Matrix (full):
[0.7659999426447789, -0.8428000332703937, 214.1616156934035;
0.6427999985417542, 0.966000008132273, -108.4043013037557]
水色:入力点集合1
赤色:入力点集合2:
集合1から集合2へのアフィン変換を推定
緑色の円:制限されたアフィン変換による変換後の点
黄色の円:任意のアフィン変換による変換後の点
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 左辺
cv::Mat lhand = (cv::Mat_<double>(3,3) << 1,1,1,3,2,-2,2,-1,3);
// 右辺
cv::Mat rhand = (cv::Mat_<double>(3,1) << 6,1,9);
// ガウスの消去法により解を求める
cv::Mat ans;
cv::solve(lhand, rhand, ans);
std::cout << "(x,y,z) = " << ans << std::endl;
}
実行結果:
(x,y,z) = [1; 2; 3]
#include <iostream>
#include <opencv2/core/core.hpp>
int
main(int argc, char *argv[])
{
// 左辺
cv::Mat lhand = (cv::Mat_<double>(3,2) << 1,1,3,4,-1,-2);
// 右辺
cv::Mat rhand = (cv::Mat_<double>(3,1) << 3,8,2);
// SVDにより最小二乗問題の解を求める
cv::Mat x;
cv::solve(lhand, rhand, x, cv::DECOMP_SVD);
std::cout << "(x,y) = " << x << std::endl;
std::cout << "norm(lhand*x-rhand)=" << norm(lhand*x-rhand) << std::endl;
}
実行結果:
(x,y) = [9.999999999999998; -5.666666666666665]
norm(lhand*x-rhand)=1.63299