イントロダクション

OpenCV 2.0 から新たに,モダンな C++ インタフェースが導入されました. これは,短くて明瞭(短いコードで同じことができる),かつ型安全( CvArr* ,いわゆる void* が不要に)で, OpenCV をより便利に使えるようになっています.ここでは,その簡単な例を紹介します:

//
// 輝度チャンネルにノイズを加え,彩度チャンネルの輝度値を減らすことで,
// 簡単なレトロ写真風の効果を与えます.
//

// 以前と同様に,標準の OpenCV ヘッダをインクルードします.
#include "cv.h"
#include "highgui.h"

// 新しいAPIは,"cv" という名前空間内に存在します.
using namespace cv;

// 以下のコードで,API の混合利用の有効と無効を切り替えます.
#define DEMO_MIXED_API_USE 1

int main( int argc, char** argv )
{
    const char* imagename = argc > 1 ? argv[1] : "lena.jpg";
#if DEMO_MIXED_API_USE
    // Ptr<T> は,参照カウントを行う安全なポインタクラスです.
    Ptr<IplImage> iplimg = cvLoadImage(imagename);

    // cv::Mat は CvMat と IplImage を置き換えますが,
    // 新旧のデータ構造間の変換は簡単です.
    // (デフォルトでは,ヘッダのみが変換されデータは共有されます)
    Mat img(iplimg);
#else
    // cvLoadImage に代わる新しい関数は MATLAB 形式の名前です.
    Mat img = imread(imagename);
#endif

    if( !img.data ) // 画像が適切に読み込まれたかどうかをチェックします.
        return -1;

    Mat img_yuv;
    // 画像を,YUV 色空間に変換します.
    // 出力画像のメモリは,自動的に確保されます.
    cvtColor(img, img_yuv, CV_BGR2YCrCb);

    // 画像を色平面毎に分割します.
    vector<Mat> planes;
    split(img_yuv, planes);

    // 別の形式の Mat コンストラクタです.
    // 指定されたサイズ,型の行列を確保します.
    Mat noise(img.size(), CV_8U);

    // 行列を正規分布する乱数値で埋めます.
    // 一様分布の乱数を使う場合は, randu() .
    // CvScalar は Scalar に,cvScalarAll() は Scalar::all() に置き換わります.
    randn(noise, Scalar::all(128), Scalar::all(20));

    // ノイズを少し平滑化します.
    // カーネルサイズは 3x3 ,シグマは共に 0.5 に設定します.
    GaussianBlur(noise, noise, Size(3, 3), 0.5, 0.5);

    const double brightness_gain = 0;
    const double contrast_gain = 1.7;
#if DEMO_MIXED_API_USE
    // IplImage または CvMat に対してのみ動作する関数でも,
    // そこに新しい形式の行列を渡すのは簡単です.
    // ステップ1) - ヘッダを変換,データはコピーされません.
    IplImage cv_planes_0 = planes[0], cv_noise = noise;
    // ステップ2) - 関数の呼び出し.ポインタを渡すので,単項演算子 "&" を忘れないように.
    cvAddWeighted(&cv_planes_0, contrast_gain, &cv_noise, 1,
                 -128 + brightness_gain, &cv_planes_0);
#else
    addWeighted(planes[0], constrast_gain, noise, 1,
                -128 + brightness_gain, planes[0]);
#endif
    const double color_scale = 0.5;
    // cvConvertScale は, Mat::convertTo() に置き換わります.
    // 出力行列の型(ここではそのまま,つまり planes[1].type() を渡します)
    // を明示的に指定する必要があります.
    planes[1].convertTo(planes[1], planes[1].type(),
                        color_scale, 128*(1-color_scale));

    // コンパイル時にデータ型が分かっている場合(ここでは, "uchar" )に
    // 利用できる, convertTo の別の形式です.
    // この表記法は,テンポラリな配列を作成せず,上述の表記法とほぼ同じ速度です.
    planes[2] = Mat_<uchar>(planes[2]*color_scale + 128*(1-color_scale));

    // cvMul() は, Mat::mul に置き換わります.このシンプルな表記法でも,
    // テンポラリな配列は作成されません.
    planes[0] = planes[0].mul(planes[0], 1./255);

    // 結果をマージして元に戻します.
    merge(planes, img_yuv);
    // そして,出力 RGB 画像を作成します.
    cvtColor(img_yuv, img, CV_YCrCb2BGR);

    // これは cvNamedWindow に相当します.
    namedWindow("image with grain", CV_WINDOW_AUTOSIZE);
#if DEMO_MIXED_API_USE
    // これは img と iplimg が本当にデータを共有していることを示します.
    // これまでの処理結果は img に格納されており,したがって iplimg 内にも存在します.
    cvShowImage("image with grain", iplimg);
#else
    imshow("image with grain", img);
#endif
    waitKey();

    return 0;
    // vector<>, Mat, Ptr<> のデストラクタにより,
    // すべてのメモリは自動的に解放されます.
}

このイントロダクションでは,以下の「チートシート」に従って,新しいインタフェースの重要な特徴についてさらに詳しく述べます.

前のトピックへ

OpenCV 2.2 (r4295) C++ リファレンス

次のトピックへ

C++ チートシート

このページ