OpenCVではピクセルの値を取得したり設定したりする方法が何種類かある。自分用に、ピクセルへアクセスする手法のメモ。なお、本稿ではOpenCV2.4.0を扱う。
その1. ポインタを取得してピクセルの値を取得・設定
// 画像の読み込み cv::Mat srcImg = cv::imread("sample.png"); for( int y = 0; y < srcImg.rows; y++ ) { // ポインタの取得 cv::Vec3b* ptr = srcImg.ptr<cv::Vec3b>( y ); for( int x = 0; x < srcImg.cols; x++ ) { // 値の取得 // 対象のピクセルが赤だった場合、BGRの順に"0,0,255"と出力される。 cv::Vec3b bgr = ptr[x]; printf("%d,%d,%d\n", bgr[0], bgr[1], bgr[2]); // 値の設定 // 対象のピクセルにBGR順に255,0,0(青)を設定する。 ptr[x] = cv::Vec3b(255, 0, 0); } } // 結果としてsrcImgが真っ青になる。
その2. イテレータで取得・設定
// 画像の読み込み cv::Mat srcImg = cv::imread("sample.png"); // イテレータの取得 cv::MatIterator_<cv::Vec3b> itd = srcImg.begin<cv::Vec3b>(), itd_end = srcImg.end<cv::Vec3b>(); for(int i=0; itd != itd_end; ++itd, ++i) { // 値の取得 // 対象のピクセルが赤だった場合、BGRの順に"0,0,255"と出力される。 cv::Vec3b bgr = (*itd); printf("%d,%d,%d\n", bgr[0], bgr[1], bgr[2]); // 値の設定 // 対象のピクセルにBGR順に255,0,0(青)を設定する。 (*itd)[0] = 255; (*itd)[1] = 0; (*itd)[2] = 0; } // 結果としてsrcImgが真っ青になる。
その3. Matのatメソッドを使う
// 座標の設定 int x = 0; int y = 0; // 画像の読み込み cv::Mat srcImg = cv::imread("sample.png"); // 値の取得 // (0,0)が赤だった場合、BGRの順に"0,0,255"と出力される。 cv::Vec3b bgr = srcImg.at<cv::Vec3b>(0,0); printf("%d,%d,%d\n",bgr[0],bgr[1],bgr[2]); // 値の設定 // (0,0)にBGR順に255,0,0(青)を設定する。 srcImg.at<cv::Vec3b>(0,0) = cv::Vec3b(255,0,0);
その4. MatにPoint型を指定する
参考:OpenCV rgb value for cv::Point in cv::Mat – Stack Overflow
// 座標の設定 int x = 0; int y = 0; // 画像の読み込み cv::Mat srcImg = cv::imread("sample.png"); cv::Mat3b dotImg = srcImg; // 値の取得 // (0,0)が赤だった場合、BGRの順に"0,0,255"と出力される。 cv::Vec3b bgr = dotImg(cv::Point(x,y)); printf("%d,%d,%d\n",bgr[0],bgr[1],bgr[2]); // 値の設定 // (0,0)にBGR順に255,0,0(青)を設定する。 dotImg(cv::Point(x,y)) = cv::Vec3b(255,0,0);
いただいたご意見
http://t.co/uYxArB7y cv::Mat の at は乗算が入るからランダムアクセスに向いているということを付け足したい。すべて加算にしてあげれば、std::transform 的なテンプレート関数にできるよ。こんな感じ。http://t.co/7SgThrRk
— Shota Matsuda 松田 聖大 (@sgss) 2013, 2月 3
その他
もしこれ以外の手法をご存知でしたら、コメント欄にてお知らせいただければ幸いです。
「OpenCVでピクセルにアクセスする方法4つ」への1件のフィードバック
コメントは停止中です。