OpenCV tips
- Mat(C++)とCvMat(C)の変換
// Mat → CvMat 代入で変換. Mat img1; CvMat _img1 = img1; // CvMat → Mat コンストラクタで変換. CvMat img2; Mat _img2(img2);
どちらの変換もデータはコピーされず参照する
- Matの初期化
Mat m1(3, 3, CV_32F, Scalar(0)); Mat m2(3, 3, CV_32F, 0); // これだと0で初期化されない Mat m2(3, 3, CV_32F, 5); // 0以外は初期値として使われるがScalar()を使ったほうが良い
Matの初期化にはScalar()を使う
- Matのビット深度(ID)をチェック
std::cout << "depth(ID):" << img.depth() << endl; //CV_8U -> 0 //CV_8S -> 1 //CV_16U -> 2 //CV_16S -> 3 //CV_32S -> 4 //CV_32F -> 5 //CV_64F -> 6
ビット深度は、1ピクセル内の1チャンネルの値を何ビットで表すかということ
数字はビット数で、Uはunsigned、Sはsigned、Fはfloating pointの意味
- CSVファイルをMatに読み込み(行列数指定)
// -------------------------------------------------------------------------------------- // CSV読み込み // // 戻り値(bool) 成功 true 失敗 false // bool CsvRead(const char* filename, // CSVファイルの名前 Mat &m, // データを格納するMat const int rows, // 行数 const int cols) // 列数 { m.create(rows, cols, CV_64F); // CSVファイルを開く FILE *fp; errno_t err = fopen_s( &fp, filename, "r"); if ( err != 0 ) { fputs("file open error", stderr); return false; } // CSVデータ読み込み char line_buffer[1024]; for(int row = 0; ( (int)fgets( line_buffer, 1024 - 1, fp ) != EOF ) && row < rows; row++) { if ( strchr( line_buffer, '\n') != NULL ) { line_buffer[strlen(line_buffer)-1] = '\0'; } char *sep_char_pointer; char *data_pointer = line_buffer; for ( int col = 0; col < cols; col++ ) { m.at<double>(row, col) = atof( data_pointer ); sep_char_pointer = strchr( data_pointer, (int)','); data_pointer = sep_char_pointer + 1; } } fclose(fp); return true; }
- Pixelにアクセス
Mat img(row, col, CV_8UC3); Mat_<Vec3b>& imgV = (Mat_<Vec3b>&)img; b = imgV(y, x)[0]; g = imgV(y, x)[1]; r = imgV(y, x)[2];
- カラー画像をRGB各チャネル画像に分離
Mat imgColor(row, col, CV_8UC3); vector<Mat> planes; split(imgColor, planes);
- グレー画像3枚でカラー画像を作成
Mat imgColor;
merge(vector<Mat>(3, imgGray), imgColor);
- 重心の計算
Mat img(100, 100, CV_8U); // 処理画像 Moments m = moments(img, true); // モーメントを計算 int cx = (int)(m.m10/m.m00); // 重心のX座標 int cy = (int)(m.m01/m.m00); // 重心のY座標
0以外の値を持った画素領域の重心
- 画素数のカウント
Mat img(100, 100, CV_8U); // 処理画像 Moments m = moments(img, true); // モーメントを計算 int count = (int)m.m00; // 値を持った画素数
- 輝度ウインドウ処理を施して画面表示
void WindowedShow(const string& windowName, // 表示するウインドウ名 const Mat& img, // 画像データ const double windowMin, // 輝度ウインドウの下限 const double windowMax) // 輝度ウインドウの上限 { Mat imgShow(img.size(), CV_8U); img.convertTo(imgShow, CV_8U, 255.0/(windowMax - windowMin), -windowMin); namedWindow(windowName, CV_WINDOW_AUTOSIZE); imshow(windowName, imgShow); }
実数型や16bit整数型のイメージを表示する時に使う
最小値、最大値はcv::minMaxLoc(img, &min, &max)で取得可能
- 画像全体のPixel値をシフトする
cv::Mat img(height, width, CV_8U, (void*)pdata); int shift = -5; // img = img + shift とは書けない cv::add(img, (double)shift, img); // これが正解 // 同時に型の変換も行うconvertTo()も使える // imgCvrt = img * gain + bias; img.convertTo(imgCvrt, CV_32F, gain, bias);
随時更新します。