2013/10/27

OpenCVでfillConvexPolyを使って四角形や多角形を描画する

OpeCVの2.xのお話ですが,

OpenCVで任意の四角形や多角形を描画するときにはポリゴンを使って頂点をつなげて描画するみたいです.

初めは下記ので書かれている
cv::fillPoly
を使って書こうと思ったのですが,

描画処理 — OpenCV-CookBook
http://opencv.jp/cookbook/opencv_drawing.html

下記のサイトのfillPolyを見てみると,引数は次のように書かれています.
描画関数 — opencv v2.1 documentation
http://opencv.jp/opencv-2.1/cpp/drawing_functions.html

void fillPoly(Mat& img, const Point** pts, const int* npts, int ncontours, const Scalar& color, int lineType=8, int shift=0, Point offset=Point())

特に2個目の"Point**"とか渡さないといけなくて,なんか変だなと思っていました.

そしてなんとなく上の方を見てみると"fillConvexPoly"というのを見つけました.

void fillConvexPoly(Mat& img, const Point* pts, int npts, const Scalar& color, int lineType=8, int shift=0)

これだとPoint*を渡せばいいのでわかりやすいです.
また,「fillPolyよりも高速で動作する」とも書いています.
勝手に塗りつぶされるのがたまにキズですが,今回は塗りつぶされてもいいのでこれを使います.

"fillConvexPoly"を使ったサンプルプログラムを探したのですが,見つからなかったので,
自分で書きます.

/*****************************************************
    C++  のプログラム(Python版は下に書きます)
******************************************************/

次にプログラムを載せますが,
カメラで画像を取得して適当な4つの点を結ぶ四角形を描画します.
下のは四角形ですが,配列を増やせば多角形もいけます.


#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

int main(int argc, char *argv[])
{
  cv::VideoCapture cap(0);
  cap.set(CV_CAP_PROP_FRAME_WIDTH, 640);
  cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
  
  // カメラがオープンできたかの確認
  if(!cap.isOpened()) return -1;
  cv::namedWindow("Capture", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);

  while(1) {
    cv::Mat frame;
    cap >> frame;


    cv::Point pt[4]; //任意の4点を配列に入れる
    pt[0] = cv::Point(100, 100);
    pt[1] = cv::Point(150, 200);
    pt[2] = cv::Point(300, 300);
    pt[3] = cv::Point(400, 100);

    //描画 引数は (画像, 点の配列, 点の数, 色)
    cv::fillConvexPoly( frame, pt, 4, cv::Scalar(0,0,200) ); 
    
    cv::imshow("Capture", frame);
 
    if(cv::waitKey(30) >= 0){
      break;
    }
  }
}


実行結果はこのようになります.




#####################################
#   2015年1月18日 追記
#   コメントでPythonの方のプログラムのリクエストがあったので書きます。
#   Python のプログラム
#####################################
Ubuntu14.04
Python 2.7.6 , python-opencv 2.4.8
で確認しました。

引数などを確認すると
Drawing Functions — OpenCV 2.4.9.0 documentation
http://docs.opencv.org/modules/core/doc/drawing_functions.html#void%20fillPoly(Mat&%20img,%20const%20Point**%20pts,%20const%20int*%20npts,%20int%20ncontours,%20const%20Scalar&%20color,%20int%20lineType,%20int%20shift,%20Point%20offset)

cv2.fillConvexPoly(img, points, color[, lineType[, shift]])

となっています。
同じようにカメラ画像から取得した画像にfillConvexPolyで多角形を描画します。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import cv2
import numpy as np

def main():
    cap = cv2.VideoCapture(0)

    while(True):
        #カメラのキャプチャからフレームを取得する
        ret, frame = cap.read()
        #多角形を記述
        contours = np.array( [ [100,100], [100,230], [230, 250], [150,70] ] )
        #fillConvexPolyで多角形を描画
        cv2.fillConvexPoly(frame, points =contours, color=(0,0,255))

        cv2.imshow('Camera Capture', frame)

        #何かキーを押したら終了
        if cv2.waitKey(10) > 0:
            cap.release()
            cv2.destroyAllWindows()
            break

if __name__ == '__main__':
    main()

実行するとこのようになります。
これでおkです。






2 件のコメント:

  1. これpythonではどうしますか?

    返信削除
    返信
    1. コメント有り難うございます。
      Pythonで同じように描画をするプログラムを追加で載せてみました。

      削除