粒をカウントする (粒子解析)

  1. 粒をカウントする (粒子解析)
  2. 一般的な2値化と適応的な2値化
  3. 収縮処理:OpenCVは2値画像では白をモノとして認識する
  4. 輪郭を検出して重心を求める

画像を表示する

最終的な目的は種子数のカウントですが、まずは画像を表示することから始めましょう。これは画像へのパスは各々で画像の置いてある場所に合わせてください。

#include "opencv/cv.h"
#include "opencv/highgui.h"
using namespace cv;
int main(){
    Mat img = imread("seed.jpg", IMREAD_UNCHANGED);
    imshow("IMAGE",img);
    waitKey(10000);
    return 0;
}

まずは一般的な2値化を試す

画像を2値化してみましょう。下に表示されたウィンドウのスクリーンショットを載せています。種子の部分が黒く、背景が白くなっていますが、四隅の部分では背景が暗かったため、種子が判別できません。

seed21

#include "opencv/cv.h"
#include "opencv/highgui.h"
using namespace cv;
int main(){
    Mat img = imread("seed.jpg", IMREAD_UNCHANGED);
    Mat gray_img;
    cvtColor(img, gray_img, CV_BGR2GRAY);
    Mat bin_img;
    threshold(gray_img, bin_img, 0, 255, THRESH_BINARY|THRESH_OTSU);
    imshow("IMAGE",bin_img);
    waitKey(10000);
    return 0;
}

適応的な2値化を試す

次に、周囲の明るさに応じて閾値を自動的に設定できる2値化手法を試してみましょう。adaptiveThreshold関数を使用します。下の例で99となっているのは、周囲の明るさを参考にするとき、どれくらいの広さまで勘定するかという広さを与えています。この場合は99×99の矩形領域になります。領域周囲が暗くなっていましたが、今回は周辺部分の種子も判別できそうです。

seed31

#include "opencv/cv.h"
#include "opencv/highgui.h"
using namespace cv;
int main(){
    Mat img = imread("seed.jpg", IMREAD_UNCHANGED);
    Mat gray_img;
    cvtColor(img, gray_img, CV_BGR2GRAY);
    Mat bin_img;
    //ここを変更
    adaptiveThreshold(gray_img, bin_img, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 99, 8); 
    imshow("IMAGE",bin_img);
    waitKey(10000);
    return 0;
}
1 2 3 4