説明
- OpenCVにはラベリング処理の関数がありません。ありそうなものなのに。
- すごくいい感じのラベリングクラスが公開されているのを見つけたので、OpenCVと連携させるサンプルを書いてみました。
ラベリングクラス
ダウンロード
サンプルの説明
- 読み込んだ画像にラベリング処理を加え、何かキーが押されるまで停止します。
- 画像をマウスでクリックすると、その領域に割り当てられたラベルナンバーが標準出力に表示されます。
//==============================================================================
//?C???N???[?h
//==============================================================================
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;
//???C?u??????????
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")
//???x?????O?N???X
//http://chihara.naist.jp/people/STAFF/imura/products/labeling
#include "Labeling.h"
//==============================================================================
//?O???[?o?????
//==============================================================================
IplImage *image;
short *dst;
LabelingBS labeling;
//------------------------------------------------------------------------------
//IplImage??C??s?N?Z????A?N?Z?X????????
//------------------------------------------------------------------------------
inline unsigned char getPixel(IplImage *image, int x, int y, int index)
{
return (uchar)image->imageData[y*image->widthStep + x*image->nChannels + index];
}
//------------------------------------------------------------------------------
//?}?E?X?R?[???o?b?N
//------------------------------------------------------------------------------
void onMouse(int event, int x, int y, int flags)
{
switch (event) {
//?N???b?N??u?E??????l?E???x???i???o?[??o??
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;
}
}
//------------------------------------------------------------------------------
//???C??
//------------------------------------------------------------------------------
int main()
{
char *filename = "test.bmp";
char *window_name = "Labeling Sample";
cvNamedWindow(window_name);
// ?R?[???o?b?N?????Z?b?g
cvSetMouseCallback(window_name, (CvMouseCallback)onMouse);
//??????????E??l??
image = cvLoadImage(filename, 0); // 0: ?O???C?X?P?[?????????
cvThreshold(image, image, 128, 255, CV_THRESH_BINARY);
//???x?????O?????????p?z??
dst = new short[ image->width * image->height ];
//???x?????Oタ?s
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 ???o?b?t?@
// DstT *result ??o?b?t?@
// int target_width ?o?b?t?@???T?C?Y
// int target_height ?o?b?t?@??c?T?C?Y
// bool is_sort_region ?A?????????~??\?[?g????
// int region_size_min ??????T?C?Y(????????????
//------------------------------------------------------------------------------
//??????o??
cout << "number of regions: " << labeling.GetNumOfRegions() << endl;
//?????\ヲ?E?L?[?????
cvShowImage(window_name, image);
cvWaitKey(-1);
//?????
delete dst;
cvReleaseImage(&image);
cvDestroyAllWindows();
return 0;
}