ずっと”後でやる”状態だったOpenCVでヒストグラムを表示してみました。
インストール
そろそろ最新版がリリースされるという噂があるので、リポジトリのヘッドを使おうとしたのですが、全然ビルドが成功しないので、仕方なしに1.1pre版を使いました。環境はosx 10.5.4です。
$ wget http://sourceforge.net/projects/opencvlibrary/files/opencv-linux/1.1pre1/opencv-1.1pre1.tar.gz/download $ tar zxvf opencv-1.1pre1.tar.gz $ cd opencv-1.1pre1 $ ./make && make install
ヒストグラムの表示
opencv.jpのサンプルコードを参考にしながら書きました。描画処理が面倒だったので、画像を白黒でロードして1次元のヒストグラムをベタ書きしています。
#include < stdio .h > #include < cv .h > #include < highgui .h > IplImage* createHistgram(IplImage* srcImg, CvSize& imageSize); int main(int argc, char** argv) { // 画像読み込み(グレースケールで読み込み) char* imageFilename = "sample.jpg"; if (argc == 2) { imageFilename = argv[1]; } IplImage* img = cvLoadImage(imageFilename, CV_LOAD_IMAGE_GRAYSCALE); if (!img) { printf("@E failed to load image %s @\n", imageFilename); exit(-1); } // Window作成 char* windowTitle = "Original Image"; char* histWindowTitle = "Histgram"; cvNamedWindow(windowTitle, CV_WINDOW_AUTOSIZE); cvNamedWindow(histWindowTitle, CV_WINDOW_AUTOSIZE); // 元画像とヒストグラム表示 CvSize size = cvSize(256, 256); IplImage* histImg = createHistgram(img, size); cvShowImage(histWindowTitle, histImg); cvShowImage(windowTitle, img); // キー入力待ち cvWaitKey(0); // 破棄 cvReleaseImage(&img); cvReleaseImage(&histImg); cvDestroyAllWindows(); return 0; } IplImage* createHistgram(IplImage* srcImg, CvSize& imageSize) { // ヒストグラム作成 int channelSize[] = { 256 }; float levelRange[] = { 0, 256 }; float* range[] = { levelRange }; CvHistogram* hist = cvCreateHist(1, channelSize, CV_HIST_ARRAY, range, 1); cvCalcHist(&srcImg, hist); // ヒストグラム出力用画像作成 IplImage* dstImg = cvCreateImage(imageSize, IPL_DEPTH_8U, 1); cvSet(dstImg, cvScalarAll(255), 0); // ヒストグラムのスケール変換 float max = 0; cvGetMinMaxHistValue(hist, 0, &max, 0, 0); cvScale(hist->bins, hist->bins, ((double)dstImg->height) / max, 0); // 画像に出力 int binWidth = cvRound((double)imageSize.width / channelSize[0]); for (int i = 0; i < channelSize[0]; i++) { int histValue = cvRound(cvQueryHistValue_1D(hist, i)); CvPoint bottomLeft = cvPoint(i * binWidth, dstImg->height); CvPoint topRight = cvPoint((i+1) * binWidth, dstImg->height - histValue); cvRectangle(dstImg, bottomLeft, topRight, cvScalarAll(0), CV_FILLED, 8, 0); } // ヒストグラム破棄 cvReleaseHist(&hist); return dstImg; }
これをビルドすれば冒頭の画面が表示されます。普段スクリプト言語使ってると本当にビルドが面倒です。幾つかライブラリをリンクしないと駄目です。
TARGET = helloworld SRCS = helloworld.cpp INC = /usr/local/include/opencv LIB = -lcxcore -lcv -lhighgui all:$(TARGET) $(TARGET):$(SRCS) g++ $(SRCS) -o $(TARGET) -I$(INC) $(LIB) run:all ./$(TARGET) clean: rm $(TARGET)
まとめ
ドキュメントの質が非常に良くて、サンプルも豊富にあるので、割とスムーズにコーディングできました。感触としては画像の解析能力は思ったよりも強力で、サンプルを実行するだけで楽しいです。ただ表示に必要な出力系APIが貧弱なので、もっぱら解析用に使うのが良さそうだと思いました。
関連する記事
タグ: helloworld, opencv





