Top > OpenCV > ラベリング
HTML convert time to 0.075 sec.


OpenCV/ラベリング

Last-modified: 2007-03-07 (水) 15:18:29

説明 Edit

  • OpenCVにはラベリング処理の関数がありません。ありそうなものなのに。
  • すごくいい感じのラベリングクラスが公開されているのを見つけたので、OpenCVと連携させるサンプルを書いてみました。



ラベリングクラス Edit

  • 奈良先端科学技術大学院大学 井村誠孝先生によるラベリングクラス
    URL:http://chihara.naist.jp/people/STAFF/imura/products/labeling
    使用方法のPDFも上記ページで公開されているので、参考にしてください。
    ラベリングサンプル画像をお借りしました。感謝!



ダウンロード Edit

  • コンパイルには Labeling.h が必要です。



サンプルの説明 Edit

  • 読み込んだ画像にラベリング処理を加え、何かキーが押されるまで停止します。
  • 画像をマウスでクリックすると、その領域に割り当てられたラベルナンバーが標準出力に表示されます。



fileLabelingSample.cpp

//==============================================================================
//インクルード
//==============================================================================
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;

//ライブラリ読み込み
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")

//ラベリングクラス
//http://chihara.naist.jp/people/STAFF/imura/products/labeling
#include "Labeling.h"


//==============================================================================
//グローバル変数
//==============================================================================
IplImage *image;
short *dst;
LabelingBS labeling;


//------------------------------------------------------------------------------
//IplImageの任意ピクセルにアクセスするための関数
//------------------------------------------------------------------------------
inline unsigned char getPixel(IplImage *image, int x, int y, int index)
{
    return (uchar)image->imageData[y*image->widthStep + x*image->nChannels + index];
}


//------------------------------------------------------------------------------
//マウスコールバック
//------------------------------------------------------------------------------
void onMouse(int event, int x, int y, int flags)
{
    switch (event) {
        //クリック位置・元画像の値・ラベルナンバーを出力
        case CV_EVENT_LBUTTONUP:
            cout << " x: " << x << ", y: " << y << endl;
            cout << "\tValue: " << (int)getPixel(image, x, y, 0) << endl;
            cout << "\tLabel: " << dst[y*image->width+x] << endl;
            break;
        default:
            break;
    }
}


//------------------------------------------------------------------------------
//メイン
//------------------------------------------------------------------------------
int main()
{
    char *filename = "test.bmp";
    char *window_name = "Labeling Sample";

    cvNamedWindow(window_name);

    // コールバック関数をセット
    cvSetMouseCallback(window_name, (CvMouseCallback)onMouse);

    //画像の読み込み・二値化
    image = cvLoadImage(filename, 0);  // 0: グレイスケールで読み込む
    cvThreshold(image, image, 128, 255, CV_THRESH_BINARY);

    //ラベリング処理の結果保存用配列
    dst = new short[ image->width * image->height ];

    //ラベリング実行
    labeling.Exec((uchar *)image->imageData, dst, image->width, image->height, false, 10);
    //------------------------------------------------------------------------------
    //int Exec( SrcT *target, DstT *result, int target_width, int target_height,
    //          const bool is_sort_region, const int region_size_min )
    //引数:
    //  SrcT *target 入力バッファ
    //  DstT *result 出力バッファ
    //  int target_width バッファの横サイズ
    //  int target_height バッファの縦サイズ
    //  bool is_sort_region 連続領域を大きさの降順にソートするか
    //  int region_size_min 最小の領域サイズ(これ未満は無視する)
    //------------------------------------------------------------------------------

    //領域数を出力
    cout << "number of regions: " << labeling.GetNumOfRegions() << endl;

    //画像を表示・キー入力待ち
    cvShowImage(window_name, image);
    cvWaitKey(-1);

    //終了処理
    delete dst;
    cvReleaseImage(&image);
    cvDestroyAllWindows();
    return 0;
}