移動する物体を追跡する

OpenCVは2値画像では白をモノとして認識する

ダンゴムシは黒色でした。そのため、2値化しても黒くなっています。OpenCVに限らずほとんどの画像処理ライブラリは2値画像においては白をモノとして認識します。したがって、後々の処理の際に便利になるので、この時点で色を反転し、ダンゴムシを白にしてしまいましょう。色の反転は簡単です。チルダ「~」をMat型の前につけると反転した画像になります。下の例のようにします。

Mat img = imread("sample.png", IMREAD_UNCHANGED);
img = ~img; //反転したimgをimgに入れる

膨張処理

ダンゴムシの動画を2値化したときのダンゴムシの部分を拡大したのが下の画像の左です。中央の画像はさらに色反転を行ったものです。このまま輪郭を検出することにより、ダンゴムシの認識をしても良いのですが、左側に白い部分が欠けている部分があるため、おそらく楕円形状と認識することはできません。よって、この穴を埋める処理、すなわち、白い部分を膨らませる処理を行います。これはdilate関数により実装されています。今回の動画では3回、この膨張処理を行うことで穴を無くしています(下の画像右)。ただし、膨張処理をした後の画像から面積などを求めるのは不適当であるということには注意してください。文字通り、大きくなっています。

#include "opencv/cv.h"
#include "opencv/highgui.h"
using namespace cv;

int main(){
    Mat img;
    Mat gray_img;
    Mat bin_img;
    Mat element = Mat::ones(3,3,CV_8UC1); //追加 3×3の行列で要素はすべて1 dilate処理に必要な行列
    VideoCapture cap("pillbug.mp4");
    int max_frame=cap.get(CV_CAP_PROP_FRAME_COUNT);
    for(int i=0; i<max_frame;i++){ cap>>img;
        cvtColor(img, gray_img, CV_BGR2GRAY);
        threshold(gray_img,bin_img,70,255,THRESH_BINARY);
        //追加ここから
        bin_img=~bin_img; //色反転
        dilate(bin_img, bin_img, element, Point(-1,-1), 3); //膨張処理3回 最後の引数で回数を設定
        //追加ここまで
        imshow("Video",bin_img);
        waitKey(1);
    }
    return 0;
}