AR.Droneで物体検出

今回は色ベースで物体検出をしていきます。

色の抽出にはHSV表色系を用います。

手順は以下の通りです。
1. RGBからHSVに変換
2. 閾値処理で2値化
3. 一番大きな輪郭を抽出

2値化に関してはcvInRangeS()を使っています。
cvThreshold()の方がメジャーですが、Hue==0を扱うことができません。

#include "ardrone/ardrone.h"

#define KEY_DOWN(key) (GetAsyncKeyState(key) & 0x8000)
#define KEY_PUSH(key) (GetAsyncKeyState(key) & 0x0001)

// --------------------------------------------------------------------------
// main(引数の数、引数リスト)
// メイン関数です
// 戻り値 正常終了:0 エラー:-1
// --------------------------------------------------------------------------
int main(int argc, char **argv)
{
// AR.Droneクラス
ARDrone ardrone;

// 初期化
if (!ardrone.open()) {
printf("初期化に失敗しました\n");
return -1;
}

// 閾値
int minH = 0, maxH = 255;
int minS = 0, maxS = 255;
int minV = 0, maxV = 255;

// ウィンドウ
cvNamedWindow("binalized");
cvCreateTrackbar("H max", "binalized", &maxH, 255);
cvCreateTrackbar("H min", "binalized", &minH, 255);
cvCreateTrackbar("S max", "binalized", &maxS, 255);
cvCreateTrackbar("S min", "binalized", &minS, 255);
cvCreateTrackbar("V max", "binalized", &maxV, 255);
cvCreateTrackbar("V min", "binalized", &minV, 255);
cvResizeWindow("binalized", 0, 0);

// メインループ
while (!GetAsyncKeyState(VK_ESCAPE)) {
// 更新
if (!ardrone.update()) break;

// 画像を取得
IplImage *image = ardrone.getImage();

// HSVに変換
IplImage *hsv = cvCloneImage(image);
cvCvtColor(image, hsv, CV_RGB2HSV_FULL);

// 2値化画像
IplImage *binalized = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);

// 2値化
CvScalar lower = cvScalar(minH, minS, minV);
CvScalar upper = cvScalar(maxH, maxS, maxV);
cvInRangeS(hsv, lower, upper, binalized);

// 結果を表示
cvShowImage("binalized", binalized);

// ノイズ除去
cvMorphologyEx(binalized, binalized, NULL, NULL, CV_MOP_CLOSE);

// 輪郭検出
CvSeq *contour = NULL, *maxContour = NULL;
CvMemStorage *contourStorage = cvCreateMemStorage();
cvFindContours(binalized, contourStorage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

// 一番大きな輪郭を抽出
double max_area = 0.0;
while (contour) {
double area = fabs(cvContourArea(contour));
if (area > max_area) {
maxContour = contour;
max_area = area;
}
contour = contour->h_next;
}

// 検出できた
if (maxContour) {
// 結果を表示
CvRect rect = cvBoundingRect(maxContour);
CvPoint minPoint, maxPoint;
minPoint.x = rect.x;
minPoint.y = rect.y;
maxPoint.x = rect.x + rect.width;
maxPoint.y = rect.y + rect.height;
cvRectangle(image, minPoint, maxPoint, CV_RGB(0,255,0));
}

// メモリ解放
cvReleaseMemStorage(&contourStorage);

// 表示
cvShowImage("camera", image);
cvWaitKey(1);

// メモリ解放
cvReleaseImage(&hsv);
cvReleaseImage(&binalized);
}

// さようなら
ardrone.close();

return 0;
}

cvBoundingRect()で矩形(くけい)を包含する四角形を描画しています。

cvMoment()を使えば重心位置を算出できます。

detect_halo.jpg

見える、私にも見えるぞ!
関連記事

コメントの投稿

非公開コメント

プロフィール

puku

Author:puku
暇な時はゲームかプログラミングしてる人だよ。
だいたい月1更新。
CV Drone はこちら(GitHub)

最近はQiitaでOnsenUI2で遊んでいる。

最新記事
最新コメント
最新トラックバック
検索フォーム
カレンダー
04 | 2023/05 | 06
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -
月別アーカイブ
カテゴリ
スポンサードリンク
RSSリンクの表示
FC2カウンター
リンク
ブロとも申請フォーム

この人とブロともになる

アクセスランキング
[ジャンルランキング]
コンピュータ
822位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
152位
アクセスランキングを見る>>
FC2ブログランキング

FC2Blog Ranking

QRコード
QR