2017年3月7日火曜日

node-opencv で検出した物体の中心を算出する方法

概要

前回 Canny アルゴリズムを使って四角形を検出してみました
今回は検出した Contours (輪郭) の中心点を求める方法を紹介します

環境

  • Mac OS X 10.10.5
  • OpenCV .2.4.12
  • Nodejs 0.12.0
  • npm 2.5.1
  • node-opencv 5.0.0

四角形の中心点を検出するサンプル

スクリプトの全体は以下の通りです

  • vim draw_center.js
var cv = require('opencv');
var s = new cv.VideoCapture(0);

var camWidth = 320;
var camHeight = 240;
var rectColor = [0, 255, 0];
var rectThickness = 2;
s.setWidth(camWidth);
s.setHeight(camHeight);

var lowThresh = 0;
var highThresh = 100;
var nIters = 2;
var minArea = 2000;

var RED   = [0, 0, 255]; // B, G, R

var detect = function(){
  s.read(function(err, im){
    if (err) throw err;
    width = im.width();
    height = im.height();
    if (width < 1 || height < 1) throw new Error('Image has no size');
    im_canny = im.copy();
    im_canny.canny(lowThresh, highThresh, 3, true);
    im_canny.dilate(nIters);
    contours = im_canny.findContours();
    for (i = 0; i < contours.size(); i++) {
      if (contours.area(i) < minArea) continue;
      var arcLength = contours.arcLength(i, true);
      contours.approxPolyDP(i, 0.02 * arcLength, true);
      switch(contours.cornerCount(i)) {
        case 4:
          im.drawContour(contours, i, RED);
          var moments = contours.moments(i);
          var cgx = Math.round(moments.m10 / moments.m00);
          var cgy = Math.round(moments.m01 / moments.m00);
          im.line([cgx - 5, cgy], [cgx + 5, cgy], RED);
          im.line([cgx, cgy - 5], [cgx, cgy + 5], RED);
          console.log("detect rectangle, x: %d, y: d%", cgx, cgy)
      }
    }
    w = new cv.NamedWindow("shapes detect", 1);
    w.show(im);
    w.blockingWaitKey(0, 50);
    detect();
  })
}
detect();
  • node draw_center.js

ポイントは case: 4 で四角形を検出した後に contours.moments を使って Moments の情報を取得しているところです
m00, m01, m10, m11 は空間モーメントを保持しているフィールドでこれを使って中心点を算出することができます

あとは算出した空間モーメントの情報と im.line を使って動画に中心点を描画します

動作確認

実行して四角形のものを近づけると枠線と中心点が描画されているのがわかると思います
opencv_draw_center.png

ターミナルには検出した輪郭の中心点の情報が出力されます

detect rectangle, x: 157, y: d% 122

最後に

検出した四角形の中心点を算出して描画してみました

今回はグレースケールにしないで検出してみました
精度をあげる場合、普通はグレースケールにして影や反射などの影響を抑てください
サンプル用に描画した線がはっきりわかるようにカラーでやってみました

参考サイト

0 件のコメント:

コメントを投稿