2013年2月13日水曜日

Image recognition and Noise reduction

ロボットの原価を低減させる為に、市販の部品を使っていますが、いろいろ課題が発生します。
ロボットの目には、2,000円台のWebcamを使っていますが、高価な物に比べて不安定です。従って、画像認識において、図1のような元のイメージからピンクのボールを認識する場合、大量のノイズが発生する事が多いです。
図2は、その状態を解り易くする為に二値化した物です。大量のノイズが存在します。
このような状況で、図3の様にボールだけを認識しなければなりません。
画像処理は、奥が深いです。だから、面白いです。更に、ロボットと組み合せると、”面白い”の二乗になります。ロボットは、動いていますから、限りなく短い時間で処理をしなければなりません。その情報を元に、駆動系の制御をします。
webcamが、どのような画像を取得しているか解りません。従って、プログラムはそれを前提に作らないとなりません。いやはや、とっても面白い世界です。

しかし、結局、ロボットは、ソフトウェアが勝負ですね。また、ソフトの工数を減らす為には、高価なデバイスが必要になります。結局、高い原価構成のジレンマに陥ります。
だから、企業レベルでロボットの原価を考えると、価格は高くならざるおえません。
それを、僕は、RDCSで解決しています。

図1 元画像 
(白い格子は、画像の保存時に付加)
図2 noiseの大量発生
noiseが解り易いように二値化した画像
HSV色空間では、大量のnoiseを拾ってしまう場合がある
 図3 認識結果
noise処理を行い、ボールだけを認識する 
この処理もRaspberry Piで実行しますが、画像の保存をしなければ処理は瞬時に終わります。

peace!

Recon

2013年2月9日土曜日

Performance of the recognizing a moving ball on Raspberry Pi

自律型ロボットは、自分で空間認識をする必要があります。その為には、リアルタイムで画像解析が必要になりますが、Raspberry Piでそれをする事は無理があります。
しかし、どこまで可能なのか?知る必要があり各種の画像処理のパフォーマンステストをしています。
結果的に言えば、私のプログラムのチューニングをすれば、かなりの事ができるという事でした。プログラムを見直すと、無駄な処理やループが沢山ありました。今は、とにかく、数を優先している為、ロジックに無駄が沢山あります (-_-)

(私が開発しているのは、人が操作しない、自律型ロボットです。人が操作する物は、ラジコンだと考えて、ハッキリ分けています。趣味の一つがラジコン飛行なので、、、)

テストの例
「画像入手(webcam 640x480 CV_U8C3) -> 動くボール認識 -> 認識画像出力」
上記100回の処理時間 → 10回計測 平均45秒 約2回/秒 の認識処理
同上 ファイル出力無し → 10回計測 平均30秒 約3回/秒 の認識処理

テスト方法は、下図のピンクのボールを手に持って、Webcamの前で不規則に動かします。Raspberry Pi上の認識プログラムが、usb接続されたwebcamから画像を入手して、動いているボールだけを認識します。
図1
ピンクのボールをwebcamの前で不規則に動かし、ボールだけを認識する
図2
左上から右下に、処理結果の順で並べている
赤が、手で不規則に動かしたボールの認識結果。
光の影響があるので、完全な'円'になっていない。白丸は同じボールであることを示す
認識プログラムは、複数の動く物体を認識できる
図2の8枚のボールの動きは、約3.6秒間(45秒/100x8)の動きのsnapshotになります。
1回の処理毎に、認識した結果をファイルに保存した画像の一部を並べました。保存をしない場合は、同じ時間で、12回のボール認識ができます。

1秒間に、3回の画像認識処理ができれば、僕のロボットの要求仕様を十分に満たす事が出来ます。実際には、風景内の沢山の認識をしているので、ロボットの運用上は1秒間に1回の画像認識処理で十分です。

Raspberry Piは、見た目以上に、すごいヤツです。

peace!

2013年2月7日木曜日

A memorandum : fswebcam

fswebcamは、デフォルトでbannerを出力するので、それを抑制する設定。
忘れない様に、、、
いままでは、画像処理の途中で無くなっていたので無視していたけど、
ある処理をする為に、赤いラインが邪魔になるので、調べました。
デバイスを指定しているのは、Raspberry Piに2台のWebcamを接続している為。
保存ファイル名は、2050-02-07-123950.jpgの様になります。


fswebcam -d /dev/video0 -r 640*480 --no-banner --line-colour '#FF000000' -save /tmp/`date +%Y-%m-%d-%H%M%S.jpg` -S 3


bannerが消えました
ファイル名の2050年は、冗談です。 (^_^)

peace!

Recognizing tomatos on my robot using Raspberry Pi

15万円台、トマト収穫ロボットの基礎技術の紹介です。

今回は、ロボットの目、形状認識の紹介です。
特徴は、2次元の画像データ1枚から、トマトを抽出し、かつ抽出したトマトの3次元の位相関係を作る点です。この位相関係が出来れば、その後の処理を効率よくすすめる事が出来ます。
    Step1: 2次元画像を使ったトマト形状認識と、その他 controlデータ抽出
    Step2: 3次元位相構造の作成

この認識で使っているアルゴリズムは、Computer Visionで開発された様々なOpenCVに実装されているアルゴリズムと、トマトを栽培しながら観察した植物体の位相構造などから作ったアルゴリズムを組合せました。(3D GISの開発経験も役に立ちました)
この内容は、トマト収穫機や収穫済みのトマトのパッキングなど、広範囲に使える基礎的な技術です。また、webcamなどの安価なカメラで行う事を前提に開発しています。

下に表示した画像からのトマト抽出結果は、ブログ標題の背景写真を使っています。トマトの表面が光っている、またガクがついているなど、画像を使った形状認識に於いては、条件が悪いデータです。

青い範囲(640x480)が、Actuatorのmotion planning の対象であり、その中は精度を高めて認識をしています。赤い丸で囲まれた物が、第一段階の画像処理をして認識したトマトです。青い四角の範囲では、ほぼ100%の認識です。この処理は、アルゴリズムの高速化に苦労しました。今は、i5クラスのマシンで1秒の数分の1以下のオーダです。

第一ステップの認識
青い四角は、特に認識精度を要求する範囲
赤い○は、トマトとして認識した形状
シアンの○は、後処理に必要なcontrolデータ
画像のふちは、切れたデータの処理が完成していないので
誤認識が発生しています。(改善予定)
この処理の後に、第二段階として、さらに独自のテンプレートを使った位相構造抽出処理をして、一定の誤差内の3次元データを生成します。3次元データが出来た段階で、トマト認識処理は終了です。第二段階は位相構造の演算が主なので短時間で終わります。
その3次元データは、ActuatorのMotion Planningの元データになります。
このように書くと、単純だけど、僕に取っては認識処理は結構複雑で悩みました。

可能な限り、2次元の画像データから3次元のデータを生成します。その方がコストが安く出来ます。全ては、15万円トマト収穫機の実現のためです。

この認識は、Raspberry Piの性能では負荷が高いので、他の処理への影響も考えてserviceで実施する様にしています。
ただし、プログラム処理ロジックのチューニングの余地がかなりあるので、他の機能の性能が定量的に把握できた段階で、再検討をします。1台のRaspberry Piを専用に割当てても良いし。。。。。

今は、Raspberry Piで画像を取得して、Recognizing Serviceに送って、あっという間に処理して返します。RDCSの腕の見せ所です。
RDCSによって、Raspberry Piは、実際の性能以上のロボットコントローラになります。
こういうのが、smartですよね。
The network is the computer. いい言葉です。

peace!

2013年2月5日火曜日

Configure X11 Server ( Mac ) and Client ( Raspberry Pi )

How to configure a connection between X11 client (Raspberry Pi) and a X11 Server (Mac) using a SSH tunnel.

1. Client (Arch Linux on Raspberry Pi)
[root@rcmp-r03 ~]# vi /etc/ssh/sshd_config

#AllowTcpForwarding yes    --->   AllowTcpForwarding yes
#X11Forwarding no                --->   X11Forwarding yes
#X11DisplayOffset 10             --->   X11DisplayOffset 10
#X11UseLocalhost yes           --->   X11UseLocalhost yes

If you get "X11 forwarding request failed on channel 0" , try below.
#AddressFamily any              --->   AddressFamily inet    

[root@rcmp-r03 ~]# reboot


2. Server (OS X on Mac)
Macmini:~ nao$# sudo vi /etc/ssh_config

#ForwardX11 yes                   --->   ForwardX11 yes   


3. Login  from X11 Server to X11 Client
Macmini:~ nao$# ssh -X  root@192.168.11.99

Last login: Mon Feb  4 22:47:37 2013 from 192.168.11.xx
[root@rcmp-r03 ~]# test3-18

Macが、X11 Server として画面表示をしている為、
画像上部に ”X11 アプリケーション"  と記述がある。
おまけに、顔認識をしておきました。OpenCVの基本機能で出来ます。
Macが、Raspberry PiのXサーバになれば、Raspberry Piにそれぞれディスプレーを接続しなくても良くなる。何たって、13台のRaspberry Piがあるか、画面を見る為に接続変更するのはとんでもない事です。

peace!

opencv memo


http://junkroom2cyberrobotics.blogspot.jp/2012/10/raspberry-pi-opencv_16.html

/ OpenCV カメラ画像顔検出のテスト。
// gcc -Wall -o "%e" "%f" -g -L/usr/local/lib 
//     -lopencv_core -lopencv_imgproc -lopencv_highgui 
//     -lopencv_ml -lopencv_video -lopencv_features2d 
//     -lopencv_calib3d -lopencv_objdetect -lopencv_contrib 
//     -lopencv_legacy -lopencv_flann -lusb
// 実行フォルダに haarcascade_frontalface_default.xml を置く。
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

#include <opencv/cv.h>
#include <opencv/highgui.h>

int main(int argc, char **argv)
{
 CvCapture *capture = 0;
 IplImage *frame = 0, *src_gray = 0;
 int max_detect, min_detect;
 int c ,i;
 
 double width = 320, height = 240;
 //double width = 640, height = 480;
 
 // 正面顔検出のための検出器を読み込む。
 CvHaarClassifierCascade *cvHCC =
  (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_default.xml", 0, 0, 0);
 // 検出用のメモリストレージの用意。
 CvMemStorage *cvMStr = cvCreateMemStorage(0);
 // 検出情報格納用シーケンスの用意。
 CvSeq *detectFace;
 // 検出最小及び最大サイズ設定。
 max_detect = (int)height;
 min_detect = (int)(height / 5);
 
 
 // カメラに対するキャプチャ構造体を作成。
 if (argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
  capture = cvCreateCameraCapture(argc == 2 ? argv[1][0] - '0' : 0);
 
 // キャプチャサイズの設定。
 cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
 cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);
 
 // ウィンドウ作成。
 cvNamedWindow("face_detect", CV_WINDOW_AUTOSIZE);
 
 while(1)
 {
  // 画像キャプチャ。
  frame = cvQueryFrame(capture);
  
  // グレイスケールイメージに変換。
  src_gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
  
  // 顔検出処理。
  detectFace = cvHaarDetectObjects(frame, // 対象イメージ。 
      cvHCC,  // Haar分類器カスケード。
      cvMStr, // メモリストレージ。
      1.1,  // スケーリングファクタ。
      3,   // 近接矩形グループ化。
      CV_HAAR_DO_CANNY_PRUNING,   // 処理モード。
      cvSize(min_detect, min_detect),  // 最小窓サイズ。
      cvSize(max_detect, max_detect)); // 最大窓サイズ。  
  // 検出結果を矩形&クロス表示。
  for (i = 0; i < detectFace->total; i++)
  {
   CvRect *faceRect = (CvRect*)cvGetSeqElem(detectFace, i);
   cvRectangle(frame,
      cvPoint(faceRect->x, faceRect->y),
      cvPoint(faceRect->x + faceRect->width, faceRect->y + faceRect->height),
      CV_RGB(255, 0, 0),
      3,
      CV_AA,
      0);
   cvLine(frame,
    cvPoint(faceRect->x + (int)(faceRect->width / 2) -10,
     faceRect->y + (int)(faceRect->height / 2)),
    cvPoint(faceRect->x + (int)(faceRect->width /2) + 10,
     faceRect->y + (int)(faceRect->height /2)),
     CV_RGB(255, 0, 0),
     3,
     CV_AA,
     0);
   cvLine(frame,
    cvPoint(faceRect->x + (int)(faceRect->width / 2) ,
     faceRect->y + (int)(faceRect->height / 2) - 10),
    cvPoint(faceRect->x + (int)(faceRect->width /2),
     faceRect->y + (int)(faceRect->height /2) + 10),
     CV_RGB(255, 0, 0),
     3,
     CV_AA,
     0);
  }
  
  cvShowImage("face_detect", frame);
  
  c = cvWaitKey(10);
  if(c != -1) break;
  //sleep(2);
 }
 
 // 後片付け。
 cvReleaseMemStorage(&cvMStr);
 cvReleaseHaarClassifierCascade(&cvHCC);
 cvReleaseCapture(&capture);
 cvDestroyWindow("face_detect");
 
 return 0;
}

OpenCv cookbook for Raspberry Pi

何気に、OpenCVのソフトを整理していたら、cookbook 向きのサンプルプログラム集ができてきた。基本的な動きが分かるプログラムだけど、全部で40数個。
今度の教育の提案の時に使おうと思います。

下は、有名なLenna さんの画像を使って顔と目の認識。OpenCVは、こんな事が簡単に出来てしまいます。Raspberry Piはこの処理を”一呼吸”おいた感じでやってしまいました
LXDE の上で、大変な事になっています。
ついでに、gimp が起動しています。
僕は、グラフィック系の勉強は、あんまりパフォーマンスが高くないマシンの方が良いと思っているので、Raspberry Piがちょうどいいかもしれません。
恐るべし、Raspberry Pi。最近、そう思ってきた。

まぁ、提案の題は、こんな感じ。大人向きだから、これでいいでしょう。
子供達のための、ビジュアル技法を使った、問題解決法

peace!

2013年2月3日日曜日

OpenGL ES2 on Raspberry Pi

これは、完全な忘備録

Raspberry Piには、GPU が搭載されています。
/opt/vc/src/hello_pi にサンプルプログラムあります。
README の通りにするとエラー。あらマー。。。
エラーを眺めて、Makefile.includeにちょっと追記。
INCLUDES+=  に下の2つのpathを追加すればOK。その後、rebuild.shをするとRaspberry PiのGPUを使ったサンプルプログラムが実行できます。

-I$(SDKSTAGE)/opt/vc/include/interface/vmcs_host 
-I$(SDKSTAGE)/opt/vc/include/interface/vmcs_host/linux

画面を撮った写真ですが、実際はCUBEがくるくる回っています。(hello_triangle.bin)
恐るべし、Raspberry PiのGPU.



peace!

2013年2月2日土曜日

Raspberry Piを使ったコンピュータ教育を提案しま〜す。

ロボットの講演を依頼され、その打合せを昨日しました。
事前に送っておいた、Agendaに記載したコンピュータ教育について、
提案をする事のOKが出ました。こういうのは、こちらの想いだけではできないので、
ちゃんと了解を取る事が必要です。

一度、書いた文を読み返して、気がついたのは、
問題解決技法を、伝えたかった!」と言う事でした。
それを、中学などの早い段階に、触れておく事が大切であると、これまのでの社会生活で強く認識しました。それらは、下記の経験などから得た物です
  (1) 長く新規技術/事業開発をしてきた経験、そのKFSの分析結果
  (2) 企業の知識マネジメント研究で実施した約5,000人のインタビュー分析結果
  (3) 海外での勤務/業務経験と、海外事業成功のKFS分析結果

結局、行き着く所は、想い、必然性、イノベーションの梃、そして、実現する為の技術です。細かい事は、書きませんが、、、

という事で、
ビジュアル技法を使った、問題解決法」このテーマで落ち着きそうです。
それで、Raspberry PiのGPUを目一杯使って、体験してもらいます。
すっきりしたー!!!
こんな感じ  Here click!

--------------------------------------------------------------------------------
ここから下は、上に書いた事の元ネタです。自分で忘れないために消さないでおきます。


提案する内容は
「自分のアイディアや、便利にしたい事を、コンピュータで実現する為の考え方の教育」
それを個人所有が可能な、Raspberry Piを使って実施します。教育というのは、アバウトな言い方だけど。

「コンピュータで実現する為の考え方」
これは、以前から考えていた事です。
これは、プログラムを教える事ではない。コンピュータを使いこなす為に必要な、基本的な考え方と、テクニックです。プログラミングは、目的を達成するために必要となる手段であり、それが中心のコンピュータ教育には違和感を持っていた。それは、僕の経験からかもしれないが、、、

僕の場合は、企業向けのソフトウェア商品開発の業務経験が、社会に入ってから、ほぼ半分くらいを占めている。自分で企画して、プロト開発して、商品化提案をして、開発チームを作り、営業もしたし、事業化もした。
その過程を振り返ると、次のように考えてやってきた。例えば、
「この事象xxxの問題点は、qqqである。それをyyyの構造的な関係としてとらえて、この構造を、z1、z2、z3の観点から解決をめざし検討を行った。その中で、tttの理由から、Z2ので示した構造的な関係性に着目することが最もrrr効果的な解決をする方法であり、その解決のメソッド開発とその実現を担保するaaaaをコンピュータ化して、解決します。」
つまり、構造的な解析と、解決方法のメソッド構築、そしてその為に必要となるコンピュータシステムの開発をしてきた。最初の2つが特に、大切であり、多くのお客さんは、システムに投資したのではなく、メソッドに投資をしてくれたと考えている。
このメソッドの大切さは、あるグローバル企業の経営者から呼ばれて面談した時に認識した。彼らは、コンピュータ会社でありながら、ビジネスにおけるメッソドの重要性を強く認識していた。さすがだなぁと思った。
当時、私は組織内の知識マネジメントのメソッドを開発して市場導入していた。そのメソッドは多くの企業で採用してくれた。そして、システムも導入してくれた。Valueは、メソッドだった。

メソッドはともかく、システム思考的に考える方法を、子供達に伝えられたらと考えている。コンピュータシステムは、対象の構造化とシステム思考的な組み立てで、構築するべきである。この考え方ができれば、コンピュータを自分の道具として使いこなす事ができる。コンピュータを使いこなせれば、本当に頼もしい味方になる。
子供達は、将来コンピュータ関連以外の仕事で働く事が多いと思う。一方で、コンピュータがいま以上に、社会や日常生活に組込まれてくる。だからこそ、コンピュータシステムの作り方や、その背景にある考え方を理解できる事が必要がある。
コンピュータシステムが、大事なのではない、その裏にある解決のメソッドが大切なのである。」と、、、、
それが、明確でないシステムには、「近寄ってはいけない
まだまだ、整理できていませんが、こんな事を提案しようと思っています。

これを、演習形式にして、ドキュメント作成やプログラミングを合わせて、実施できればと考えています。
ただ、その時の言語は、やっぱりC言語かもしれない。
Raspberry Piは、GPUをフルに活用して使います。CPUは、ほどほどですが、GPUはすごい。試してみて、ビックリしました。
子供達の演習で、CADでも作りましょうか?なんちゃって。

peace!