ELM Home Page

2011. 2. 4

ラインスキャンカメラ


Line Camera

ラインスキャンカメラはデジタルカメラの方式の一種で、普段はその存在には気づきにくいものの、意外に身近なところで活躍しています。今回はそんなラインスキャンカメラを製作・実験してみます。

ラインスキャンカメラのキーデバイスであるCCDラインセンサですが、10年以上前、既にジャンク屋で入手していました。しかし、当時利用可能な電子デバイスでは、このようなプロジェクトの実現は困難で、将来に望みを託してラインセンサはジャンク箱で眠り続けていました。というか、無理だと分かって投げ出した。

やがて半導体技術の進歩と開発環境の充実・低価格化により、気がついたときにはプロジェクトは現実味をおびていました。このように、プロジェクトの実現可能な環境が整ったため、満を持しての挑戦ということになりました。2010年現在、これらに加えArduinoやmbedのようなフレームワークの普及により、入門レベルでも高性能な32ビットマイコンやGバイト級の大容量メモリカードを易々と使いこなせるようになりました。すごい時代になったものです。まぁ、それが電子工作と言えるかどうかは別として。

ラインスキャンカメラとは

原理

図1. エリアカメラとラインカメラ
Fig.1

ラインスキャンカメラとは、撮像素子にラインセンサ(一次元CCD)を使用したカメラのことを言います。普通のカメラでは、エリアセンサ(二次元CCD)を使用してで像を捉えるのに対し、ラインカメラではで像を捉えます(図1)。

ラインカメラも最終的には二次元イメージを得ることになりますが、一度に一本の線しか取り込めません。したがって、被写体またはカメラを動かすことで位置をずらしながら一ラインづつ取り込み(副走査という)、メモリ上にそれを並べて二次元イメージを組み立てることになります。しかし、得られたイメージの副走査方向(ラインに直角)はライン上における時間軸を示すという点がエリアカメラとの決定的な違いになっています。

フィルムカメラにもこれと似たような物としてスリットカメラというものがあります。フィルムを巻き上げながらスリット(ぼほ一次元)を通して露光することにより、同様に二次元イメージとして撮影しているのです。

特徴と用途

ライン スキャン カメラには、主に次のような特徴があります。

これらの特長から、ラインスキャンカメラは主に次に示すようなものに使われています。ラインセンサというのは、エリアセンサに並びごくありふれた、しかし重要な電子デバイスなんですね。

ハードウェア

機能

図2. ブロック図
Block Diagram

図2に製作したラインスキャンカメラの機能ブロック図を示します。ラインセンサで電気信号に変換された一次元像は、ゲインやオフセットを調整したあとデジタイズされ、数値データとして制御部に送られ、モニタ表示および記録されます。ラインレートはCCDの仕様に基づき、500~2000ライン/秒とします。

電子回路はケースに組み込む都合上、3つの基板に分割し、それぞれの基板はFPCケーブルで接続します。基板については一品物なので、時間とお金がかかりやり直しもきかないプリント基板は起こさず、手っ取り早くプロト基板上にUEW配線で作成します。

ケースと光学系

写真2. 製作したケース
case

写真2に製作したケースを示します。今回のプロジェクトでは、ある程度精度の要求される光学系を含むため、ちゃんと寸法を出して正確に組み立てる必要があります。また、参考までに、カメラの構造を考えるときに描いたスケッチを示します。アナログ基板のマウントは、無限遠を調整できるようにしておきます。

種となるケースにはタカチのABSケースのSW-85Bを使用しました。レンズマウントは、産業用カメラとして標準的なCマウントとしています。Cマウント単体の入手は一般には困難ですが、C-CSマウント変換アダプタがCマウントとして使えるので、これを流用しています。ケースの底にはUNCナットを取り付けて、カメラを三脚にマウントできるようにしておきます。また、ケース内部には導電塗料を吹いてシールド効果を持たせておきます。

アナログ基板

写真3. アナログ基板
PCB
回路図 | 動作波形

写真3に製作したアナログ基板を示します。ラインセンサとアナログ信号処理回路で、カメラの目に当たる重要な部分です。使用するラインセンサは、東芝のモノクロCCD(TCD132D)です。CCDはそのままでは赤外線領域に広く感度を持つため、CCDの受光窓にはIRCFを取り付けてCCDの分光感度を人間の代表的な視感度-波長特性に近くなるように補正しておきます。CCDはコントロール基板からのタイミング信号で駆動されます。CCDから出力された映像信号は、オフセット調整および可変ゲインアンプ(AD8830)でレベル調整され、ADC(ADC1173)に入力されます。ADCで8ビット値にデジタイズされた映像信号はコントロール基板へ送られます。ピクセルレートは0.5MHz~2.1MHz程度まで可変しますが、ADCのサンプリングレートの下限は1MHzになっています。このため、ADCはピクセルレートの倍速で駆動し、1サンプル置きにデータを取り込むようにしています。

コントロール基板

写真4. コントロール基板
PCB
回路図

写真4に製作したコントロール基板を示します。マイコンには最近の電子工作界で大流行になっている各種ARMマイコンからNXPのLPC2368を使用します。LPC2368のコアCPUは72MHz動作のARM7TDMIで、512Kバイトのフラッシュメモリと、32K+16K+8KバイトのSRAMがオンチップに集積されています。データストレージにはmicroSDメモリカード(SDC)を使用します。LPC2368にはMCIが内蔵されているので、SDCを4-bitネイティブモードで制御できます。CCDの駆動はマイコン単体では難しいため、PLD(LC4256V)を1個使用します。PLD上にはCCD駆動信号生成回路と、高速なピクセルデータ入力のためのデータFIFOを構成します。電源回路ではロジック電源(3.3V)とアナログ電源(12V)を生成しています。

ディスプレイ基板

写真5. ディスプレイ基板
PCB
回路図

写真5に製作したディスプレイ基板を示します。ケースの後ろ側に配置され、主にユーザI/Fを受け持ちます。主な搭載デバイスは、OLEDパネル、スイッチ類、microSDメモリカードソケットです。メモリカードはケースの蓋を開けて抜き差しします。

ソフトウェア

データの取り込み

ピクセルレートは最大2.1Mピクセル/秒、つまり映像データも約2.1Mサイクル/秒のレートでA-Dコンバータから出力されるので、まずはこれを取りこぼすことなくマイコンのRAMに取り込む必要があります。毎秒2Mサイクルの転送処理はマイコン単体では難しいため、映像データは、まずPLD内のバッファ(FIFO)に格納します。そして、FIFOの半分までデータが埋まったときマイコンに割り込み要求(DRDY#)を出します。マイコンはそれを受けて、FIFOサイズの半分のデータを一度に引き取ります。FIFOサイズは16バイトなので、割り込みレートはピクセルレートの1/8(約260kHz)になり、割り込みによるデータ転送が可能になります。この処理は最優先で行われる必要があるため、ARM7TDMIのFIQ機能を利用します(最近のCortex-M3コアではFIQ機能が削除されてしまいました)。

CPUがFIQに応答するとFIQ専用のバンクレジスタに切り替わり、コンテキスト切り換え処理なしに割り込みサービスを実行できます。FIQルーチンはその機能を最大限に生かすため、アセンブラで記述することが普通です。実際に確認したFIQの応答波形によると、無負荷時では0.8μs以下でデータ引き取りが終わっています。SDCのデータ転送中(DMA動作時)は、バス調停の待ち合わせがあるためか最大で2μsほどかかっていますが、それでも十分に余裕があることが分かります。

1ラインで出力されるピクセル数は1094で、そのうちダミーピクセルを除いた1024の有効ピクセルがメモリに取り込まれます。各ラインの開始時には割り込み信号(SYNC#)が出力され、ラインの同期を取ります。

データの記録

取り込まれたデータは、画像ファイルとしてSDCに記録することができます。ファイルフォーマットは、BMPファイル(8bitグレースケール)とします。幅は1024ピクセル固定、高さは記録しただけとなります。ファイル名は\DCIM\LCAM\Ynnnn.BMP(nnnnはシリアル番号)で格納されます。この辺は普通のDSCと同じですね。

単に書き込むと言ってもマイコンシステムではその実現には高いハードルがあります。一定のレートで取り込まれる映像データを遅延無くファイルに書き込む必要があるからです。このプロジェクトでは、最高速でスキャンしたときのデータレートは2Mバイト/秒になり、これを維持しなければなりません。幸いなことに、LPC2368にはMCI(SDC/MMCインターフェース)があり、ファイル読み出し8Mバイト/秒、書き込み6Mバイト/秒程度のスループットが得られています。ただし、これは数Mバイト以上のデータを転送したときの平均値です。実際にはSDCの内部処理やFATファイルシステムのオーバーヘッドなどの影響で、瞬間的にはデータ転送が止まっている時間があります。そのため、この間の映像データを溜められるだけのバッファが確保されていないと、バッファオーバーランが発生して記録データに欠落が生じてしまいます。しかし、メモリの乏しいマイコンシステムでは、十分なバッファを確保できないことが多いのです。

では、実際に許容される処理時間を見積もってみます。バッファには内蔵RAMを32Kバイト割り当て、半分(16Kバイト)埋まる毎にそれをファイルに書き込む、いわゆるリングバッファ(FIFO)処理としています。バッファが半分埋まる時間は8msになります。つまり、8ms毎に発生する16Kバイトの書き込み要求をそれぞれ8ms以内に処理しなければならない、ということになります。このプロジェクトでは次のような対策を講じた結果、バッファオーバーランの無い連続書き込みを実現できました。

ファイル書き込み中に起きる遅延で最も大きいのが空きクラスタの検索によるもので、リアルタイムシステムではいつも頭の痛い問題です。多くのファイルシステムでは多かれ少なかれ発生し、予測も難しく場合によっては秒単位に及びます。これを避けるため、このプロジェクトではクラスタプリアロケーション(seek関数でファイルを拡張し、予めクラスタを割り当てておく)というテクニックを使って、データの書き込み中は空きクラスタの検索およびFATの更新が発生しないようにしています。さらに、ファイルシステムの高速シーク機能を使ってFATの読み込みも無くしています。

ファイルへの書き込みはクラスタ境界にアライメントするようにして、個々の書き込み処理でSDCに対するライトトランザクションが1回で済むようにします。ファイルは先頭がSDCのAU境界にアライメントするように調整します。このようにすると、記録開始時に起こりやすい原因不明の大きな遅延を回避できるようです。

このようにしてファイルシステム上の不確定要素を取り除いたとしても、SDCの内部処理による遅延は依然として避けられないので、少しでも実力のあるカードを選んで使うしかありません。スピードクラスはあまり当てにならないので、いくつかのブランドで実際に特性を調べてみました。その結果、東芝製のmicroSD(ただし国産のみ)が最も遅延時間が短く安定した性能を示しました。

データの表示

図3. 輝度表示とイメージ表示
disp1

得られる映像データが一次元であるため、普通のカメラのような二次元イメージでのモニタ表示はできません。そのため、代わりにオシロスコープのようにX軸をピクセル位置、Y軸を輝度で表示します。映像の確認に必要なのは明るさ(ゲイン)とピントです。スコープ表示からはピントが合っているかどうか分かりにくいので、輝度の下段にその微分値(の絶対値)も表示しています(図3a)。ピントが合うと画像データの高周波成分が増え、微分値も大きくなりピントの山が分かるというわけです(図3b)。これはコントラストAFの原理そのものです。

もう一つ必要な調整はラインレートで、これと対象物の移動速度の関係により、取り込まれた画像の縦横比が変わります。この表示モードでは、得られる二次元像を直接表示しますが、映像は連続して取り込まれるため、図3cに示すようにウォーターフォール表示(実際は上方向に流す)となります。撮影対象が静止しているときは一定の縦縞になるだけで像は現れません。このため、ラインレートを調整するときは、実際にスキャンするときの速度でカメラまたは対象物が動いている必要があります。

使い方

基本的にスリットカメラと同じですが、ラインスキャンカメラの場合はスリットカメラに比べてはるかに容易で、ピントと露出だけ合っていれば成功率はほぼ100%です。これは、スリット幅に相当するCCDの画素サイズがきわめて小さい(14μm×14μm)ことによります。カメラの操作はジョイスティック操作(上・下・左・右・中央)で行います。

カメラのセッティング

まず、対象物がラインに対して直角に通過するようにカメラをセットします。例えば、横方向に通過する物体や、パニングによる撮影なら、ラインが縦になるようにセットします。これは正確に合わせてやらないと、像が歪んで(長方形→平行四辺形)しまいます。

ピントの調整

表示モードの切り替え(スコープ表示とウォーターフォール表示)は右クリックにより行います。まず、スコープ表示モードにして、絞りとゲイン(上下クリック)で信号レベル(上段)を調整します。ゲインは左クリックで自動設定することもできます。次に、レンズのフォーカスリングを回して微分値(下段)が最大になる位置に調整します。何分、どこにピントが合っているのか、またそもそもどこを写しているのか分かりにくいので、可能なら目標位置にゼブラシート等を置いて確実に合わせると良いと思います。

ラインレートの調整

ウォーターフォール表示にして、動いている対象のアスペクト比が正しくなるようにラインレートを調整(上下クリック)します。これは計算で求める(ラインレート = 速度 * 像倍率 / 画素ピッチ)こともできます。例えば、100km/hの列車を50m離れて50mmレンズで撮影する場合、27.8 * 0.001 / 0.000014 = 1986 と、約2000ライン/秒となります。なお、ラインレートは正確である必要はありません。なぜなら、デジタル画像なのでアスペクト比の狂いや方向反転は簡単に補正できるからです。ただし、ラインレートが遅すぎると画像を大きく引き延ばすことになり、それだけ副走査方向の解像度は落ちます。ラインレートが速すぎる分には感度が犠牲になる程度の問題しかありません。ラインレートを変えると露光時間も変わるので、必要なら信号レベルを再調整します。

撮影

中央クリックで記録を開始・停止しますが、開始時にクラスタプリアロケーションに0.5秒ほど要するので、開始のタイミングには少し注意する必要があります。なお、準備完了後はボタンを放すまで記録を開始しないので、ヨーイ・ドン方式で開始タイミングを合わせることもできます。最大記録サイズはプリアロケーションしただけ(とりあえず10万ライン(約100MB))ですが、これは任意に変更できます。撮影した画像はそのままでは使える状態ではないので、PC上でガンマ補正および回転・反転・アスペクト比等の補正を加えて仕上げます。

資料

Sign