あなたが書いた数字を、人工知能は正しく認識できるか? – 第4回(全4回)


前回の結果から浮かび上がってきた、人工知能の特性に関する私見です。

人工知能の特性1: ヒトが見逃がす特徴を捉えられる

「大きさを揃える」という前処理が最も効果的でした。私は、「向きを揃える」や「細線化」のほうが、踏み込んだ処理をしている分いい結果になると予想していたのですが、意外でした。

前処理を設計した私の目論見が間違っていたと考えられます。例えば、字の傾きは、0-9の数字を見分けるのに有用な情報だったのかもしれません。「向きを揃える」ことでその手がかりを捨ててしまっていたのであれば、認識精度が下がるのも当然と言えます。

「もっと人工知能を信じて、持っている情報を全て渡しなさい!」と言われた気分です。できる部下と、その部下を過小評価しているダメ上司の関係ですね。

人工知能の特性2:新人にもベテランにもなる

前回の検証で、データセットの量が認識精度に大きな影響を与えていることが分かりました。これは、本質的に新人とベテランの違いです。

例えば、60,000組(ベテラン)と100組(新人)の人工知能について考えます。あるデモで両者が同じ認識結果を出した場合、両者の違いは分かりません。しかし、何度もデモを繰り返すと、60,000組は常に安定した認識率を維持できるのに対して、100組の方は認識率に浮き沈みが出てきます。いわゆる経験の差です。

人工知能の分野では、GoogleやFacebookなどの「データホルダー」企業が、人工知能の活用に有利と言われています。大量データを使って、人工知能をベテランに育てられるからです。

人工知能の特性3:機転が利かない

十分な量のデータセットを与えた人工知能は、頼れるベテランとして活躍してくれます。しかし、人間と違ってイレギュラーな状況で「機転」を利かせてはくれません。人工知能にデータセットのどれとも似ていない入力が与えられると、急に新人並みに頼りなくなってしまいます。

前回の、前処理を比較した結果は「前処理なし:43%」に対して「大きさを揃える:95%」と、認識率に倍以上の開きがありました。これは、mnistデータセットと似ていないデモ入力が多い程、認識率が下がることを示しています。

mnistデータセットは、どの画像もキャンバスの中央に文字が書かれています。それに対して、デモ画面はキャンバスの中央に数字を書くことを強制していません。中央から外れた場所に書かれた数字は、mnistデータセットのどれとも似ていないため、人工知能からするとイレギュラーで、認識できません。「大きさを揃える」という前処理は、このイレギュラーを予防する効果があります。

 

 人工知能の開発手法は、従来と真逆

本記事で、「~と思います」「~と考えられます」「~かもしれません」など、あいまいな言い方を多用していることに気づかれたでしょうか?

従来のソフトウェア開発では、エンジニアがプログラムの仕様を説明するときにあいまいな言い方をする事はありません。入力をどう変換して何を出力するのか、その全てがエンジニアの意図通りにコントロールできているからです。

一方、人工知能の開発において、変換処理はブラックボックスです。その変換処理の妥当性は、実際に動かして出力(認識結果)を見るまでわかりません。

従来のソフトウェア開発で、新人プログラマーが「実装しましたが、どう動くか分かりません」と言ったら、きっと先輩に叱られます。(誰も叱ってくれないなら職場を変える事を勧めます(笑))しかし、人工知能の開発においては、”本当に” どう動くかわからないのです。

Preferred Networksの丸山さんは、これを、「演繹的システム開発」と「帰納的システム開発」の違いと説明しています。

プログラムをY=f(X)と表現します。Xが入力、fが変換処理、Yが出力です。従来のソフトウェア開発は演繹的システム開発です。fをプログラマーがせっせと実装し、Xとfを与えるとYが得られます。

一方、人工知能の開発は帰納的システム開発です。本連載で”データセット”と呼んでいたXとYを与えると、fが得られます。従来は手作業で作成していたfが、人手を介さずに自動生成されます。

本連載で述べている通り、自動生成されたfの本質は「統計」です。

 

まとめ

「人工知能」は大袈裟に捉えられがちですが、実際にやっていることは統計データの作成と活用です。統計の価値は収集データの量と精度で決まります。それと同様に、人工知能を実用レベルに押し上げる為には、データセットの量と質がとても大切です。

そして、「動かしてみないとわからない」危うさを持っているものの、コンピューターの活躍の場を大いに広げてくれる、社会に役立つ技術です。

今の人工知能の盛り上がりは、一過性のブームで終わることなく、将来のプログラマーにとって当たり前の必修スキルになっていくと思います。

本連載を通じて、人工知能のカラクリについて理解を深めていただければ幸いです。


あなたが書いた数字を、人工知能は正しく認識できるか? – 第3回(全4回)


 

前回までは人工知能の一般論が中心でした。今回は、人工知能の認識精度を上げる為に、デモの開発中に試したことを説明します。

デモの内部構造について

デモの内部構造は、以下のようになっています。

デモの内部構造

 

左下のmnistデータセットは、様々な人が書いた手書き数字(28×28ピクセルの白黒画像)を約6万枚集めた、一般公開されているデータ集です。それぞれの画像に、正解(0〜9のいずれか)がタグ付けされているところがポイントです。

それ以外の要素については、前回説明ずみなので説明を省きます。

 

検証1:前処理を工夫して、認識精度を上げる

いろいろな前処理を試して、精度向上の効果を検証しました。以下は、その結果と前処理の概要です。

検証結果

mnist_3_4_filter前処理なし

前処理なし

mnistデータセットをそのまま使用します。他の方法と比較するためのベースラインです。

大きさを揃える

大きさ・位置を揃える

数字を認識するうえで、文字の大きさは関係ありません。ということは、大きさは認識に不要な情報と考えら
れるので、全ての手書き数字を同じ大きさに揃えて、統計に反映されないようにします。

向きを揃える

向きを揃える

数字を認識するうえで、文字の傾き具合は関係ありません。字の向きを揃えて、統計に反映されないようにします。

細線化

細線化

数字を認識するうえで、線の幅は関係ありません。幅を一定(1ピクセル幅)に揃えて、統計に反映されないようにします。

 

検証2:最適なデータ量を求める

mnistデータセットには6万の手書き数字がありますが、認識精度を上げるために、そんなに沢山のデータが必要なのでしょうか?この素朴な疑問を検証しました。

検証結果

mnist_3_4_volume

100組

mnistデータセットから、0-9の数字それぞれにつき10組を無作為抽出しました。

100組×10

[100組]のデータセットを元に、それぞれの画像をランダムに歪めながら、10倍に水増ししました。

水増しイメージ

60,000組

mnistデータセットをそのまま使用します。

60,000組×10

[60,000組]のデータセットを元に、それぞれの画像をランダムに歪めながら、10倍に水増ししました。

 

検証3:デモと同じ環境を使ってデータセットを用意する

mnistデータセットの手書き数字は、ペン(もしくは鉛筆)で書かれたように見えます。一方、デモ画面ではマウス(スマホであれば指)を使って書きます。この違いが認識精度に影響するか検証しました。

検証結果

mnist_3_4_content

ペン書き

mnistデータセットから、0-9の数字それぞれにつき10組を無作為抽出しました。

マウス書き

デモ画面を使ってひたすらカキカキした画像を、0-9の数字それぞれにつき10枚集めました。

ペン書き×10

[ペン書き]のデータセットを元に、それぞれの画像をランダムに歪めながら、10倍に水増ししました。

マウス書き×10

[マウス書き]のデータセットを元に、それぞれの画像をランダムに歪めながら、10倍に水増ししました。

 

検証して分かったこと

検証1〜3のいずれについても、認識精度に影響を与える結果となりました。特に、データセット量の違いによるインパクトがとても大きいです。

個人的には、「向きを揃える」や「細線化」の前処理で精度が上がらなかったのが予想外でした。

次回(最終回)は、この結果を分析しつつ、人工知能の開発の特殊性にも触れて、本連載を締めたいと思います。


あなたが書いた数字を、人工知能は正しく認識できるか? – 第2回(全4回)


人工知能が画像を認識する方法

手書き数字の画像や、音声、小説、ツィートなど、コンピューターに理解させることを前提としていない情報をコンピューターに与えて、人間のような認識をさせたい場合、大別して2種類の実現方法があります。

1. 不要なデータを捨てる

これらの入力は、一部の情報が欠落しても認識結果に影響を及ぼしません。例えば、下図の中央の画像は、左の画像の4分の1の情報量しかありませんが、人間にはどちらも問題なく認識できます。左の画像の全ピクセルが、数字の認識に欠かせない訳ではないのです。

不要なデータを切り詰め

入力データから不要な情報を極限まで取り除くと、認識に欠かせない僅かなデータだけが残ります。(画像の縮小はほんの一例で、他にも様々なやり方があります)データ量が少なくなる事で、取り得るパターン数も劇的に少なくなる為、コンピューターが認識しやすくなるのです。

とはいえ、切り詰めすぎると、図の右端の画像のように必要な情報まで失ってしまい、認識できなくなります。このさじ加減は、解こうとしている問題の種類や入力データの形式などによって異なります。

2. 様々なデータを収集して「統計」を作る

28×28ピクセルの白黒画像を例にとると、ピクセル列の取りうるパターン数は”2の784乗”という途方もない数になります。しかしながら、もし仮に、世界中の人々から同じサイズの手書き数字を収集できたなら、ほとんどのパターンには該当する人がひとりもいないと予想できます。収集データの統計を取ると、以下の図のようになる筈です。
統計のイメージ
数字を書く人は誰でも、子供の頃に覚えたアラビア数字の字体をイメージしているので、これは当然の結果です。そして、この分布のバラつきは、数字を認識する上で大変役に立ちます。
”字体”の概念など知る由もないコンピューターであっても、様々な手書き数字を事前に収集して統計を作成しておけば、入力画像と統計のマッチングにより、その入力画像がなんの数字を表しているか判別できるようになるのです。
入力データと統計のマッチング
ここでは分かりやすさを優先して、縦横2軸で表現できるシンプルな統計で例えました。実際のAIは、これよりもっと多種多様で複雑な統計を使用していますが、認識方法の本質に変わりはありません。

 人工知能のシステム構造

実用的な人工知能は、大抵、1と2の両方を組み合わせて使っています。素の入力データから不要な情報を取り除いた後で、統計を作成するのです。こうすると、どちらか一方を用いるよりも高い精度で分類できます。

本記事のデモも同じアプローチを採用しています。いろいろな処理方式を試して、その認識精度を評価しました。次回は、その評価結果について説明したいと思います。


あなたが書いた数字を、人工知能は正しく認識できるか? – 第1回(全4回)



まずは体験!

早速ですが、手書き数字を人工知能で認識するデモ を試してみてください。(今回の記事の為に、私が作成しました)
おそらく、100%近い確率で、あなたの手書き数字を正しく認識できたのではないでしょうか?(わざと下手な字で書いてみるのも面白いです。人間みたいな間違え方をします)
 (※公開終了しました。下の画像はデモ画面のスナップショットです。マウスで描いた数字を認識します )
手書き数字を人工知能で認識するデモ(自作)

はじめに

このデモには、人工知能(AI)が使われています。近年巷を賑わせている、自動車の自動運転や囲碁ゲーム(Alpha Go)、スマホの音声アシスタントなどに搭載されているアレです。

ただ、私たちが普段目にする「人工知能」関連のニュースは、過剰なアピールや不安を煽る記事が多いので、人工知能の技術的本質への理解を妨げている気がします。

本記事では、非研究者・非エンジニアの方でも理解できるように気をつけながら、人工知能のカラクリを具体的に解説します。長文なので、全4回に分けて掲載する予定です。人間はAIとどう共存していくべきか・・みたいな、大袈裟で抽象的な話は一切しません。

 画像認識の難しさ

先ほどのデモの内側で、どんな処理が行われているか想像つきますか?コンピューターの目線に立つと、下記のような分類処理をしています。

コンピューターから見た画像の認識方法

理論的には、あらゆるピクセルの組み合わせを事前に用意しておけば、機械的なマッチングにより100%正確に分類できます。とはいえ、組み合わせパターンは無限にあるので、現実的ではありません。(28×28ピクセルの小さい白黒画像でさえ、パターン数は”2の784乗”という途方もない数になります)

手書き数字の場合、同じ数字であっても、ヒトによって書き方が違います。同一人物が同じ数字を書いた場合でさえ、1ピクセルのズレもなく同じ書き方になることはまずありません。従って、「33番目から48番目のピクセルが「白」だったら”5”」などといったルールを予め設定しておくこともできません。

ヒトとコンピューターの認識の違い
人工知能は、 このような”あいまい”な入力から、入力者の意図を汲み取る技術と言えます。
次回(第2回)は、この”あいまい”な入力を、コンピューターで処理する方法について説明します。

ドライブシミュレーターが臨場感ありすぎ


11月9日に、フロンティア21 エレクトロニクスショー 2016へ行ってきました。

主に制御系のいろいろな製品やサービスの紹介やプレゼン発表、講演会を行う
イベントなのですが、大学の研究室からの出展も幾つかあり、面白かったのでご紹介します。

実映像型運転評価シミュレーター

愛知県立大学 情報科学共同研究所 小栗河中研究室」から出展されていたのは、CGではなく、実際に撮影した映像を用いたドライブシミュレーターです。
ドライブシミュレータの仕組み
単純な仕組みでありながら、実際に運転している錯覚に陥るくらいリアルに感じられる事に驚きました。私が自動車教習所でCGのシミュレーターを使った時には、こんな感覚は得られませんでした。最近は写真並みの精細なCGが当たり前になってきましたが、実際に撮影した動画のリアリティには敵わないですね。
体験させて頂いたデモでは、左右10度くらいしか視点を変えられず、進路も決め打ちなので変更できませんでした。ブレーキをかけると、動画の一時停止と同じ状態になる為、周りの歩行者や車も全て止まります。でも、それらの課題はアプリの作り込みで十分解決出来ると思います。
自動車教習所への導入を目指しているそうですが、自動車教習所側に、現状のCGシミュレーターを置き換えたいニーズがあるのか個人的には疑問です。観光PRとかの方が需要ありそうな気がしました。
これだけの臨場感を出せるシミュレーターに、とても可能性を感じました。

netshのメリットと限界


netshとは?

netsh(ネットシェル)は、Windowsに標準で備わっているコマンドプログラムです。画面はなく、コマンドプロンプトなどからコマンド文を打ち込んで使用します。Windowsのコントロールパネルやチャームの設定メニューの画面から設定するのと同様のことができます。
Windowsは、どちらの方法でもネットワーク設定が可能
同じ目的を満たす手段が2つあるのは、無用な混乱を招くだけなのでは?と思われる方もいるかもしれません。しかし、netshには独自の使い方があります。

netshのいいところ

設定画面は、利用者が設定を変更したい時に操作することを前提としています。一方、netshはあまりそういう使い方をしません。

Windowsに詳しい人は、コマンドプロンプトを立ち上げて、真っ黒なコンソールにコマンドをスラスラと入力できるかもしれませんが、普通の人はnetshコマンドのスペルを思い出すこともままならず、手が止まってしまうのがオチです。(かくいう私も、コマンドを暗記できた試しがありません)
netshは、設定を「入力する時」と実際に「適用する時」を分離できるのが強みです。netshに限らず、コマンドプロンプトから入力できるコマンド全般に言えることなのですが、コマンドというのは、別の見方をするとメールやツィッターの本文と同じタダの文字列です。
タダの文字列なので、ファイルに保存することができます。メールは、本文を書いたら直ちに送信しなければならないわけではありません。「下書き」という状態のまま手元に残しておいて、後日、送信することができます。
同様に、苦労して入力したnetshコマンドをファイルに保存しておき、その適用を、本当に必要になるその時まで先送りできるのです。
コマンドを記録したファイルのことを、「バッチファイル(拡張子は.bat)」と言います。
設定画面だと、こういう使い方はできません。画面をずっと開いたままにしておくことはできず、閉じようとすると「適用」または「キャンセル」のいずれかを選択させられます。
入力と適用の時間差
これは、ノートPCやタブレットを普段持ち歩く方にとって特に便利です。
日常的に利用する場所のネットワーク設定を予め別々のバッチファイルに保存しておいて、場所を移るたびに、対応するバッチファイルを起動して設定を即座に切り替えることができます。
このやり方を勧める記事を、ネットでよく見かけます。マイクロソフトも、きっとそういう使い方を想定してnetshを提供しているのだと思います。

netshの限界

しかし私は、この方法は一部の人しか救えないと考えています。それほどパソコンに詳しくない方にとって、バッチファイルというハードルは高すぎるのです。
たとえ自分一人しか使わないようなバッチファイルであっても、きちんと動くものを作ろうとすればそれなりの基礎知識と経験が必要になります。
それらを備えている方であればnetshという選択肢はありなのですが、そうでない方々にとっては解決策になりません。

その限界を乗り越える

そういう不満もあって、私は「NCSwitch」を作りました。このツールは、利用者がWindowsの設定画面に入力した内容を吸い上げて、ファイルに保存することができます。NCSwitchのウィザード画面を数回クリックして、バッチファイルを
自動生成するイメージです。
NCSwitchの仕組み
更に、接続先ネットワークが変わったことを自動的に検出して、自動的に設定を復元できます。バッチファイルのように、利用者が起動するバッチファイルを選択する必要もありません。
これらは全て、Windowsに詳しくない普通のユーザーに使っていただくことを念頭に設計された機能です。1.0のリリースから10年以上経ちますが、今も変わらず多くの利用者にご愛用いただいております。
ネットワーク設定の切り替えでお悩みの方は、ぜひお試しください。こちらからダウンロードできます。

360度カメラを自作しようとして、180度という顛末に (4 of 4)


 

前回からの続きです。

EdisonのI2Cハードを使わずにI2C通信する

数日間ずっと暗い気持ちでモヤモヤしていたのですが、ふと、全く別のアプローチを思いつきました。Edisonが提供しているI2Cハードを使うのをやめて、汎用のデジタルIOピン上でI2C通信する処理を自前で実装するのです。(Bit Bangingと呼ばれる手法です)

基本的な実装は思ったほど難しくなかったのですが、いざ動かしてみると、ここにも一つ落とし穴がありました。

通常、汎用のI/Oピンは、データの方向(INPUT/OUTPUT)を設定してから、電圧レベル(HIGH/LOW)を読み書きします。今回はI2C通信をエミュレートするため、データ方向を頻繁に切り替える必要がありました。(I2Cは、データの送受信を1本の線でまかないます)

データ方向の切り替えはArduino互換ライブラリのpinMode関数を使って行ったのですが、この関数を呼び出すと、なんと、切り替えと関係ない「他のIOピン」の電圧が一瞬上下に振れます。I2Cプロトコルに準じた波形を作るために苦労している中で、こんな副作用があっては困ってしまいます。

想定外のクロック生成

試行錯誤した結果、今回は、pinMode関数を呼び出すタイミングを調整することで、なんとか副作用を抑えることができました。

Bit Bangingが救いの神だった

Bit Bangingの実装が終わったところで、デモプログラムのI2C処理を置き換えて、動作確認してみました。どうせダメでしょ・・・くらいに思っていたのですが、なんとなんと、全てのパラメーター書き込みに成功しました!

結局、EdisonのI2CハードとArduCAMの相性が悪かったんですね・・・。

カメラモジュールを1台繋げた状態でうまくいったので、今度は、2台繋げて検証してみました。いろいろ試した結果、2kHz程度のクロック周波数なら、複数台繋いでもうまくいくことが分かりました。(10kHzだと、一方は正常に動作するものの、他方はパラメーター設定に失敗して変な画像が出力されたりしました)

2kHzと言うと、I2C仕様の中で最も低速なスタンダードモードの100kHzより50倍遅いことになります。とはいえ、今回の自作カメラにおいては、I2C通信はカメラモジュールの初期化時に1回走るだけです。初期化後のシャッター制御や画像読み取りは高速なSPI通信で制御されるので、実用上の問題はありません。

ようやく、自作カメラがまともに動く

幾多の困難を乗り越えて、ようやくArduCAMがEdison上で動くようになりました。

動かし始めた頃は、EdisonからSDカードを抜き、自機のMAC OS Xに差し、画像を確認し、Edisonに再び差し直す・・・という作業を繰り返していました。ただ、これを数十回も繰り返しているうち、いい加減面倒になってきました。

そこで、Expressというnode.js用のWebサーバーAPIを使って、SDカードのJPEG画像を自機のWebブラウザから直接見られるようにしました。

$ vi app.js
var express = require(‘express’);
var app = express();

// Edisonは、SD Card を /media/sdcardにマウントする
app.use(‘/sdcard’, express.static(‘/media/sdcard’));

app.listen(3000, function () {
console.log(‘Example app listening on port 3000!’);
});

$ node app.js   #webサーバ起動

特にトラブることなく、あっさり成功。I2Cの苦労を思えば、まさに瞬殺です。こういうことがサクッとできるところに、Edisonの凄さを感じます。

今後の予定

冒頭でも述べた通り、本当にやりたい事はカメラから画像出力した先の処理なのですが、今回は、画像出力までで力尽きました。

でも、これでようやくスタートラインに立てました。これから色々試してみて、随時、本ブログに結果報告していきたいと思います。

 


360度カメラを自作しようとして、180度という顛末に (3 of 4)


 

前回からの続きです。

複数のカメラを繋ぐと上手くいかない

I2C通信に問題があることが判明しました。次は、それがデモプログラムの組み方の問題なのか、もっとハードウェア寄りの問題なのかを見極める必要があります。

そこで、Edison上のLinuxに同梱されている、i2c-toolsというI2C通信用コマンドセットを使って、現象の再現を試みました。再現しないならデモプログラムの問題で、再現するならハードの問題という事になります。

まず、i2cdetectコマンドを使って、接続されているI2C機器(今回の場合はカメラモジュール)のアドレスを取得できるか確認しました。1台のカメラを接続した状態であれば100%取得できます。(”30″というのが、ArduCAMのアドレスです)

I2Cデバイスの識別成功

2台繋ぐと少し取得の成功率が下がり、3台を超えると全く取得できなくなりました。

I2Cデバイスの識別できず

i2cdumpコマンドによるパラメーターの読み出しも試みましたが、同じ傾向が見られます。

EdisonのI2CバスにArduCAMを複数台繋げると、通信障害が起きるようです。結局、ハードの問題でした。(プログラムの問題なら対処も簡単だったのに・・・現実は厳しい)

とはいえ、手元のArduCAMカメラモジュールがJPEG画像を出力したところを一度も見たことがない自分としては、そもそも初期不良なのでは?という不安も払拭しきれません。

Arduino UNO なら問題なし

そこで、初期不良かどうかはっきりさせる為に、Arduino UNOも購入することにしました。

現品の到着後、早速、Edison for ArduinoをArduino UNOに差し替えてリトライしました。1台でも複数台でも、ちゃんと動きます。これで、初期不良ではないことがはっきりしました。

余談ですが、実はArduino UNO上で動かす時に、少々ハマりました。Arduino UNOは、Edisonと違ってメモリ領域の制限が厳しい為、デバッグ用にSerial.print(“xxx”)を挟みすぎると、文字列定数(“xxx”の部分)が貴重なメモリ領域を圧迫してしまいます。これが一定量を超えると、変数の読み書きが正しく行えず、プログラムの挙動が不安定になります。(本家サイトにも注意書きがありました)

結局、1台だけでも上手く行かない

この自作カメラは、1本のI2Cバス上に、同じI2Cアドレスを持つArduCAMカメラモジュールを複数台繋げる構成になっています。普通は、複数の機器を同一バスに繋ぐのであれば、それぞれが異なるアドレスを持つべきです。しかし、開発者本人は、「確かに良い設計とは言えない。でも、動くよ。」という見解のようです。実際、Arduino UNOで動くことは私も確認しました。でも、EdisonのI2Cバスにはその力技が通用しないという事なのかもしれません。

そこで、一旦複数台のカメラを繋ぐ事は先送りして、1台だけつないだ状態で動かしてみる事にしました。1台のみであれば、I2C通信に問題がないことは前述のi2c-toolsで確認済みです。

ところが・・・デモプログラムは動きません。

デモプログラムを動かす為には数十個のパラメーターを設定する必要があるのですが、ある特定のパラメーターに書き込みすると、それ以降、どのパラメーター書き込みもエラーになるのです。しかも、動作電圧(3.3V / 5V)によって、エラーの引き金となるパラメーターが異なります。加えて、3.3Vなら、同じパラメーター書き込みを何度も繰り返しているうちにいずれ成功するのですが、5Vだと、どれだけリトライしても失敗し続けます。

もはや説明がつきません。EdisonとArducamは相性が悪いのでしょうか?

デジアナを買って、原因を追求

それでも、ここまで来たら諦めきれません。I2C通信の波形を見れば、何かヒントが得られるかも知れないと思い、Analog Discovery 2 というデジタルアナライザを購入しました。(今回の自作は、結構な額を出費しています(泣))

早速、波形を観測してみました。

エラー応答(NACK)

I2C通信のプロトコルシーケンス自体に問題はなく、Arducamがエラー応答(NAK)を返しているように見えます。

ちなみに、書き込みに成功した場合は以下のシーケンスになります。

正常応答(ACK)

残念ながら、カメラセンサーの内部構造を知らない私には、NAKを返す原因を調べる術がありません。

通信速度を落としてみるも効果なし

実は、デジアナであれこれ調べている時に、NAKとは別にもう1つ気になる点がありました。EdisonとArduino UNOの波形が少し違うのです。

i2c_voltage

Arduinoと比べると、Edisonの方はクロックのHI電圧が上がりきっていないように見えます。これが問題の原因とは考えにくいものの、他にやれることも見当たらないので、ここに対策を打ちます。

いろいろ調べた結果、Arduino UNOは100kHzのスタンダードモードがデフォルト設定で、一方のEdisonは400kHzのファーストモードがデフォルト設定だと知りました。

そこで、Edisonをスタンダードモードに落とした状態で、再度波形を観測してみます。

理想的な波形になりました。なったのですが・・・やはり、NAKを返す問題は解消されませんでした。

もう、打てる手がありません。


360度カメラを自作しようとして、180度という顛末に (2 of 4)


 

前回からの続きです。

待ち受けていた困難の数々

ここから先は、電子工作する方以外全く興味のない話になりますが、完成させるまでの苦労話をつらつらと書いてみます。同じ轍を踏む人が一人でも減ってくれることを祈りつつ。

部品の購入からLチカまでは順調

まずは、自作に必要な部品を購入します。

ハード一式

左がEdison for Arduinoボード、右がArduCAMカメラモジュール、中央がArducam4台を前後左右に接続するために使用する拡張ボードです。

組み立て後

これらを組み立てると、上の写真のようになります。後の説明で明らかになりますが、結局、Arducamを接続する拡張ボードは使うことができず、同サイズのブレッドボードに置き換わりました。

記事で使用されているデモプログラムはArduino用のソースコードなので、Arduino IDEを開発環境として使用します。これを自機のMacOS Xにインストール後、LEDを点滅させるだけの簡単なテストプログラム(通称、Lチカ)を動かしてみます。

Lチカ(ソース)Lチカ(Edison本体)

緑色に光っている部分がLEDです。写真では分かりませんが、ちゃんと点滅しています。ここまでは比較的スムーズに辿り着きました。

コンパイルできないデモプログラム

これで、デモプログラムを動かす準備が整いました。

GitHubからデモプログラムのソースコード(ArduCAM_Mini_2MP_4Cams_TimeElapse2SD.ino)をダウンロードして、Arduino IDEでビルドします。ところが、ここでコンパイルエラーになってしまいます。デモプログラムの動作ターゲットにEdisonが含まれておらず、ArduinoやRaspberry Piでのみ動作する書き方で実装されていたことが原因でした。
そこで、処理内容を変えることなくEdisonのコンパイラにも納得してもらえるよう、以下の点を修正しました。

  • itoa関数が見つからないというエラーが発生したので、snprintf関数で置き換え
  • パフォーマンス向上のためにArduino(AVRマイコン)のレジスタを直接操作してGPIO入出力を実装している箇所を、EdisonのArduino互換ライブラリに含まれているdigitalRead()/digitalWrite()呼び出しに置き換え
  • グローバル変数のオブジェクトポインタを宣言と同時に初期化している箇所でコンパイルエラーになったので、初期化処理をsetup関数の中に移動

これらの対策により、Edisonでもビルドが通るようになりました。

動かないデモプログラム

ビルドが通ったので、実機上で動かしてみました。うまく動いていれば、Edisonに装着したmicroSDカードへJPEG画像が出力されている筈です。期待と不安を胸に、SDカードを抜いて中身を確認しましたが、残念ながら何も出力されていません。

デモプログラムにSerial.print()を挟みまくって原因調査した結果、I2C通信に失敗していることが分かりました。

Edisonとカメラモジュールの結線は、電源(VCC, GNDの2本)、I2C通信用(SCL, SDAの2本)、SPI通信用(CS, MISO, MOSI, SCLKの4本)の3種類(8本)で構成されています。I2Cを使ってカメラのパラメーター(出力画像サイズなど)を設定し、SPIを使って撮影した画像データを読み取ります。

このような仕組みなので、I2C通信に問題があると、適切なパラメーター設定ができず、カメラ画像を取得できません。


360度カメラを自作しようとして、180度という顛末に (1 of 4)


360度カメラの自作デモに感化される

Arduino Panorama Photography with ArduCAM」という記事に感化され、360度カメラを自分でも作ってみようと思いました。

とはいえ、記事をそのままなぞっても面白くありません。純粋に360度カメラが欲しいなら、THETA買えばいいじゃん!とも思ってしまいます。

せっかく自作するなら、360度カメラの入力をリアルタイムに画像認識させたり、動画撮影できるように拡張したり、VRヘッドセットの出力に直結させたりといった、応用的な使い方を開拓したいのです。しかし、そういう重い処理は、記事どおりの作り方では実現できません。Arduino UNOのAVRマイコンにはそこまでのスペックがないのです。

軽い気持ちで、Edison Kit for Arduinoを選択する

そうなると、超小型でありながらデスクトップLinuxと同じように使えて、スペックも申し分ない、「Raspberry Pi」と「Intel Edison」のどちらかを選ぶ事になります。(他の競合製品を知りません。完全に独断です)
ラズパイとArduCAMカメラモジュールの組み合わせは動作実績があるようですが、EdisonとArduCAMの組み合わせは、いくらググっても何も出てきません。誰も試していないのでしょうか?
Edisonについてさらに調べてみると、Arduino互換ボードが発売されている事が分かりました。Arduino UNOの代替としてはうってつけだと思い、今回はEdisonを使うことにしました。

Arduino UNOをEdison Kit for Arduinoに置き換える以外は、記事通りのやり方で自作します。ArduCAMの提供元はEdisonで動くなんて一言も言っていませんが、Arduino互換ボードなのだから、問題なく動く筈です。(程なくして、この目論見の甘さを痛感する事になりました)

数々の困難を乗り越えて、ようやく完成
完成写真(横から) 完成写真(上から)

当初は、前後左右に4台のカメラモジュールつける予定だったのですが、作成途中に2台が壊れてしまい、このような形になってしまいました(泣)。

壊れたと言っても、カメラモジュールが不良品だった訳ではなく、私が、カメラと本体(Edison)の結線を間違えてしまった為、内部回路が焼き切れてしまった事が原因だと思います。(動くようになるまでに数百回とI/Oピンを抜き差ししていたので、2、3回間違えても不思議ではない・・・と自分を慰めてみる)

本当は動作デモをお見せしたかったのですが、今回は動くようになったところで力尽きてしまいました。後日、改めてアップします。