ラベル OpenCV の投稿を表示しています。 すべての投稿を表示
ラベル OpenCV の投稿を表示しています。 すべての投稿を表示

2012/01/28

C++と仲直り計画: Cの構造体をスマートポインタで扱う (同時上映: ラムダ式もほんのちょっとかじる)

いきなりですが今日は boost::shared_ptr を構造体に対して用いるお話です。ここまで読んで、『何を今さら』と思った方はブラウザをそっと閉じると幸せになれますよ。

あと、今日の日記は解説というよりは備忘録的な色が強いので、僕と波長が合わないとなかなか内容に共感して頂けないかも知れません。そういう方もブラウザをそっt(ry


2011/09/14

OpenCV で Tilt Shift もどき

ある日突然、「3年生の向けの『画像情報処理』の演習課題を作ってほしい」と言われました。なんじゃそりゃ。

軽く考えていたものの、いざ作り始めてみると意外なほど制約が多い事に気付きました。

まず、この学校ではなぜか C++ のカリキュラムが存在しないため、サンプルコードもオブジェクト指向を極力避ける形になります。加えて、3年生は JABEE の関係上、非常に過酷な実験科目が別途課されているため、あんまり追いつめるわけにもいきません。

そんなこんなで、ひとまず「Gaussian フィルタによる画像平滑化を利用した Tilt Shift 画像の生成」と題して、デジカメで撮った写真をファンタジックに加工する処理でも実装して頂こうかと考えています。なんじゃそりゃ。



Tilt Shift で画像検索すると、風景がまるでジオラマのように写っている写真が多く見られます。この効果を狙って、Tilt Shift レンズが装着されているカメラも存在します(4月25日の日記参照)。

本来は、アオリ撮影を応用して被写界深度を狭めるテクニックなのですが、通常の画像でも簡単な画像処理を施す事によってその効果を疑似的に再現する事が可能です。

今回、試作したプログラムで写真を加工した結果はこんな感じになりました。

【Before】
↓
【After】

上下にぼかしが加わっているのがお判りいただけますでしょうか。

彩度やコントラストを強調したり、構図を工夫したりすれば、よりジオラマのような質感が得られますが、今回は簡単のため省略。

2011/05/24

『Kinectセンサープログラミング』買ってきた

【同時上映: ユーザー検出でバグってみた】

今日は、世界で初めて Kinect プログラミングを解説した技術書の発売日である。

ぼくはこれがすごく気になり、予約開始とともに Amazon に注文をして発売日を今か今かと待ちわびていたほどだった。

しかし突如として Amazon は予約を一方的にキャンセル。さらに「この本はお取り扱いできません」状態が今なお続いている。


仕方なくジュンク堂書店に行ってみたところ、出来たての『Kinect センサープログラミング』が折よく品出し用のワゴンに載っていたので早速ゲットして意気揚々と帰途についた。

『Kinect センサープログラミング』 ¥3,200 (税別)

さてさて。

 Kinect に関しては、このブログでもちょこちょこ言及してきたけれど、いかんせんぼくの調べ方が適当すぎて細かい誤解がいっぱいあった。

その中でも今回は、特に致命的だった事柄について述べたいと思う。

2011/05/16

Qt Designerとカスタムウィジェット

【Qt をもうちょっといじってみよう】

昨日に引き続き、Qt (+ OpenCV)のお勉強。表題でカスタムウィジェットとか言っているけど、単にこんなものを作っただけだったりして。
昨日と比べて、なんかスクロールバー的なものがくっついているあたりがおしゃれ。

2011/05/11

Qtはじめました

【動機】

最近、C++ で効率的に GUI を構築する手段を探している。

ちなみに僕はそれまで、C/C++ で GUI を構築する場合には Windows API を直接叩いていた。『猫でもわかる』に洗脳された身としては、このスタイルこそが最もスタンダードな選択肢だと信じていたためである。

しかしコレ、他言語(というか Java)と比較して生産性が圧倒的に悪い。

RAD ツールの出来不出来以前の問題として、そもそも API の仕様が洗練されていないのだ。長い Windows の歴史の中で建て増しを繰り返すうちにすっかりカオスになってしまったらしい。

そして残念ながら、これをがんばって身につけるメリットを、僕はあまり見いだす事ができなかった。

ロジックの本質とは今ひとつ関係のないソースコードばかりが肥大化して、保守性や拡張性が著しく低下するのはどう考えても残念だし、そもそも人様が書いた GUI 関連のコードなど読む気すらしない。

一方、C/C++ を使用する動機は、既存のソフトウェア資源が圧倒的に豊富だからという理由だけで充分である(ラッパを使う事で、他言語から C++ で書かれたライブラリを活用する事ももちろん可能だが、使用できるライブラリのバージョンに制約があったり、不整合が起きやすかったり、そもそもネイティブライブラリに加えてラッパの仕様を調べなきゃいけなくて二度手間だったりと色々面倒なのだ)。

このあたりのせめぎ合いをうまく調停できないだろうかと思っていたところ Qt なるものを見つけたので、早速試してみる事にした。

Qt は Windows / Mac / Linux で使える C++ 向け GUI ツールキットで、Wikipedia によると
QtはGTK+やMFC等、他の標準的なグラフィックツールキットに比べて、もっとも後発であることもあり、以前から存在するライブラリーのよいところを集めたアーキテクチャーとなっている。
だそうだ。なるほど。

さらに Qt SDK には Qt Creator なる統合開発環境が付属しており、グラフィカルにコンポーネントを配置できるナイスな RAD ツール(Qt Designer)も使える。

2011/05/06

OpenCV×文字認識エンジン

前回、形状マッチングで文字認識をさせようとして見事に失敗した。

しょうがないので、偉大な誰かが作った文字認識エンジンをありがたく使わせていただく事に。

そんなこんなで本日作ったガラクタは、以下のようなカメラ映像から、赤枠内の文字を認識してくれるというシロモノだよ。
こういうものを読み込ませると…。
こんなふうに認識してくれる。

2011/05/02

形状マッチングで文字認識をさせようとして失敗してみた

Web カメラから撮影した数字を自動的に認識できたらいいなぁと思い、こんなものを作ってみた。

Webカメラで撮った数字を認識しているところ。背景のコマンドプロンプトには識別した数値が表示されている。
その他のウィンドウ / 左:カメラの映像、右上:2値化してトリミングした画像、右下:対応するテンプレート画像。
一応、プログラム自体はできたのだけど、精度が悪過ぎて到底使い物にならなかった。

恥の記録として残しておく事にする。

2011/04/25

Kinectプチハック(エピソード4)

【ミッション: Kinectで立体復元に挑戦しよう】

前回奥行き情報を(一応)推定する事ができたので、そろそろ 3D にしてみようと思う。

本日のターゲットは、このどうしようもない写真。


これを、Kinect で適当に 3 次元復元して俯瞰したら、こうなった。

机上の本や PC はもちろん、部屋の隅っこの柱やパイプなどの凹凸がくっきり浮き出ている事が確認できる。

※ ちなみにぼくの隣は博士様の席なのだ。いないけど。

2011/04/22

Kinectプチハック(エピソード3)

【ミッション: Kinectから奥行き情報を推定しよう】

前回、カメラ画像に位置を合わせた深度データを取ってくる事ができたので、今回はそれを 3 次元的にマッピングしてみようと思った。

これは、椅子と机の一部の奥行きデータを3次元的にプロットした結果である。

2011/04/18

Kinectプチハック(エピソード2)

【ミッション: OpenCVでNiSimpleViewerもどきを作ろう】

前回、Kinect の深度データと RGB 画像を OpenCV の IplImage で取得する実験をしてみた。

この調子で、OpenNI Tips に載っている『デプスと画像を重ね合わせするデモのサンプルコード』を試してみよう。


…って、あれ? ずれていてうまく重ならない。なにこれダメじゃん。

どうやら、深度センサとカメラの位置が微妙にずれているため、単なるオーバレイ表示にしただけではダメらしい。

2011/04/13

Kinectプチハック

【ミッション: Kinectのカメラ映像をIplImageに変換して使おう】

前回のあらすじ: OpenNI を入れた。

Kinect のカメラ、及び深度データを OpenCV で使うための最小限のソースコードをこの辺で見つけたので、さっそく試してみた。

自分の環境に合わせてじゃっかんソースコードを書き換えたが、概ねそのままである(下記のコードは、Visual Studio と OpenCV 2.0 のコンビネーションじゃないとうまく動かない気がする。特にライブラリのバージョンに注意)。
#include<cv.h>
#include<highgui.h>

// ※インクルードパスに
//  「C:\Program files\OpenNI\Include」
//  を追加しておこう!
#include<XnCppWrapper.h>

#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")

#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"

int main() {
    xn::Context context;
    xn::EnumerationErrors errors;

    context.InitFromXmlFile(SAMPLE_XML_PATH);

    xn::DepthGenerator depth; // 深度コンテキスト
    context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);

    xn::ImageGenerator image; // イメージコンテキスト
    context.FindExistingNode(XN_NODE_TYPE_IMAGE, image);

    xn::DepthMetaData depthMD;
    xn::ImageMetaData imageMD;

    cv::Mat depthshow;
    cv::Mat show;
    int key = 0;
    bool isWarp=false;
    while (key!='q')
    {
        // waitとエラー処理
        context.WaitAnyUpdateAll();

        image.GetMetaData(imageMD);
        depth.GetMetaData(depthMD);

        // 画像と深度はOpenCVのMatに格納
        cv::Mat depth16(480,640,CV_16SC1,(unsigned short*)depthMD.WritableData());
        cv::Mat imni(480,640,CV_8UC3,(uchar*)imageMD.WritableData());

        // RGB色空間をBGRに変換
        cv::cvtColor(imni,show,CV_RGB2BGR);  
        
        // 11ビット画像を8ビット画像に変換
        depth16.convertTo(depthshow,CV_8U,-255/4096.0,255);

        cv::imshow("depth",depthshow);
        cv::imshow("image",show);
        key = cv::waitKey(33);
    }
    context.Shutdown();
    return 0;
}
これで、Kinect から労せずしてカメラ映像を取得する事ができるようになった。

……と見せかけて、上記のサンプルコードのままでは(僕にとって)多少問題がある。

この段階で、画像データは OpenCV の汎用行列クラスである cv::Mat のオブジェクトとして扱えるようになるのだが、このページの情報によると、 cv::Mat のメンバである step の値が、4 バイト単位に調整されなくなるという不都合が残っているらしい。

以前書いたような Windows API との連携を考えた場合、画像の管理には素性がはっきりしている IplImage 構造体を用いた方が、面倒も少なくて済むだろう。

僕がてきとうに調べた限り、Kinect から取ってきた画像データを直に IplImage に変換するような先人のソースコードを見つける事はできなかった。

それでも、恐らく需要はあるかも知れないと思い、ちょっと作ってみることに。

2011/02/16

魔法使いの弟子(その7-1)

【ミッション: Windows プログラミングに挑戦せよ】

中学の頃、ぼくは生まれて初めて C 言語の入門書を買った。

しかしそこに書いてあったのは、退屈なコマンドラインアプリケーションばかり。 GUI アプリケーションの構築を夢見ていたぼくにとって、それはあまりにもショッキングな現実であった。

そんなぼくも、やがて C 言語をひととおり学び(全然身についていないが)、ついに GUI アプリに手を付ける日が来た。