Pynote

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

OpenCV - cv::Mat と他のオブジェクト間の型変換について

試した環境

変換一覧

cv::Mat <-> std::vector
// cv::Mat <- std::vector
template<typename _Tp>
Mat(const std::vector<_Tp> &vec, bool copyData=false)
// cv::Mat -> std::vector
template<typename _Tp>
operator std::vector<_Tp> () const

std::vector<uint8_t> vec = {1, 2, 3, 4, 5, 6};

// cv::Mat <- std::vector
// explict 修飾子が付いているため、mat = vec はできない。
cv::Mat mat(vec);

std::cout << mat << std::endl;
||<>

出力
>|cpp|
[  1;
   2;
   3;
   4;
   5;
   6]

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

// cv::Mat -> std::vector
// 変換元の行列は nx1 または 1xn である必要がある
std::vector<uint8_t> vec = mat;

for (auto &v : vec) {
    std::cout << unsigned(v);
    if (&v != &vec.back())
        std::cout << ", ";
}
std::cout << std::endl;

出力

1, 2, 3, 4, 5, 6, 7, 8, 9
cv::Mat <-> cv::Matx
// cv::Mat <- cv::Matx
template<typename _Tp, int m, int n>
Mat(const Matx<_Tp, m, n> &mtx, bool copyData=true)
// cv::Mat -> cv::Matx
template<typename _Tp, int m, int n>
operator Matx<_Tp, m, n>() const

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

// cv::Mat <- cv::Matx
// explict 修飾子が付いているため、mat = matx はできない。
cv::Mat mat(matx);

std::cout << mat << std::endl;

出力

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

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

// cv::Mat -> cv::Matx
cv::Matx<uint8_t, 3, 3> matx = mat;

std::cout << matx << std::endl;

出力

[  1,   2,   3;
   4,   5,   6;
   7,   8,   9]
cv::Mat <-> cv::Vec
// cv::Mat <- cv::Vec
template<typename _Tp, int n>
Mat(const Vec<_Tp, n> &vec, bool copyData=true);
// cv::Mat -> cv::Vec
template<typename _Tp, int m, int n>
operator Matx<_Tp, m, n>() const;

cv::Vec<uint8_t, 3> vec(1, 2, 3);

// cv::Mat <- cv::Vec
// explict 修飾子が付いているため、mat = vec はできない。
cv::Mat mat(vec);
std::cout << mat << std::endl;

出力

[1;
 2;
 3]

uint8_t data[] = {1, 2, 3};
cv::Mat mat(3, 1, CV_8UC1, data);

// cv::Mat -> cv::Vec
cv::Vec<uint8_t, 3> vec = mat;

std::cout << vec << std::endl;

出力

vec
cv::Mat <- cv::Point_
// cv::Mat <- cv::Point_
template<typename _Tp>
Mat (const Point_<_Tp> &pt, bool copyData=true);

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

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

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

出力

[1;
 2]

// cv::Mat -> cv::Point2i
uint8_t data[] = {1, 2};
cv::Mat mat(2, 1, CV_8UC1, data);

cv::Point p = mat;
std::cout << p << std::endl;

出力

[1, 2]
cv::Mat <-> cv::Point3_
// cv::Mat <- cv::Point3_
template<typename _Tp>
Mat(const Point3_<_Tp> &pt, bool copyData=true)

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

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

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

出力

[1;
 2;
 3]

// cv::Mat -> cv::Point3i
uint8_t data[] = {1, 2, 3};
cv::Mat mat(3, 1, CV_8UC1, data);

cv::Point3i p = mat;
std::cout << p << std::endl;

出力

[1, 2, 3]
別の型に変換する
void convertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const

以下の変換が行える。
ただ別の型に変換を行いたい場合は、元の配列 m と変換先の型 rtype を指定すればよい。
元の値を x としたとき、\alpha x + \beta とした上で型変換を行いたい場合は \alpha 及び \beta を指定する。

m(x, y) = saturate_cast<rType>(alpha (∗this)(x, y) + beta)

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

// uint8_t から float に変換する。
cv::Mat mat1;
mat.convertTo(mat1, CV_32FC1);
std::cout << mat1 << std::endl;

// 2 * mat + 1 とした上で、float に変換する。
cv::Mat mat2;
mat.convertTo(mat2, CV_32FC1, 2, 1);
std::cout << mat2 << std::endl;

出力

[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
[3, 5, 7;
 9, 11, 13;
 15, 17, 19]