はじめに
この記事では const cv::Mat を書き換える方法を示しますが、
const cv::Mat の書き換えを推奨する意図はございません。
cv::Mat に限らず const が付いた変数は基本的に書き換えるべきでは無いと思っています。
この記事は OpenCV に慣れていない人がここにある方法でcv::Mat を宣言してしまわないための注意となれば幸いです。
環境
- OpenCV 3.4.6
- Microsoft Visual Studio Community 2015 Update 3
本題
const cv::Mat を書き換えようとすると普通はコンパイルエラーになります。
void changeValue(const cv::Mat& const_mat, const cv::Scalar& color) { // これはコンパイルエラーになります const_mat.setTo(color); }
ただし以下のように cv::Mat のコピーコンストラクタ(または代入)を用いることで値を書き換えられます。
void changeValue(const cv::Mat& const_mat, const cv::Scalar& color) { cv::Mat mat = const_mat; mat.setTo(color); }
cv::Mat< Tp >でも同様です。
template <typename T> void changeValue(const cv::Mat_<T>& const_mat, T val) { cv::Mat_<T> mat = const_mat; mat.setTo(val); }
コピーコンストラクタよりまわりくどいですが、dataメンバ変数を用いる方法もあります。
void changeValue(const cv::Mat& const_mat, const cv::Scalar& color) { uchar* p = const_mat.data; cv::Mat mat(const_mat.rows, const_mat.cols, const_mat.type(), p); mat.setTo(color); }
const_mat と同じ値を持つ mat を作りたい場合にここで示した方法で作ってしまうと、 const_mat の値を書き換えてしまう恐れがありますのでご注意ください。 そういう場合は copyTo や clone メソッドを使用するか、 ディープコピーを避ける目的なら新しい宣言先も const cv::Mat にしたほうが適当でしょう。