2010/08/31

新しいWebカメラを買いました(Logicool C910)

私が持っているWebカメラは120万画素と30万画素のものなのですが、もうちょっと解像度よいカメラが欲しくなったので、電器店に行ってみました。

電器店のWebカメラコーナーで物色したところ、Logicool HD Pro Webcam C910を発見しました。
値段が1万円ぐらいするのでちょっとためらいましたが、
・CMOSの画素数が500万画素もある(私の持っているデジカメに匹敵する解像度)
・カールツァイス社が開発した光学レンズつきる
・フォーカスの動作距離が7cm~となっているので、接写に強そう
遊び研究に金がかかるのはいつものこと
という理由から、即決で買ってしまいました。

んで、OpenCVで実際にキャプチャしてみたのが下の画像です。
撮影した条件は下記の通りです。
・カメラと対象物との距離は約50mm(フォーカスをマクロ側いっぱいに設定すると、対象物まで30mmあればボケずに写せました)
・解像度:800x600
・30fps


上記の画像の通り、かなり細かいところまで撮影でき、かつ接写にも強いということがわかります。(今持っているデジカメだと、同じ距離から撮影してもボケてしまい、ここまでの接写はできませんでした)

このカメラには、カメラのコントロールソフトがついていて、カメラを使うアプリケーションを起動したときに、自動的にコントロールソフトも起動します。
コントロールソフトでフォーカスや明るさ調整が調整できるので、なかなか便利です。

デジタル一眼レフカメラとかだとPCからの撮影やフォーカス調整ができるものが多いので
便利だな~とは思ってたのですが、Webカメラでも同じようなことができるようになったので、とても嬉しいです。

その他、付属ソフトに動体検知モードというのがあり、定点観測中、設定した閾値よりも大
きく画像が変化した場合に動画ファイルに保存する、という機能がありました。
録画した動画の右下には録画した時刻も記録できるので、防犯カメラとしても使えそうな感じです。

ではまた。

2010/08/28

ジグソーパズルプログラム ピース情報の取得方法

パズルプログラムの実験を継続中です。


ジグソーパズルを解くためには、1ピースごとの形状を把握しなければなりません。
輪郭抽出でピースの外周の情報は得られるのですが、マッチングに使用する際は外周の輪郭情報を上下左右の4区画に分かれていなければ使い物になりません。
4区画に分けるには、ピースの4つの角を検出しなければならないので、角を検出するところからやっていきます。

外周の輪郭情報から直角を抽出すればいいのではと考え、輪郭の数点に直線を割り当てたり、ハフ変換で画像内の直線を検出したりしましたが、ノイズが多かったり検出されるべき角が検出されなかったりと、結果はあまりよいものではありませんでした。

んで、OpenCV本をめくって何かいい方法が無いかを探したところ、モルフォロジー演算というのが使えそうでした。

モルフォロジー演算のクロージング処理は下方向(暗い点)のアウトライヤーを除去し、オープニング処理は上方向(明るい点)のアウトライヤーを除去してくれるようです。

実際にピースの画像にモルフォロジー演算をやってみたのが下記の図となります。











今回はクロージング処理でピースのへこみ部分を除去し、その後オープニング処理でピースの出っ張り部分を除去することに成功しました。いろんなピースでやってみましたが、ほとんどのピースで4つの角を検出することができました。

モルフォロジー演算を行うときに、カーネルの大きさを自分で指定することができるのですが、このカーネルの大きさを取り除きたい部分の大きさよりも少し大きめにすると、うまく除去してくれるようです。(ただし、ピースが斜めに配置されていると、カーネルが短形なためモルフォロジー演算を行ってもピースの角を抽出することはできなくなります。)

ピースの4つの角を抽出できたので、あとは上下左右の形状を調べるだけです。

ひとまず「出っ張りがある」「へこみがある」「何も無い(直線)」の3つに区分したいので、
x方向に伸びる辺は上下5~10ピクセル、y方向に伸びる辺は左右5~10ピクセルの輝度を順次調べていけばよさそうです。

ではまた。

2010/08/27

ジグソーパズルプログラム 苦戦中

むずい、、むずいよ ジグソーパズル解答プログラム (ノД`)


Googleで答えを探しても文献が見当たらず、ようやく見つけたのが
A Global Approach to Automatic Solution of Jigsaw Puzzles という論文。
この論文では、輪郭同士を直接マッチングさせるのではなく、出っ張っている部分やへこんでいる部分の位置や大きさを比較して、その後で輪郭情報を使用してマッチングさせているようです。

論文の中では「巡回セールスマン問題を解くことで、自動的にパズルを解かすことに成功した」的なことが書かれていたのですが、巡回セールスマン問題は難しそうなのでパス。
フルオートで解答させるのはあきらめて、まずはセミオートで解答するものを作ることにしました。

処理手順(新)

・輪郭を抽出します。(ピースの数だけ輪郭が出力されます)
・輪郭1個ずつに対し、下記の処理を行います。
・輪郭に外接する四角形をcvMinAreaRect2を使って求めます。
・外接する四角形のサイズ、中心点、角度がわかったので、1ピースごとに回転が0度になるようにcvGetQuadrangleSubPixを使って回転させます。
・この時点で1ピースの向きは、45度傾いているか、整列されているかのどちらかになります。(ピースの4方向に出っ張りがある場合、出っ張りに外接する四角形が計算されてしまうため、45度傾いてしまいます)
・ピースの出っ張り・へこみではなく、ピースの四隅を探します。見つからない場合は、45度画像を回転させてもう一度探します。
LaplacianフィルタCannyフィルタをかければ四隅を検出できそうです)
 ・四隅がわかれば、ピースの輪郭を上下左右の4つに分けて、輪郭の区分と出っ張り・へこみの位置、大きさを計算します。これが輪郭の識別子となります。


 ・輪郭が直線の場合はコーナーピースもしくはラインピースになるので、コーナーピースの場合は下と右が直線部分になるように回転させます。
 ・ラインピースは下が直線部分になるように回転させます。


ここまでで、各ピースは整列され、上下左右の輪郭がどんな種類なのかが決まります。




あとはこの情報を元にマッチングさせていきます。


マッチング
1.四隅のピースのうち、どれか1つを適当に選び、完成図の左上(XY座標にすると0,0)に配置します。
2.  配置したピースの右(1,0)にはラインピースが必ず来るので、右に来るラインピースを探します。
3.さらにもうひとつ右(2,0)のラインピース、その隣のラインピース(3,0)と探していきます。
4.いつかは四隅の残り3ピースのうちのどれかに隣り合うので、四隅のピースになったらピースの探す方向を変えます。(右に探していた場合は下、下に探していた場合は左、左に探していたら上)
5.ラインピースと四隅のピースで配置されていないものがなくなれば、一番外側のピースが完成したことになります。
6.その先も同じように、左上から螺旋を描くように埋めていけばできあがる・・・かも。


本家と違うところは、ピースを探すときに人間の手を借りる、というところです。
たとえば、ピースの左側がへこんでいるピースはたくさんあるので、その中の候補を順番に表示させていき、人間に「当てはまる」「当てはまらない」と判断してもらいます。
この辺がセミオートな理由。セミオートが完成したらフルオートにも挑戦します。




完成までは結構時間がかかりそうな感じではありますが、
とりあえず今週末でピースの切り分けと分類までやってみようと思います。


ではまた。

2010/08/17

久々の更新

  先週、StarCraftIIというパソコンのゲームを買ってしまい、
研究そっちのけでゲームをやってました。

ちょっと落ち着いたので今週はマシンビジョンの研究に戻ります。

さて、前回やっていたジグソーパズルを解くプログラムですが、
重大な欠陥を発見してしまいました。

普通のパズルだと当たる確立ほぼゼロという、非常に悲しいものです。
チラシを切って作ったものだと大体あたるのですが、
実際に買ってきたジグソーパズルだとひどい結果となりました。

買ってきたのは、
「108ピース となりのトトロ 五月晴れの日に」
という初心者向けのパズルです。

完成品は20cm x 26cm程度の大きさ(A4と同じぐらいです)になりますが、
パッケージに載っている完成図の大きさが7cm x10cmと小さめでした。
とりあえず持っているデジカメのズームを使って高解像度(6Mピクセル)で撮影したものを
使い実験したところ、結果はボロボロ。

気を取り直して一度パズルを完成させ、それを撮影したものでやってみましたがこちらもボロボロ。

前回はここで力尽きました。

ジグソーパズルの解き方のコツを検索したところ、
1.外周のピースを抽出し、外周を作成する。
2.特徴量の多いピースを抽出し、部分的に作成する
3.外周、もしくは特徴量の多いピースの塊から領土?を拡大させていく
4.わかんないピースはとりあえず放置。 あとでひたすらあわせてみる
というものでした。

外周のピースを抽出するためには、各ピースの輪郭情報が必要となるので、
今度は輪郭マッチング方式でやってみることにしました。

プログラムの概要
1.スキャナーのガラス台の上にピースを適当な間隔をあけて並べます。(ひとまずグレースケールでスキャン)
2.スキャンした画像から、各ピースの輪郭を抜き出します。
3.各ピースの輪郭を順次比較して、似たような輪郭を持つグループに分けます。
4.ピースのグループのうち、1辺もしくは2辺が直線になっているもの(=外周ピース)を抽出します。
5.外周ピースを輪郭マッチングにかけます。
6.その後、外周ピースの1つ内側から輪郭マッチングをかけて、パズルを埋めていきます。

ここで重要なのが輪郭マッチングで、どうやってやったらよいものかを悩んでるところです。

パズルのピースは四角形の各辺がへこんだり出っ張ったりしているので、パズルの各辺を
へこんでる → -1
直線のまま →  0
出っ張ってる→ +1
で表すと、パズルを組み合わせたときの各辺の総和がゼロになっていれば
完成とみなせるはずです。

問題はこの組み合わせ方をどうするかですね~

ちょっとググって探してみようかな。。

2010/08/04

OpenCVでジグソーパズルを解いてみる

コンピュータビジョンの資料として使っている、"Computer_Vision_Algorithms_and_Applications"の
課題に、「イメージの特徴点を利用してジグソーパズルを解いてみよう」というものがありました。

面白そうだったので、実際に作ってみました。

準備
0.ジグソーパズルを用意します。
  (手元にパズルがなかったので、とりあえずドミノピザのチラシを素材にしました)
1.パズルの完成図をデジカメで撮影するか、スキャナで取り込みます。
  (とりあえず今回はA4サイズのチラシを6Mピクセルの大きさで撮影しました)
2.完成図をグレースケールで読み込み、SURF特徴量を求めます。
3.Webカメラから1ピースの画像を読み込み、SURF特徴量を求め、完成図の特徴量と比較します。
4.特徴点が一致した点をプロットします。
5.プロットされた点が多いところが、1ピースの場所となります。



今度は売っている100ピースぐらいのジグソーパズルでやってみたいと思います。
ソースコードはまた今度。


ではまた。