motion を用いた動態検出と顔抽出の例

Rcpp Makevars

動態検出

motion を用いた動態検出と顔抽出の例

Web カメラの画像保存と動態検知を行う

手順

  1. Webカメラの設定
    sudo apt -y update
    sudo apt -y install uvccapture guvcview luvcview
    lsmod | grep uvc
    
  2. vlc で Web カメラの画像を確認
  3. motion のインストール
    sudo apt -y update
    sudo apt -y install motion
    lsmod | grep uvc
    
  4. /etc/motion/motion.conf の編集

    カメラにあわせて設定

    width 640
    height 480
    framerate 15
    
  5. motion でjpegファイル, swf ファイルを作成

    ファイルは/tmp/motion 下にできる

    sudo motion
    
  6. jpegファイルをaviファイルにエンコード

    ファイル名を連番画像に変えた後にエンコード

    i=1
    for f in *.jpg; do
     echo $f
     mv $f `printf "%07d" $i`.jpg
     i=$(($i+1))
    done
    ffmpeg -r 15 -i %07d.jpg -vcodec mjpeg -b:v 8000k -s 640x480 video.avi
    

https://www.kkaneko.jp/tools/od/info/2014-02-03

顔検出

  1. facedect.htmlに記載のサンプルプログラムを使う

    出典

    http://www.aianet.ne.jp/~asada/prog_doc/opencv/opencv_obj_det_img.htm

    https://www.kkaneko.jp/rinkou/bigdata/facedetect.html を使う

    次のように書き換える

    cvSaveImage("/tmp/out.jpg",tarImg,0);
    
  2. 顔検出の繰返し
    cp /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml .
    for f in *.jpg; do
      echo $f
      ./a.out $f
      cp /tmp/out.jpg `basename $f .jpg`-out.jpg
    done
    
  3. jpegファイルをaviファイルにエンコード

    ファイル名を連番画像に変えた後にエンコード

    ffmpeg -r 15 -i %07d-out.jpg -vcodec mjpeg -b:v 8000k -s 640x480 video2.avi
    
  4. 別の動画ファイル hoge.avi での操作手順例
    mkdir /tmp/d
    cd /tmp/d
    ffmpeg -i hoge.avi %07d.jpg
    cp /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml .
    for f in *.jpg; do
      echo $f
      /tmp/a.out $f
      cp /tmp/out.jpg `basename $f .jpg`-out.jpg
    done
    ffmpeg -r 30 -i %07d-out.jpg -vcodec mjpeg -b:v 8000k -s 640x360 video3.avi
    

fruits.jpg の解析(vlfeat の mser を使用) convert fruits.jpg mser fruits.pgm octave S = dlmread( "fruits.frame", " ", 1, 0 ); [rgb, map, alpha] = imread("fruits.pgm"); colormap(gray(256)); hold imshow(rgb); plot(S(:,1), S(:,2), '@'); print -dpng hoge.png
mkdir /tmp/d
cd /tmp/d
ffmpeg -i hoge.avi %07d.jpg
cp /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml .
#
cat >disp.oct <<-OCTAVE
S = dlmread( "fruits.frame", " ", 1, 0 );
[rgb, map, alpha] = imread("fruits.pgm");
colormap(gray(256));
hold
imshow(rgb);
plot(S(:,1), S(:,2), '@');
print -dpng hoge.png
OCTAVE
#
rm -f COUNT
for f in *.jpg; do
  echo $f
  rm -f fruits.pgm
  rm -f fruits.frame
  rm -f hoge.png
  convert $f fruits.pgm
  mser fruits.pgm
  octave --no-gui --no-history --no-init-file --silent disp.oct
  cp hoge.png `basename $f .jpg`-out.png
  wc fruits.frame  | sed 's/ /\t/g' | cut -f3 >> COUNT
done
ffmpeg -r 30 -i %07d-out.png -vcodec mjpeg -b:v 8000k -s 640x360 video3.avi

more using OpenCV

  1. OpenCV のビルド
    cd /tmp
    wget http://133.5.18.161/linux/opencv-2.4.8.tar.gz
    tar -xvzof opencv-2.4.8.tar.gz
    cd opencv-2.4.8
    sudo cmake -DWITH_GTK=ON -DWITH_OPENGL=ON -DWITH_QT=ON -DBUILD_SHAERD_LIBS=OFF -DBUILD_DOCS=ON -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=RELEASE -DINSTALL_C_EXAMPLES=ON -DWITH_OPENCL=OFF -DWITH_CUDA=OFF -DWITH_UNICAP=ON -DWITH_V4L=ON -DWITH_XINE=ON -DWITH_OPENEXR=ON -DBUILD_OPENEXR=ON
    sudo make -j4
    sudo make install
    cd samples
    cd c
    sudo make
    sudo bash build_all.sh
    cd ..
    tar -cvf /tmp/c.tar ./c
    cd /usr/local/share/OpenCV/samples
    sudo tar -xvf /tmp/c.tar
    
  2. /tmp/opencv-2.4.8/samples/c/adaptiveskindetector.cpp cvReleaseImage(&img); の前あたりに 次の2行を追加. cd /tmp/opencv-2.4.8/samples/c; sudo bash build_all.sh
    	std::sprintf(s, "/tmp/c/%07d-skin.jpg", numFrames);
    	cvSaveImage(s,img,0);
    

  3. /tmp/opencv-2.4.8/samples/c/motempl.c

    cvShowImage( "Motion", motion ); の次あたりに 次の4行を追加. cd /tmp/opencv-2.4.8/samples/c; sudo bash build_all.sh

            char buf[1024];
    	sprintf(buf, "/tmp/c/%07d-motion.jpg", i);
    	cvSaveImage(buf,motion,0);
    	i++;
    

  4. /tmp/opencv-2.4.8/samples/c/adaptiveskindetector の実行

    先ほどの連番jpeg画像を使う

    # mkdir /tmp/c
    # cd /tmp/c
    # # prepare hoge.avi
    # ffmpeg -i hoge.avi %07d.jpg
    # cd /tmp/c
    
    # /tmp/opencv-2.4.8/samples/c/adaptiveskindetector の実行
    cd /tmp/c
    cp /tmp/opencv-2.4.8/samples/c/adaptiveskindetector  /tmp/c
    ./adaptiveskindetector "/tmp/c/%07d.jpg" 1 1043
    ffmpeg -r 15 -i %07d-skin.jpg -vcodec mjpeg -b:v 8000k -s 640x480 skin2.avi
    
    #
    cd /tmp/c
    cp /tmp/opencv-2.4.8/samples/c/motempl /tmp/c
    ./motempl video.avi
    ffmpeg -r 15 -i %07d-motion.jpg -vcodec mjpeg -b:v 8000k -s 640x480 motion2.avi
    
    #
    cp /tmp/opencv-2.4.8/samples/c/smile_detect  /tmp/c
    ./adaptiveskindetector "/tmp/c/%07d.jpg" 0 6600
    
    

    sample 下の2つの program

    大勢の人が重なったり、つながっていても人を検出できる「HOG」のコードです。

    #include "stdafx.h"
    #include "opencv2\\opencv.hpp"
    
    using namespace cv;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    Mat img = imread("summit.bmp", 1);
    
    HOGDescriptor hog;
    //分類器の取得
    hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
    
    std::vector found;
    //HOG
    hog.detectMultiScale(img, found, 0, Size(3,3), Size(0, 0), 1.1, 2);
    
    std::vector::const_iterator it;
    for(it = found.begin(); it!=found.end(); ++it)
    {
    Rect r = *it;
    rectangle(img, r.tl(), r.br(), Scalar(255,0,0), 2);
    }
    
    // 結果の描画
    namedWindow("hog", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
    imshow( "hog", img );
    waitKey(0);
    
    return 0;
    }
    

    http://imagesensing.seesaa.net/article/251094189.html

    目の検出プログラムです。openCVは目を学習済みのため、教師データを参照するのみで目の検出処理が作成できます。とても便利です。

    #include "stdafx.h"
    #include "opencv2/opencv.hpp"
    
    using namespace cv;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    //入力画像
    Mat Img = imread("face.jpg", 1);
    
    //グレースケール画像(目検出の処理はグレースケール画像で行う))
    Mat GrayImg;
    
    //入力画像をグレースケール画像に変換
    cvtColor(Img, GrayImg, CV_BGR2GRAY);
    
    //目の教師データ(openCVはすでに目のデータを用意している))
    std::string nested_cascadeName = "C:\\OpenCV2.2\\data\\haarcascades\\haarcascade_eye.xml";
    CascadeClassifier nested_cascade;
    if(!nested_cascade.load(nested_cascadeName))
    return -1;
    
    std::vector nestedObjects;
    ///目の検出
    // 画像,出力矩形,縮小スケール,最低矩形数,(フラグ),最小矩形
    nested_cascade.detectMultiScale(GrayImg, nestedObjects,
    1.1, 3,
    CV_HAAR_SCALE_IMAGE,
    cv::Size(10,10));
    
    // 目の位置の表示
    for(std::vector::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); ++nr) {
    rectangle(Img, Point(nr->x,nr->y), cv::Point(nr->x + nr->width, nr->y + nr->height), cv::Scalar(255,0,0), 3, 4);
    }
    imshow( "result", Img );
    
    waitKey(0);
    
    return 0;
    }
    

    http://imagesensing.seesaa.net/article/214206116.html

    lbpcascade and haarcascade