OpenCV 3.1 + contrib

CV Drone付属のOpenCVライブラリを3.1にバージョンアップしました。

cvdrone_opencv31.png
https://github.com/puku0x/cvdrone


最近ほとんどメンテできてなかったので、そのお詫びとしては何ですが、今回は標準モジュールの他に「opencv_contrib」モジュールも同梱しております。

opencv_contribモジュールで追加される機能は、
・深層学習
・SfM (複数画像からの3D形状復元)
・ARマーカ検出
・テキスト検出
・RGB-D処理 (Kinect系)
などなど、面白そうなものがたくさんあってオラ、ワクワクすっぞ!
スポンサーサイト



AR調べもの

久しぶりにAR調べてたら、More Than TechnologyのRoy氏がマーカレスARのサンプル更新してました。



コードはこちらで紹介されています。
http://www.morethantechnical.com/2015/03/16/bootstrapping-planar-ar-tracking-without-markers-wcode/#more-1647

2010年のサンプルより洗練されてる?
http://www.morethantechnical.com/2010/03/06/implementing-ptam-stereo-tracking-and-pose-estimation-for-ar-with-opencv-w-code/

さすがRoy神!俺達にできない事を (ry

5点アルゴリズムで遊んでたアレも掘り起こしてみるかな。

OpenCV 3.1リリース

OpenCV3.1がリリースされました。
http://opencv.org/opencv-3-1.html

今回の更新は、バグ修正メインですが、ちゃっかりVS2015とXCode7.1も正式サポートされるようになったようです。
よかったよかった。

CV Droneも追って3.1に対応する予定です。
opencv_contribも入れるかどうかは考え中です。

CamShift使ってみた

OpenCV付属のサンプルもありますが、もっと短くしたかったので。
CamShiftアルゴリズムで選択範囲をトラッキングするコードです。

// OpenCV 2.0
#include <opencv2/opencv.hpp>

// マウスコールバック関数に渡す用
struct MOUSE_CALLBACK_DATA {
int trackObject;
bool selectObject;
cv::Point origin;
cv::Rect selection;
};

// マウスコールバック関数
static void onMouse(int event, int x, int y, int flag, void *arg)
{
MOUSE_CALLBACK_DATA *data = (MOUSE_CALLBACK_DATA*)arg;

if (data->selectObject) {
data->selection.x = MIN(x, data->origin.x);
data->selection.y = MIN(y, data->origin.y);
data->selection.width = std::abs(x - data->origin.x);
data->selection.height = std::abs(y - data->origin.y);
}

switch (event) {
case cv::EVENT_LBUTTONDOWN:
data->origin = cv::Point(x, y);
data->selection = cv::Rect(x, y, 0, 0);
data->selectObject = true;
break;
case cv::EVENT_LBUTTONUP:
data->selectObject = false;
if (data->selection.width > 0 && data->selection.height > 0) data->trackObject = -1;
break;
}
}

// メイン関数
int main(int argc, const char *argv[])
{
// 最初に見つかったカメラを開く
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cout << "カメラの初期化に失敗しました" << std::endl;
return -1;
}

// 閾値
MOUSE_CALLBACK_DATA data = { 0 };
int vmin = 10, vmax = 256, smin = 30;
cv::namedWindow("Histogram");
cv::namedWindow("CamShift Demo");
cv::setMouseCallback("CamShift Demo", onMouse, &data);
cv::createTrackbar("Vmin", "CamShift Demo", &vmin, 256);
cv::createTrackbar("Vmax", "CamShift Demo", &vmax, 256);
cv::createTrackbar("Smin", "CamShift Demo", &smin, 256);

// ヒストグラム
cv::Mat hist;
cv::Mat histimg = cv::Mat::zeros(200, 320, CV_8UC3);
cv::Rect trackWindow;
int hsize = 16;
float hranges[] = { 0, 180 };
const float* phranges = hranges;

while (1) {
// キー入力
char c = cv::waitKey(10);
if (c == 0x1b) break;

// 画像を取得
cv::Mat image;
cap >> image;
if (image.empty()) break;

// HSVに変換
cv::Mat hsv;
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);

if (data.trackObject) {
// 閾値処理
cv::Mat mask;
cv::Scalar lower( 0, smin, MIN(vmin, vmax));
cv::Scalar upper(180, 256, MAX(vmin, vmax));
cv::inRange(hsv, lower, upper, mask);

// Hueだけ抽出
int ch[] = { 0, 0 };
cv::Mat hue(hsv.size(), hsv.depth());
mixChannels(&hsv, 1, &hue, 1, ch, 1);

// 矩形領域を選択した
if (data.trackObject < 0) {
// 追跡窓を設定
trackWindow = data.selection;
trackWindow &= cv::Rect(0, 0, image.cols, image.rows);

// ヒストグラムを計算
cv::Mat roi(hue, trackWindow), maskroi(mask, trackWindow);
cv::calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
cv::normalize(hist, hist, 0, 255, cv::NORM_MINMAX);

// 表示用にRGBに変換
histimg = cv::Scalar::all(0);
int binW = histimg.cols / hsize;
cv::Mat buf(1, hsize, CV_8UC3);
for (int i = 0; i < hsize; i++) buf.at<cv::Vec3b>(i) = cv::Vec3b(cv::saturate_cast<uchar>(i*180. / hsize), 255, 255);
cv::cvtColor(buf, buf, cv::COLOR_HSV2BGR);

// ヒストグラムを描画
for (int i = 0; i < hsize; i++) {
int val = cv::saturate_cast<int>(hist.at<float>(i)*histimg.rows / 255);
cv::rectangle(histimg, cv::Point(i*binW, histimg.rows), cv::Point((i + 1)*binW, histimg.rows - val), cv::Scalar(buf.at<cv::Vec3b>(i)), -1, 8);
}

// トラッキングを開始
data.trackObject = 1;
}

// バックプロジェクション
cv::Mat backproj;
cv::calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
backproj &= mask;

// CamShiftアルゴリズム
cv::RotatedRect trackBox = cv::CamShift(backproj, trackWindow, cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 10, 1));

// 表示
ellipse(image, trackBox, cv::Scalar(0, 0, 255), 3, cv::LINE_AA); // cv::LINE_AA=16
}

// 選択領域を表示
if (data.selectObject && data.selection.width > 0 && data.selection.height > 0) {
cv::Rect roi = data.selection & cv::Rect(0, 0, image.cols, image.rows);
cv::Mat tmp(image, roi);
cv::bitwise_not(tmp, tmp);
}

// 表示
cv::imshow("CamShift Demo", image);
cv::imshow("Histogram", histimg);
}

return 0;
}

cv::Rectが&で論理積できるなんて初めて知った。。。

Latent SVM 使ってみた

流行りのLatent-SVMに手を出してみました。

Latent-SVMはモデルをいろんなパーツを持った集合として捉え、モデルの隠れ変数となっている各パーツの位置関係を学習する手法です。参考URL → http://www.cs.berkeley.edu/~rbg/latent/

OpenCVにも実装されているので早速サンプルを動かしてみましょう!

#include <opencv2/opencv.hpp>

// --------------------------------------------------------------------------
// main(Number of arguments, Argument values)
// Description : This is the entry point of the program.
// Return value : SUCCESS:0 ERROR:-1
// --------------------------------------------------------------------------
int main(int argc, char **argv)
{
// 画像
cv::Mat image = cv::imread("cat.jpg");

// モデルデータ
std::vector<std::string> models;
models.push_back("cat.xml");

// LSVM
cv::LatentSvmDetector detector(models);

// 検出
std::vector<cv::LatentSvmDetector::ObjectDetection> detections;
detector.detect(image, detections);

// クラス名
const std::vector<std::string> classNames = detector.getClassNames();

// 検出したモデルの表示
for (size_t i = 0; i < detections.size(); i++) {
const cv::LatentSvmDetector::ObjectDetection &od = detections[i];
cv::rectangle(image, od.rect, CV_RGB(0, 255, 0), 2);
cv::putText(image, classNames[od.classID], cv::Point(od.rect.x+4, od.rect.y+13), cv::FONT_HERSHEY_SIMPLEX, 0.55, CV_RGB(255, 255, 255), 2);
}

// 画像表示
cv::imshow("cat", image);
cv::waitKey(0);

return 0;
}

lsvm_cat.jpg
ネコネコカワイイヤッター!

なんだか猫以外も検出していますね。

これ以外の学習済みモデルはopencv_extraにあります。いろいろ試してみましょう。

あれ?でもこれどうやって学習データ作るんだ?
プロフィール

puku

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

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

最新記事
最新コメント
最新トラックバック
検索フォーム
カレンダー
02 | 2023/03 | 04
- - - 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カウンター
リンク
ブロとも申請フォーム

この人とブロともになる

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

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

FC2Blog Ranking

QRコード
QR