とらりもんHOME  Index  Search  Changes  Login

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);
}
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/

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);
Last modified:2020/02/11 23:10:13
Keyword(s):
References:[とらりもんHOME]