OpenCV by C++
インストール
Ubuntu 14.04
sudo apt-get install -yV build-essential git cmake sudo apt-get install -yV libcv-dev libhighgui-dev libcvaux-dev python-opencv opencv-doc sudo apt-get install libcv2.4 libcvaux2.4 opencv-doc libcv-dev libcvaux-dev libopencv-dev apt-file
コンパイル
g++ test.cpp -lopencv_core g++ hogehoge.cpp `pkg-config opencv --cflags --libs` ↑こうすると, リンクすべきライブラリをひとつづつ調べて指定しなくても大丈夫!
cv::Mat
// cv::Matの型を表示する関数 // compile: $ g++ test.cpp -lopencv_core -lopencv_highgui # include <opencv2/core/core.hpp> # include <opencv2/highgui/highgui.hpp> # include <iostream> using namespace std; void cvmat_style(cv::Mat m){ // thanks to OpenCV-CookBook http://opencv.jp/cookbook/opencv_mat.html#mat-various-properties cout << "行数 rows:" << m.rows << " 列数 cols:" << m.cols << endl; cout << "次元数 dims:" << m.dims << " サイズ(2次元の場合)size[]:" << m.size().width << "," << m.size().height << endl; cout << "ビット深度ID depth (ID):" << m.depth() << "(=" << CV_64F << ")" << endl; cout << "チャンネル数 channels:" << m.channels() << endl; cout << "(複数チャンネルから成る)1要素のサイズ [バイト単位] elemSize:" << m.elemSize() << "[byte]" << endl; cout << "1要素内の1チャンネル分のサイズ [バイト単位] (elemSize/channels):" << m.elemSize1() << "[byte]" << endl; cout << "要素の総数 total:" << m.total() << endl; cout << "ステップ数 [バイト単位] step:" << m.step << "[byte]" << endl; cout << "1ステップ内のチャンネル総数 step1 (step/elemSize1):" << m.step1() << endl; cout << "データは連続か? isContinuous:" << (m.isContinuous()?"true":"false") << endl; cout << "部分行列か? isSubmatrix:" << (m.isSubmatrix()?"true":"false") << endl; cout << "データは空か? empty:" << (m.empty()?"true":"false") << endl; } int main(){ cv::Mat image = cv::imread("tmp/2015_0622_1413_cimg3755.jpg"); // imreadはhighguiの関数 cv::imshow("Look at me!", image); // imshowはhighguiの関数 cvmat_style(image); cv::waitKey(0); }
- 単チャンネル複数画像から複チャンネル単画像への変換 http://stackoverflow.com/questions/13648567/multiple-single-channel-matrix-converted-to-single-multi-channel-matrix
cv::Mat result; std::vector<cv::Mat> channels; channels.push_back(r); channels.push_back(g); channels.push_back(b); channels.push_back(a); cv::merge(channels, result);
- 複チャンネル画像のピクセル値
cout << img.at<cv::Vec3b>(50, 50) - img.at<cv::Vec3b>(50, 50) << endl;
ベクトル
- ベクトルの大きさ (ノルム)
cout << cv::norm(img.at<cv::Vec4b>(50, 50), NORM_L2) << endl; 注: using namespace cv; を書いておかないと, NORM_L2が定義されていない, と起こられる。 注: ベクトルを2つ並べると, それらの間の距離を求めてくれる。
サンプル(画像処理)
// 画像を読んで表示するだけのプログラム (C++言語) // Ubuntu 14.04で動作確認済み。 // compile: $ g++ test.cpp -lopencv_core -lopencv_highgui # include <opencv2/core/core.hpp> # include <opencv2/highgui/highgui.hpp> int main() { cv::Mat image = cv::imread("test.jpg"); // imreadはhighguiの関数 cv::imshow("Look at me!", image); // imshowはhighguiの関数 cv::waitKey(0); }
// 画像を読んで劣化させて表示するプログラム (C++言語) // Ubuntu 14.04で動作確認済み。 // compile: $ g++ test.cpp -lopencv_core -lopencv_highgui -lopencv_imgproc # include <opencv2/core/core.hpp> # include <opencv2/highgui/highgui.hpp> # include <opencv2/imgproc/imgproc.hpp> int main() { cv::Mat image = cv::imread("test.jpg"); // imreadはhighguiの関数 cv::Mat fg; cv::erode(image,fg,cv::Mat(),cv::Point(-1,-1),2); // erodeはimgprocの関数 cv::imshow("Look at me!", fg); // imshowはhighguiの関数 cv::waitKey(0); }
サンプル(行列計算)
// test_OpenCV1.cpp // 単位行列 #include <opencv2/opencv.hpp> int main(){ cv::Mat M = cv::Mat::eye(3, 3, CV_8U); std::cout << M << std::endl; } $ g++ test_OpenCV1.cpp -lopencv_core $ ./a.out [1, 0, 0; 0, 1, 0; 0, 0, 1]
// test.cpp // 要素を明示して行列を直接定義 #include <iostream> #include <opencv2/core/core.hpp> using namespace std; int main(int argc, char *argv[]){ cv::Mat m1 = (cv::Mat_<double>(3, 3) << 1,2,3,4,5,6,7,8,9); cout << m1 << endl; } $ g++ test.cpp -lopencv_core $ ./a.out [1, 2, 3; 4, 5, 6; 7, 8, 9]
- 列ベクトル平均その他 http://opencv.jp/cookbook/opencv_mat.html#id30
- 平均と標準偏差:
cv::Scalar mean, stddev; meanStdDev(m1, mean, stddev);
- 行列全体での最大値・最小値
double min, max; cv::minMaxLoc(a, &min, &max);
- 数値の型変換
cv::Mat a=... a.convertTo(b, CV_8U);
- ヒストグラム均一化
cv::Mat a, b; cv::equalizeHist(a, b);
- 関心領域
cv::Mat m1 = (cv::Mat_<double>(2, 3) << 1,2,3,4,5,6); cv::Rect roi(1,0,2,2); cv::Mat m2(m1, roi);
- 行の追加・削除
m1.resize(5); // 5行の行列にする(足りなければ追加, 多過ぎたら削除)
- 行列の縮約(行に、または列に。和・平均・最大値などで)
cv::Mat v1; cv::reduce(m1, v1, 1, CV_REDUCE_SUM); cout << v1 << endl;
- 特定の場所の値を抽出
cout << m1.at<double>(2,3) << endl; 注意: ファイルに書き出すと, (2, 3)の位置は, 2ライン目の3ピクセル目。多くの場合, (y, x)
- 特定の場所に値を設定
m1.at<double>(0,0)=5;
- 行列の要素同士の積
m3=m1.mul(m2);
Keyword(s):
References:[とらりもんHOME]