Pynote

Python、機械学習、画像処理について

OpenCV - cv::Mat のコンストラクタについて

試した環境

コンストラクタ

Mat();  // (1)
Mat(int rows, int cols, int type);  // (2)
Mat(Size size, int type);  // (3)
Mat(int rows, int cols, int type, const Scalar &s);  // (4)
Mat(Size size, int type, const Scalar &s);  // (5)
Mat(int rows, int cols, int type, void *data, size_t step=AUTO_STEP);  // (6)
Mat(Size size, int type, void *data, size_t step=AUTO_STEP);  // (7)
Mat(const Mat &m);  // (8)
Mat(const Mat &m, const Range &rowRange, const Range &colRange=Range::all());  // (9)
Mat(const Mat &m, const Rect &roi);  // (10)
template<typename _Tp>
Mat(const std::vector<_Tp> &vec, bool copyData=false)  // (11)
template<typename _Tp, int n>
Mat(const Vec<_Tp, n> &vec, bool copyData=true)  // (12)
template<typename _Tp, int m, int n>
Mat(const Matx<_Tp, m, n> &mtx, bool copyData=true)  // (13)
template<typename _Tp>
Mat(const Point_<_Tp> &pt, bool copyData=true)  // (14)
template<typename _Tp>
Mat(const Point3_<_Tp> &pt, bool copyData=true)  // (15)
template<typename _Tp>
Mat(const MatCommaInitializer_<_Tp> &commaInitializer)  // (16)
Mat(const cuda::GpuMat &m)  // (17)
Mat(int ndims, const int *sizes, int type);  // (18)
Mat(int ndims, const int *sizes, int type, const Scalar &s);  // (19)
Mat(int ndims, const int *sizes, int type, void *data, const size_t *steps=0);  // (20)
Mat(const Mat &m, const Range *ranges);  // (21)
空の行列を作成する

// (1) 空の行列を作成する。
cv::Mat mat;
(2), (3) 大きさ及び型を指定して行列を作成する

cv::Size で大きさを指定する場合は、cv::Size(列、行) の順番なので注意する。

// (2) 形状が 3x2 で要素の型が CV_8UC1 である配列を作成する。
cv::Mat mat(3, 2, CV_8UC1);

// (3) 形状が 3x2 で要素の型が CV_8UC1 である配列を作成する。
cv::Mat mat(cv::Size(2, 3), CV_8UC1);
(4), (5) 大きさ、型及び値を指定して行列を作成する

// (4) 形状が 3x2 で要素の型が CV_8UC1 である配列を作成する。
//     各要素は 5 で初期化される。
cv::Mat mat(cv::Size(3, 2), CV_8UC1, 5);

// (5) 形状が 3x2 で要素の型が CV_8UC1 である配列を作成する。
//     各要素は 5 で初期化される。
cv::Mat mat(cv::Size(2, 3), CV_8UC1, 5);
(6), (7) 大きさ、型及び値を指定して行列を作成する

cv::Mat の型と配列の型が一致していないとおかしくなるので注意。

// (6) 形状が 3x3 で要素の型が CV_8UC1 である配列を作成する。
//     各要素は data の値で初期化される。
uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
cv::Mat mat(3, 3, CV_8UC1, data);
std::cout << mat << std::endl;

// (7) 形状が 3x3 で要素の型が CV_8UC1 である配列を作成する。
//     各要素は data の値で初期化される。
uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
cv::Mat mat(cv::Size(3, 3), CV_8UC1, data);
std::cout << mat << std::endl;

出力

[  1,   2,   3;
   4,   5,   6;
   7,   8,   9]
(8) コピーコンストラクタ

// (8) コンストラクタ
cv::Mat mat1;

cv::Mat mat2(mat1);
cv::Mat mat3 = mat1;
(9), (10) 部分行列を作成する

行及び列は 0, 1, ... とインデックスされている。
cv::Range(begin, end) は begin ~ end - 1 のインデックスが対象で end 自身は含まれないので注意する。

// 元の行列
uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
cv::Mat mat(3, 3, CV_8UC1, data);

// (9) 部分行列 [1:3, 1:3] を作成する。
cv::Mat subMat(mat, cv::Range(1, 3), cv::Range(1, 3));
std::cout << subMat << std::endl;

出力

[  5,   6;
   8,   9]

// 元の行列
uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
cv::Mat mat(cv::Size(3, 3), CV_8UC1, data);

// (10) 部分配列 [1:3, 1:3] を作成する。
cv::Mat subMat(mat, cv::Rect(1, 1, 2, 2));
std::cout << subMat << std::endl;

出力

[  5,   6;
   8,   9]
(11) ~ (17) 変換コンストラクタ

(11) std::vector -> cv::Mat

列ベクトルとして解釈される。

// (11) std::vector -> cv::Mat
std::vector<uint8_t> vec = {1, 2, 3, 4};

cv::Mat mat(vec);
std::cout << vec << std::endl;

出力

[  1;
   2;
   3;
   4]

(12) cv::Vec -> cv::Mat

// (12) cv::Vec -> cv::Mat
cv::Vec<float, 3> vec(1, 2, 3);

cv::Mat mat(vec);
std::cout << mat << std::endl;

出力

[1;
 2;
 3]

(13) cv::Matx -> cv::Mat

// (12) cv::Matx -> cv::Mat
cv::Matx<uint8_t, 3, 3> matx(1, 2, 3, 4, 5, 6, 7, 8, 9);

cv::Mat mat(matx);
std::cout << mat << std::endl;

出力

[  1,   2,   3;
   4,   5,   6;
   7,   8,   9]

(14) cv::Point_ -> cv::Mat

列ベクトルとして解釈される。

// (14) cv::Point2i -> cv::Mat
cv::Point2i p(1, 2);

cv::Mat mat(p);
std::cout << mat << std::endl;

出力

[1;
 2]

(15) cv::Point3_ -> cv::Mat

列ベクトルとして解釈される。

// (14) cv::Point3i -> cv::Mat
cv::Point3i p(1, 2, 3);

cv::Mat mat(p);
std::cout << mat << std::endl;

出力

[1;
 2;
 3]

(16) cv::MatCommaInitializer_ -> cv::Mat

// (16) cv::MatCommaInitializer_ -> cv::Mat
cv::Mat mat = (cv::Mat_<uint8_t>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
std::cout << mat << std::endl;

出力

[  1,   2,   3;
   4,   5,   6;
   7,   8,   9]
(18) ~ (21) 多次元配列

// (18) 形状が 3x3x3 で要素の型が CV_8UC1 である配列を作成する。
int shape[] = {3, 3, 3};
cv::Mat mat(3, shape, CV_8UC1);

// (19) 形状が 3x3x3 で要素の型が CV_8UC1 である配列を作成する。
//      各要素は 5 で初期化される。
int shape[] = {3, 3, 3};
cv::Mat mat(3, shape, CV_8UC1, 5);

// (20) 形状が 2x2x2 で要素の型が CV_8UC1 である配列を作成する。
//      各要素は data の値で初期化される。
int shape[] = {2, 2, 2};
uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8};
cv::Mat mat(3, shape, CV_8UC1, data);

// 元の行列
int shape[] = {3, 3, 3};
cv::Mat mat(3, shape, CV_8UC1);

// (21) 部分配列 [1:3, 1:3, 1:3] を作成する。
cv::Range ranges[] = {
    cv::Range(1, 3), cv::Range(1, 3), cv::Range(1, 3)};
cv::Mat subMat(mat, ranges);