UVWステージのしくみ(位置決め用高精度XYθステージ)

工業用の画像処理の分野では画像を撮影して検査をするばかりでなく、半導体やFPDの業界では位置決め(アライメント)用途にも応用されています。今回は位置決め用途で用いられているUVWステージという、高精度のステージを紹介したいと思います。

 

通常のXYθステージUVWステージの基本構造は以下のようになっています。(若干異なる場合もあります。)

【通常のXYθステージ】

 

【UVWステージ】

 

UVWの各軸は、下図のように可動します。

 

UVWステージでXYθの位置決めが出来る原理は、

 

上図のようにU軸を動かすとステージはX方向へ移動し、V軸とW軸を同時に動かすとY方向へ移動します。
さらにU軸、V軸、W軸を同時に動かすとステージは回転します。

 

UVWステージの特徴は

  • ステージの高さを低く抑えられる
  • 二層構造なので、ベース面とステージ面との平行度を出しやすい
  • モーターが移動しないので、配線が用意(断線する可能性が低い)
  • 高精度

など。
なぜ?UVWステージが高精度の位置決めが可能になるかというと、特に回転方向の位置決めにおいて、同じ移動分解能のモータを使う場合、てこの原理のように、回転中心から離れた位置でステージを動かした方が回転の分解能は向上します。

 

FPDなどの位置決めにおいては、ステージのサイズも大きくなり易いので、ステージの両端で回転方向を制御するUVWステージは有効的に高精度な位置決めを可能としてくれます。

 

そんな良い事だらけのUVWステージですが、欠点もあります。

  • 移動可能範囲が狭い
  • ステージ制御が難しい

など。
移動可能範囲が狭いのは、もともと位置決め用途で使われる場合の多いUVWステージなので、最初にメカ的に粗調整しておき、UVWステージで精調整する場合が多いので、あまり問題にはならないと思います。

 

ステージ制御においては、位置決めマークの位置を画像処理で抽出し、ズレ量を算出し、目的の位置へと合わせ込みますが、この時のずれ量は通常、X、Y、θのずれ量で算出されます。
しかし、XYθ軸の移動量からUVW軸の移動量へと変換するには、ちょっと面倒なのでUVWステージの制御や位置決めの処理をライブラリ化している物もあるので、使用を検討してみては如何でしょうか?

 

【主なUVWステージメーカ】

ヒーハイスト精工株式会社

ガンマ補正(ルックアップテーブルの例)

ルックアップテーブルLookup Table【略LUT】)は、ある値の答えが必ず1つの値となる場合、あらかじめ答えを計算しておき、配列に格納しておくことで、毎回の計算をすることなく、 配列(テーブル)を参照することで効率的に処理を行う手法です。

 

画像処理では、コントラスト調整やガンマ補正などによく用いられます。

 

例えば、ガンマ補正の場合、ガンマ補正値をγ、補正前の輝度値をsrc
補正後の輝度値をdstとすると、補正式は

 

 

となりますが、この計算を全ての画素に対して処理を行うのは非常に非効率です。
そこで、例えばLUTという配列に、ガンマ補正の計算結果を以下のように格納しておきます。

 

src 0 1 2 3 ・・・ 252 253 254 255
dst 0 16 23 28 ・・・ 253 254 254 255

 

 

あとは、各画素に対して、

 

dst = LUT[src]

 

という変換をすればよいだけなので、高速に処理を行うことができます。
こうする事でルックアップテーブルを用いない場合は、画素数分のガンマ補正計算をしないといけないのが、ルックアップテールを用いる事で、この例の場合では、たかだか256回の計算だけで済みます。

 

ガンマ補正例

  • ガンマ補正前

 

  • ルックアップテーブル

 

  • ガンマ補正後

 

他にも二値化処理や、輝度値を0~255の範囲内に収めるための if 文の代わりなどにも応用できる場合があるので、処理を高速にしたい場合は、このルックアップテーブルが使えるかどうか?検討してみるのも良いと思います。

 

画像処理アルゴリズムへ戻る

 

光学部品/カメラバイヤーズガイド

マシンビジョンで使われるFA用のレンズ、照明、キャプチャボードなど紹介します。

 

ラインセンサ用レンズ

ニコン Fマウントレンズ
栃木ニコン 高性能、高精細ラインセンサ用レンズ
Fマウント、M72マウントなど
ラインセンサ用レンズとしては超高性能
ペンタックス Fマウント、Kマウント、Cマウントレンズなど
シグマ Fマウント、Kマウントレンズなど
タムロン Fマウント、Kマウントレンズなど
シュナイダー 高精細ラインセンサ用レンズ
京セラ Fマウント、M72マウントなど

 

Cマウントレンズ

ミュートロン Cマウント、M72レンズ、M42レンズ、テレセントリックレンズ
杉藤 Cマウントレンズ
ヴイ・エス・テクノロジー Cマウント、M72レンズ、テレセントリックレンズ
オプトアート Cマウントレンズ、テレセントリックレンズ、
ハロゲン、メタルハライド照明、ライトガイド、
LED照明などなど
東京パーツセンター Cマウントレンズ、近赤外用レンズ
興和オプトロニクス Cマウントレンズ、Fマウントレンズ

 

照明

シーシーエス LED照明
シマテック LED照明
1つのLED照明でローアングルから通常のリング照明までをカバーした
ドーナツ形状の「マルチライティング」が特徴的。
日進電子 LED照明、ストロボ光源
京都電機器 LED照明、高周波蛍光灯
電通産業 高周波蛍光灯、LED照明
レボックス LED照明
ラインセンサ用として、3Mを超えるシームレスな照明もあり。
アイテックシステム LED照明
比較的安価。通販サイトもあり。光ショップ

 

カメラ

アバールデータ 近赤外カメラ、ハイパースペクトルカメラ
Teledyne DALSA ラインセンサ(モノクロ、カラー(3ライン、3CCD))
TDIカメラ、HS Linkカメラ
エリアセンサ(モノクロ)、GigEカメラ
ほぼ全てアンチブルーミング機能付き
オムロンセンテック エリアンセンサ、ラインセンサ
CameraLink, CoaXPress, Opet-C:Link,GigE, USB
日本センサリデバイス(NED) ラインセンサ(モノクロ、カラー(3ライン))
高速CMOSラインセンサ
竹中システム機器 ラインセンサ(モノクロ、カラー(3ライン))
エリアセンサ(モノクロ、カラー)
東芝テリー ラインセンサ(モノクロ、カラー(3ライン))
エリアセンサ(モノクロ、カラー)
ソニー エリアセンサ(モノクロ、カラー)、
インテリジェントカメラ
日立国際電気 エリアセンサ(モノクロ、カラー)
Adimec エリアセンサ(モノクロ、カラー)
CameraLink、Geg-E、CoaXPress
e2v ラインセンサ(モノクロ、カラー(3ライン))
Basler エリアセンサ、ラインセンサ
CameraLink、Gig-E
JAI ラインセンサ(モノクロ、カラー(3CCD、4CCD))
エリアセンサ(モノクロ、カラー(Bayer、3CCD))
cis エリアセンサ(モノクロ、カラー(Bayer、3CCD))
フローベル エリアセンサ(モノクロ、カラー)
センサーテクノロジー エリアセンサ(モノクロ、カラー)
IDT エリアセンサ(ハイスピード)
アプロリンク エリアセンサ(モノクロ、カラー)

 

キャプチャボード

アバールデータ 画像入力ボード(エリアセンサ、ラインセンサ、カメラリンク、
アナログ、デジタル)
10TapCameraLink対応品、FPGA処理ボードなどもあり。

大人の事情により、一社のみの紹介です。って、私の会社だから...

 

その他

ミスミ カメラ、照明固定用ブラケットなど
エドモンド レンズ、ミラー、光学ベンチなど
光学界のミスミ的存在。ほとんど揃います。
シグマ光機 光学部品(レンズ、ミラー、プリズムなど)
精密ステージ、ハロゲン、メタルハライド光源、ライトガイド
モリテックス Cマウントレンズ、テレセントリックレンズ、
ハロゲン、メタルハライド照明、ライトガイド、LED照明などなど
品揃え豊富
エス・エフ・シー カメラ、照明スタンド
ケンコー 各種レンズフィルタなど
F-Cマウントアダプタなどもあり。
SUS アルミフレーム、リニアアクチュエータなど
ラインセンサの撮影システムを組む時に安価に組むことができます。

 

お問い合わせについて

本ページは会社とは関係なく非公認なのですが、公知ではあるので、キャプチャボードをご検討の場合、レンズやなども含めてご質問などありましたら、弊社の問い合わせページ製品についての問い合わせはよりお問い合わせ下さい。

「イメージングソリューションというHPを見たのですが...」と言って頂けると、話が早いかも?しれません。

 

マシンビジョンへ戻る

焦点深度、被写界深度とは何か?絞りとの関係

焦点深度、被写界深度などの各名称の位置については、下図は参照ください。

 

 

上図の物体面(左側)が被写体側で、像面(右側)がカメラのセンサ側です。

 

許容錯乱円

物体面上の点を撮影したときに、像面上では点として結像し、像面から前後に外れると
円として結像します。
この円のことを錯乱円といい、ピントが合っているとみなされる最大の円を許容錯乱円といいます。
マシンビジョンでCCDカメラを用いる場合、許容錯乱円にCCD画素の大きさが用いられる場合が
多いようです。

被写界深度

物体面(被写体側)において、ピントが合って見える範囲のことを被写界深度といいます。

焦点深度

ピントが合って見える範囲において、像面側(CCDなど)の結像範囲を焦点深度といいます。
被写界深度と混同する人が多いのでご注意下さい。
通常、被写体の撮影で大事な深度は被写界深度となります。

絞りと被写界深度との関係

レンズの絞りは 明るさを調整するもの という役目もありますが、被写界深度を調整するものという大事な役割があります。

例えば、人物の撮影などでは、人物の背景をボカして撮影するには、レンズの絞りを開いて撮影します。
背景がボケるということは、被写界深度が浅い事を意味しています。

しかしながらカメラを使った画像検査をする場合、被写界深度が深い方が理想的です。

被写界深度を深くするには絞りを小さく閉じると被写界深度は深くなります。
しかしながら、そうすると画像が暗くなります。

画像が暗くなるので、画像を明るくするには

  • 照明を明るくする
  • 露光時間を長くする
  • ゲインを上げる

のいづれかの対応が必要となります。
しかしながら、それとは逆に、

  • 照明は安い物を使いたい → すごく明るい照明は高い
  • 高速に撮影したい → 露光時間は短くしないと高速に撮影できない
  • ノイズは少なくしたい → ゲインを上げるとノイズが増える

と、相反する要求もあります。

そのため総合的にカメラの撮影システムを捉え、絞りを調整する必要があります。

撮影する画像の明るさを一定にしようとすると、一般的に以下のような関係になります。

絞り 大(開) 小(閉)
深度 浅い 深い
ゲイン
ノイズ 少ない

これらの関係がどのように画像へ影響を及ぼすか?をシュミレーションできるサイトがありますので、いろいろお試し下さい。

http://camerasim.com/camera-simulator.html

上記の設定値はカメラ用語なので、用語を置き換えるなら、
Lighting(照明の明るさ)、Disatance(撮影距離、ワーキングディスタンス)、Focal Length(焦点距離)
ISO(ゲイン)、Aperture(絞り)、Shutter Speed(露光時間)
という感じでしょうか。

 

 

ただし、この計算は収差のない理想的なレンズの場合の話で、実際には像面湾曲の影響により、
像を結ぶ位置が平面からズレてしまいます。

 

このズレ量がレンズメーカに聞いてもあまり教えてくれないので、結局は全視野において
像がボケることなく撮影できるか?は撮影してみないと分からない場合がほとんどです。

 

被写界深度の計算

<計算例>
画像数2353×1728mm、画素サイズ7.4×7.4μmのカメラを用い、
レンズの焦点距離が55mmのレンズを用い、物体距離(≒ワーキングディスタンス)
300mmで撮影を行いたい場合の被写界深度の計算

 

設定条件より
許容錯乱円 =7.4μm
F=2.8の場合

 

この計算はレンズ選定(視野、撮影距離など)のページで出来るようになりました。

レンズ選定上の注意

  • 各レンズには被写体にレンズを一番近づけることの出来る距離(最短撮影距離)が設定されています。
    撮影距離Dが最短撮影距離を下回らないようにレンズを選定して下さい。
  • レンズの許容カメラフォーマットもしくはイメージサークルがCCDのサイズ以上となるレンズを選定してください。
  • レンズの公式の計算は薄肉レンズモデルの計算です。計算結果には誤差が含まれます。

 

 

余談ですが...
35mmフィルムは35mmって言っているのに、なんで36mm???と思ったりもしますが、
35mmなのはフィルムの幅で撮影領域は36mm×24mmとなります。

 

 

レンズ選定(焦点距離、WD、被写界深度の計算)

下図のような、レンズの焦点距離 f やワーキングディスタンスの求め方を紹介します。

レンズの計算には、下図のような薄肉レンズモデルを用いて計算します。

計算に必要なのは、レンズの公式と倍率の計算式です。

レンズの公式 倍率

下記、表中に数値を入力し×××計算ボタンをクリックすると、それぞれの値を計算することが出来ます。

以下、物体距離 ≒ ワーキングディスタンスとして計算します。
また、下記計算中の『センサ幅 ℓ (mm)』の値はセンサの物理的な大きさを指定するのではなく、実際の撮影に使用するセンサの領域を指定します。
例)CCD素子サイズが7μmのセンサで5000画素使用する場合、センサ幅 ℓ (mm)は
7μm × 5000画素 = 35mm
とします。

ただし、ラインセンサでラインセンサの専用レンズでなく、一眼レフカメラ用のFマウント、Kマウントレンズを用いる場合は、経験的に、ここで説明している計算でレンズを選定するよりも、マクロのf=55mmぐらいのレンズを用い、ワーキングディスタンスで視野を調整した方がきれいな画像が撮影できると思います。

 

焦点距離 f を求める場合

レンズの公式、倍率の式を変形して、

として焦点距離を求めます。

センサ幅 ℓ (mm)
視野幅 L(mm)
ワーキングディスタンス a(mm)
焦点距離 f(mm)

ワーキングディスタンス a を求める場合

レンズの公式、倍率の式を変形して、

としてワーキングディスタンスを求めます。

センサ幅 ℓ (mm)
視野幅 L(mm)
焦点距離 f(mm)
ワーキングディスタンス a(mm)

被写界深度を求める場合

被写界深度は下図のように求めます。

として被写界深度を求めます。
CCDカメラの場合、許容錯乱円 ≒ CCDの画素サイズと して計算します。

ワーキングディスタンス a(mm)
許容錯乱円 ε(μm)
F値
焦点距離 f(mm)
前側被写界深度(mm)
後側被写界深度(mm)
被写界深度(mm)


※本計算は薄肉レンズモデルの計算です。計算値には誤差が含まれます。
計算結果は参考程度に参照して下さい。

 

備考

レンズ選定の式にはここに記載してある式とは別に

という図の場合、

の関係式から、焦点距離は

として求める!

というような説明も多いかと思います。 むしろ、こちらの方が多い?!

なぜか、カメラレンズメーカーのレンズ選定の式ではこちらの式を用いる場合が多く、
ガラスレンズメーカーは最初に紹介したレンズの公式を用いて紹介している場合が多いようです。
試しに両方計算してみると分かりますが、計算結果はさほど変わりません。
おそらく、薄肉レンズモデル計算の誤差範囲???

ということから、レンズの選定の場合には計算の簡単な、こちらの式を用いるのかもしれませんが、
どうにも、焦点距離fの示している距離が気持ち悪くて、最初に説明しているレンズの公式を用いた
説明としました。
本来、焦点距離fは無限遠からの光(平行光)が入射した時に、レンズの主点から光が1点に集まる場所までの
距離を現します。
ワーキングディスタンスもレンズ本体(筐体)の先端からの距離ですが…
この辺の名称の詳細はレンズ周りの名称のページを参照願います。

 

レンズ周りの名称

レンズの選定に知っておきたい名称についてまとめました。

 

 

ワーキングディスタンス(WD)

物体面からレンズの先端までの距離

フランジバック(FB)

レンズの取付面(フランジ)から像面までの距離
(代表値)
Fマウント:46.5mm(ニコン用レンズ)
Kマウント:45.46mm(ペンタックス用レンズ)
Cマウント:17.53mm

イメージサークル

像面に結像できる範囲(撮影可能な範囲)を径(Φ)で表します。
レンズを選定するときに、CCDの領域に外接する円の大きさ以上のイメージサークルを持ったレンズを選ぶ必要があります。

画角

画面上に鮮鋭な画像として写し込むことができる範囲を角度で表したもの。
イメージサークルが大きいか焦点距離が短いと画角は大きくなります。

前側焦点、後側焦点

平行な光束を入射したときに収束する点

前側主点、後側主点

焦点からレンズ側に向かって焦点距離 f だけ離れた位置
この位置はレンズによって異なりますが、一般的に主点の位置は公開されていません。

撮影距離

物体面から像面までの距離
とくにレンズを用いたときに最短で撮影できる距離のことを最短撮影距離といいます。

 

多ビット(10Bit,12Bit,30Bit)画像データの表示、フォーマット

多ビット(10Bit、12Bitなど)の画像データは10Bitや12Bitの型が存在しないため、モノクロの場合はushort型の16bit中、下位10Bit、12Bitなどを使って画像データを格納します。
30Bitとは、R,G,Bの各色が10bitのデータとなるカラー画像の場合(RGB101010)で32Bit中の下位30Bitを使って画像データを格納します。

 

この××Bit中のどのビットをR,G,Bの色に割り振るかは、ビットフィールドというものを使います。
ビットフィールドを使うにはBITMAPINFOHEADERbiCompressionBI_BITFIELDSに設定します。

 

どのビットをR,G,Bの色に割り振るかはRGBQUAD型の32Bitを使って有効ビットを指定します。
bmiColors[0]R(赤)bmiColors[1]G(緑)bmiColors[2]B(青)の色のビットを設定するのに用います。

 

実際の描画にはWin32APIのSetDIBitsToDevice関数かStretchDIBits関数を使います。

 

モノクロ画像の場合(10~16Bitのとき)

(例)モノクロ10Bitの場合、biBitCount = 16 とし、16Bit中下位10Bitを使います。
表示に有効なビットを以下のように指定します。

画像データ 00000011 11111111
bmiColors[0] 00000000 00000000 00000011 11111111
bmiColors[1] 00000000 00000000 00000011 11111111
bmiColors[2] 00000000 00000000 00000011 11111111

以上より、bmiColorsを10進数で表示すると以下のようになります。

bmiColors[0].rgbReserved = 0;
bmiColors[0].rgbRed          = 0;
bmiColors[0].rgbGreen       = 3;
bmiColors[0].rgbBlue          = 255;
bmiColors[1].rgbReserved = 0;
bmiColors[1].rgbRed          = 0;
bmiColors[1].rgbGreen       = 3;
bmiColors[1].rgbBlue          = 255;
bmiColors[2].rgbReserved = 0;
bmiColors[2].rgbRed          = 0;
bmiColors[2].rgbGreen       = 3;
bmiColors[2].rgbBlue          = 255;

カラー画像の場合(R10G10B10Bitのとき)

(例)カラー10Bitの場合、biBitCount = 32 とし、32Bit中、下位30Bitを使います。
表示に有効なビットを以下のように指定します。

画像データ 00111111 11111111 11111111 11111111
bmiColors[0] 00111111 11110000 00000000 00000000
bmiColors[1] 00000000 00001111 11111100 00000000
bmiColors[2] 00000000 00000000 00000011 11111111

以上より、bmiColorsを10進数で表示すると以下のようになります。

bmiColors[0].rgbReserved = 63;
bmiColors[0].rgbRed          = 240;
bmiColors[0].rgbGreen       = 0;
bmiColors[0].rgbBlue          = 0;
bmiColors[1].rgbReserved = 0;
bmiColors[1].rgbRed          = 15;
bmiColors[1].rgbGreen       = 252;
bmiColors[1].rgbBlue          = 0;
bmiColors[2].rgbReserved = 0;
bmiColors[2].rgbRed          = 0;
bmiColors[2].rgbGreen       = 3;
bmiColors[2].rgbBlue          = 255;

サンプル画像

画像データはこちら(16BitGray.zip

【画像データプロパティ】
幅:1024
高さ:256
ビット数:16
BitField:16ビット中、下位10ビットの上位8ビットを表示設定
輝度値:0~1023のグラデーション

上記のビットマップファイルをTSXBINというバイナリエディタでヘッダ部分を表示すると以下の通りです。(値は16進数表示)

エクプスローラのプロパティや標準的なビューアソフトでは16ビットとして認識されない場合が多いのでご注意下さい。

注意事項

この記事では10Bitなどの多ビット画像データを8Bitデータにシフト処理などする事なく、画像データを表示する方法を説明しています。実際のモニタ上にはRGB各8Bitの解像度で表示されます。
モニタ上にRGB各10Bitで表示するには、別途、

■10Bit対応のモニタ
■10Bit対応のビデオカード
■10Bit対応の表示プログラム(Direct-X、OpenGL)

の3点セットが必要となります。

(参考資料)
10ビット/8ビット表示はドコが違う!?:「FlexScan SX2462W」のDisplayPort入力で“約10億色リアル表示”を体感する (1/3) – ITmedia +D PC USER
株式会社エーキューブ – ナナオ社製10bit対応モニタ「Flexscan」「ColorEdge」による動作確認
AMD(ATI)の資料
nVIDIAの資料

最近のCCDカメラでは8Bitのみならず、10Bit、12Bitの出力を持つカメラが増えてきています。多ビットの画像データは低コントラストの画像データを処理するには有功な場合が多いのですが、ほとんどの画像処理ライブラリでは多ビットの画像データに対応していない場合が多いため、画像処理部分のプログラムを全て自作する必要が出てきます。
また、8Bitが10Bitになるだけで、カメラから画像入力ボードへのデータ転送量は倍(16Bit/画素)となるため、フレームレートやスキャンレートの最速レートを出せなくなる場合があります。

 

そのため、総合的に捉えて多ビットの画像データをお取り扱い下さい。

ビットマップファイルフォーマット

ビットマップファイル(*.bmp)のファイルフォーマットです。

 

ビットマップ全体の構造

BITMAPFILEHEADER 14Byte
BITMAPINFOHEADER 40Byte
カラーテーブル(無い場合もあり) 4Byte*Index数
画像データ

 

各構造体について

■BITMAPFILEHEADER

typedef struct tagBITMAPFILEHEADER { 
	WORD bfType; 
	DWORD bfSize; 
	WORD bfReserved1; 
	WORD bfReserved2; 
	DWORD bfOffBits; 
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

 

bfType ファイルタイプ ‘BM’
bfSize ファイル全体のサイズ(バイト数)
bfReserved1 予約領域 常に0
bfReserved2 予約領域 常に0
bfOffBits ファイル先頭から画像データまでのオフセット数(バイト単位)

 

■BITMAPINFO

typedef struct tagBITMAPINFO { 
	BITMAPINFOHEADER bmiHeader; 
	RGBQUAD bmiColors[1]; 
} BITMAPINFO, *PBITMAPINFO;

●BITMAPINFOHEADER

typedef struct tagBITMAPINFOHEADER{
	DWORD  biSize;
	LONG   biWidth;
	LONG   biHeight;
	WORD   biPlanes;
	WORD   biBitCount;
	DWORD  biCompression;
	DWORD  biSizeImage;
	LONG   biXPelsPerMeter;
	LONG   biYPelsPerMeter;
	DWORD  biClrUsed;
	DWORD  biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
biSize 構造体のサイズ 40
biWidth 画像の幅(ピクセル数)
biHeight 画像の高さ(ピクセル数)
値が負の場合、画像の上下が逆になる
biPlanes プレーン数 常に1
biBitCount 1画素あたりのビット数 1,4,8,16,24,32
biCompression 圧縮形式 BI_RGB, BI_RLE8, BI_RLE4
BI_BITFIELDS, BI_JPEG, BI_PNG
biSizeImage 画像データのサイズ(バイト数) BI_RGBの場合0でも可
biXPelsPerMeter 水平方向の1Mあたりの画素数 0でも可
biYPelsPerMeter 垂直方向の1Mあたりの画素数 0でも可
biClrUsed カラーテーブルの色数 0でも可
biClrImportant 表示に必要なカラーテーブルの色数 0でも可

 

●RGBQUAD(カラーテーブル)

typedef struct tagRGBQUAD {
	BYTE    rgbBlue;
	BYTE    rgbGreen;
	BYTE    rgbRed;
	BYTE    rgbReserved;
} RGBQUAD;
rgbBlue 青の輝度値 0~255
rgbGreen 緑の輝度値 0~255
rgbRed 赤の輝度値 0~255
rgbReserved 予約領域 常に0

 

biBitCountが1,4,8のとき、RGBQUAD構造体のカラーテーブルが指定されます。
biBitCountが24,32のときは存在しません。
ただし、biCompressionがBI_BITFIELDS かつ、biBitCountが16,32の場合、
多ビット(10Bit,12Bitなど)が表示可能となり、ビットフィールドが指定されます。

 

■画像データ

モノクロ画像の場合、輝度値が格納されています。

24Bitカラーの場合、B,G,R,B,G,R・・・の順で各輝度値が格納されています。
32Bitカラーの場合、B,G,R,A,B,G,R,A・・・の順で各輝度値が格納されています。

 

画像データは、画像の左から右、下から上へ向かう順番で格納されます。

 

 

また、1行あたりのメモリのサイズは4の倍数バイトになるように調整されています。
この値は以下のようにして計算しています。

 

VBの場合

((biWidth * biBitCount + 31) \ 32) * 4

Cの場合

((biWidth * biBitCount + 31) / 32) * 4

 

4の倍数バイト(32ビットの倍数)になるように調整しています。

 

ビットマップファイルを開く場合の注意点について

ビットマップファイルを開く場合、ヘッダ情報をもとに画像データ格納用のメモリを確保し、
そのメモリにデータを格納しますが、ヘッダの値はすべて正しく記載されているとは限りません。私の場合、以下の値を信じてメモリの確保などを行っています。

biWidth, biHeight, biBitCountを用いて画像データ格納用メモリの確保
biOffBitsを用いて、画像データまでのファイルのシークを行う。

biSizeやbiSizeImageなどは信じない方が良いと思います。

 

フィルタ処理の高速化アルゴリズム(縦横に処理を分ける)

前回、フィルタ処理の高速化アルゴリズム(重複した計算を行わない)で紹介した方法ではカーネルの値が全て同じでないと使えないので、今回はフィルタ処理を縦方向と横方向に分けて行う事でフィルタ処理の高速化を行う方法をガウシアンフィルタを例にとって紹介します。

 

ガウシアンフィルタのカーネルには、

 

が良く用いられますが、この処理を注目画素の周辺の輝度値をI0~I8とした場合、
ガウシアンフィルタの処理を行列で

 

と、表すこともでき、この事は縦方向に3×1のガウシアンフィルタ処理をおこなってから、
横方向に1×3のガウシアンフィルタ処理を行うことを意味しています。
(横方向に処理をしてから縦方向に処理をしても同じです。)

 

このように処理を縦と横に分けることで、カーネルのサイズm×nの場合、通常の処理では
m×n回の掛け算を行うところ、m+n回の掛け算で済む事になります。
(ただし、縦横に処理を分ける事で全画素を2回参照することになるので、カーネルのサイズが
小さいと効果はあまりありません。)

他にも、移動平均フィルタの場合

ソーベルフィルタの場合

 

となります。
ソーベルフィルタの行列を見ると、縦方向にガウシアンフィルタ処理をしてから、横方向に微分処理している事が分かりやすくなっているかと思います。

 

また、比較的処理の重いメディアンフィルタにおいても、処理を縦と横に分けることによって、
ほぼ、同様な効果を得ることができます。
厳密には同じ結果にはならないのですが、スパイクノイズを除去するという意味では
十分な結果を得る事が出来ます。

試しに何回か、メディアンフィルタ処理を縦方向に1列分の処理を行ってから、横方向に1列分の
処理を行ってみましたが、ほぼ、良好な結果を得る事ができていると思います。
(画像にするともう少し分かりやすいかと思いますが、プログラムが無いもので...)

 

 

画像処理アルゴリズムへ戻る

 

フィルタ処理の高速化アルゴリズム(重複した計算を行わない)

画像フィルタ処理の高速化のテクニックを移動平均フィルタを例にとって紹介したいと思います。

 

カーネルのサイズが5×5の移動平均フィルタの場合、注目画素の周辺の5×5の輝度値を合計し、
その輝度値の合計を画素数(5×5=25)で割る処理をラスタスキャンしながら、全画素に対して
処理を行います。

 

 

ここで、隣の画素へ処理が移った時に、輝度値の合計の計算処理は前に行った輝度値の合計の
処理とかなりかぶっている(下図の緑色の部分)事に気が付きます。

 

 

そこで、最初の輝度値の平均値を計算をした時の輝度値の合計値を保持しておき、最初の輝度値の
合計値から、最初のカーネルの左端の1列分の輝度値(上図の赤色の部分)を引き、
次のカーネルの右端の1列分の輝度値(上図の青色の部分)を足すと、次のカーネル内の
輝度値の合計値を求める事が出来ます。

 

そうすると、カーネル内の輝度値の合計の計算に25回の足し算をしていたところ、5回の引き算と
5回の足し算の計10回の計算で済ませることが分かります。
この効果はカーネルサイズが大きくなればなる程、大きくなります。

 

さらに画像の1行分の合計値を確保するメモリを確保しておくと、縦方向に関しても同様の処理が
できるので、高速化が期待できます。

 

と、今回は画像のフィルタ処理を例にとって紹介していますが、この考え方は他にもいろいろと
応用が効くので、輝度値の合計の計算に留まらず、毎回同じような処理をしているな~と思ったら、
前回行った処理の使いまわしができないか?検討してみると良いでしょう。

 

画像処理アルゴリズムへ戻る

 

標準画像データベースSIDBA(Standard Image Data-BAse)

画像処理をしていると、一度は見た事があるであろう、マンドリルの画像↓

ですが、これは画像処理用の  標準画像データベースSIDBA(Standard Image Data-BAse)から用いられています。このSIDBAの画像データ入手先ですが、SIDBAで検索すると、あちこちで画像が公開されているので、どこが本家なのか?良く分かりませんが、比較的入手しやすいホームページは以下のページでしょうか...

 

※女性の画像(レナ)も有名なのですが、本人の希望により、使って欲しくないとのことなので、使用は避けましょう。
(参考)https://www.zaikei.co.jp/article/20200717/576594.html

神奈川工科大学

http://www.ess.ic.kanagawa-it.ac.jp/app_images_j.html

南カリフォルニア大学

http://sipi.usc.edu/database/

 

画像処理アルゴリズムへ戻る

 

テンプレートマッチング(template matching)

画像の中から指定した画像(テンプレート)と似ている位置を探すことを
テンプレートマッチング(template matching)と言います。

 

テンプレート 画像

 

このとき、テンプレートと画像データがどれだけ似ているか?という評価値(類似度または相違度)にはいくつかあり、次に示すような値を用います。

 

以下の式において、テンプレートの輝度値の値をT(i,j)、画像の輝度値の値をI(i,j)とします。
座標の(i,j)はテンプレートの幅をm画素、高さをn画素としたとき、左上(もしくは左下)を(0,0)、右下(もしくは右上)を(m-1、n-1)とします。

 

SSD(Sum of Squared Difference)

SSDはテンプレートをラスタスキャンし、同じ位置の画素の輝度値の差の2乗の合計が用いられます。
SSDの値が小さいほど、似ている位置となります。

 

SAD(Sum of Absolute Difference)

SADはテンプレートをラスタスキャンし、同じ位置の画素の輝度値の差の絶対値の合計が用いられます。
SADの値が小さいほど、似ている位置となります。

 

正規化相互相関【NCC:Normalized Cross-Correlation】

テンプレートと画像との類似度として、以下の正規化相互相関を用いられる場合もあります。類似度が1に近いほど、似ている位置となります。

 

ちなみに、この計算式は内積の式をCosθ = の式に変形した式と同じ事にお気づきでしょうか?上式を以下のように変形すると、M×N次元のIのベクトルとTのベクトルの内積に見えてきませんか?

 

 

正規化相互相関【ZNCC:Zero-mean Normalized Cross-Correlation】

上記NCCの相互相関係数ではテンプレートや画像の明るさが変動すると、NCCの値もふらついてしまうので、テンプレートおよび画像の輝度値の平均値をそれぞれの値から引いて計算することで、明るさの変動があっても安定的に類似度を計算することができます。

ここで、この式はテンプレートの領域内の輝度値の平均値を計算してから、さらに輝度値から平均値を引くため、標準偏差の時にも説明したように、この式でそのままプログラミングすると効率の悪いプログラムとなってしまいます。そのため、今回も同様にRZNCCの式を変形します。

 

テンプレートの平均輝度値およびテンプレートと同じ領域の画像の輝度値の平均は

 

 

で求まることから、この値をRZNCCの式に代入して整理すると、

となります。この式を用いると、プログラム的には1パスで済むでの計算効率が良くなります。

 

ΣΣ×××の部分がなんだか難しく見える方は、C言語に置き換えて

 

Sum = 0;
for(j = 0; j < N; j++){
for(i = 0; i < M; i++){
Sum += ×××;
}
}

 

と置き換えて読んで下さい。

 

ここで説明しておきながら、最近の工業用途では、この正規化相関の方法よりもパターンの輪郭に基づき、回転やスケール変動などにも対応したマッチング(輪郭サーチ)が一般的になってきています。

最近では、さらにカメラが動いてもマッチングする三次元マッチングなども登場してきています。
正規化相関では明るさの変動にも強く優れたアルゴリズムのように聞こえるかもしれませんが、パターンが重なった場合や欠けた場合に意外と弱かったりもします。

 

また、このテンプレートマッチングでは、テンプレートと画像を重ね合わせたとき、同じ画素の位置の輝度値が明暗がどれだけ似ているか?という事を評価しています。
そのため、例えば顔写真を登録しておいて、撮影した画像の中から似ている人を見つけ出す!みたいな使い方はできません。
人間の感性での似ている事とはズレがある事に注意して下さい。

 

画像処理アルゴリズムへ戻る

 

疑似カラー(Pseudo-color)

三次元データやサーモグラフィのようにデータを画像にした場合には、モノクロで表示するよりも、色を付けて表示した方が見やすい場合があります。

 

モノクロ表示 疑似カラー表示

 

このグレーの色に疑似的に色を付ける方法を疑似カラー(Pseudo-color)と言います。この色の付け方は色相を使って青~緑~赤へと変化させてもいいのですが、もう少し簡単な方法を紹介します。
青~緑~赤~青へと色を変化させるには以下のようなパターンでR,G,Bの値を変化させます。

 

 

このパターンは青~緑~赤~青の色相で言うと一周分なので、一般的に用いられるのは青~緑~赤ぐらいまでなので、上図の0~240°部分を8Bitの輝度値に割り当て

 

 

のようにすると、このようなグレースケール↓に

 

疑似カラーを割りつけると、このように↓なります。

 

このようにクレースケールにカラーを割り当てることで、より画像を見やすくしています。モノクロ8Bitの画像データの場合は、画像データはそのままに、カラーテーブルを変更するだけで、疑似カラー表示する事が出来ます。

 

画像処理アルゴリズムへ戻る

 

色相、彩度、明度の計算方法

色相Hue:色合い)、彩度Saturation:鮮やかさ)、明度Brightness,Lightness,Intensity,Value:明るさ)については、以前、変換式には色相、彩度、明度ほかのページにまとめたのですが、実は訳も分からず公式だけをまとめていました。

 

で、なんだか気持ちが悪かったので色相、彩度、明度について、よ~く調べてみました。
私なりの理解ですが、以下にまとめました。

 

R、G、Bの色空間については、下図のようにRGBをXYZのように三次元座標で表すと、一辺の長さが255で表される立方体の範囲内で全ての色を表す事が出来ます。(R,G,B各8bitの場合)

 

この立方体を白(255、255、255)に位置から黒(0、0、0)の方向へ見て、R軸を右側に取ると、

 

 

のように、正六角形となります。
この時、の方向を0°として、反時計回りにの位置が120°240°色相(0~360°(2π))を定めます。
彩度は一番外側の六角形に対して、どの割合の位置に配されているかを0~1.0で表したものが彩度となります。

 

詳細は後述しますが、色相彩度はカメラやパソコンなどの性能評価(使いやすさ、価格、処理速度など)を表す時に用いるレーダーチャート(クモの巣グラフ)もどきみたいな物?!と思うと、自分の中で少し整理ができました。

 

さらに、この六角形の高さ方法に明度を割り振ると、HSV(六角錐モデル)やHLS(双六角錐モデル)となります。
それぞれの違いは明度の定義が異なり、R、G、Bの最大輝度値をImax、最小輝度値をIminとしたときに

明度V = Imax

としたものがHSV

明度L = ( Imax + Imin ) / 2

としたものがHLSとなり、明度の値は0~1.0で表されます。

これを立体で表すと

 

HSV(六角錐モデル)

HLS(双六角錐モデル)

となります。
このHSV、HLSともに、六角錐の斜面の部分が彩度が1.0となります。

 

以下、色相、彩度、明度の詳細な計算方法です。

 

HSVの計算方法

はじめにR、G、Bの輝度値の範囲を0~255から0~1.0となるように変換します。
(R、G、Bのそれぞれの値を255で割ります。)

 

【色相Hの求め方】
下図のように、0°方向にR、120°方向にG、240°方向にBだけ進み、最後の点の位置のR軸に対する角度が色相となります。

 

 

この最後の点の座標は中心を(x、y) = (0、0) とすると、R、G、Bの方向のなす角度から

 

 

となり、xとyより色相Hが求まります。

 

 

ただし、アークタンジェントの計算が出来ない場合など、この方法とは別に、近似的に求める方法もあります。(こちらの方が一般的)

 

下図を見ても分かる?ようにR、G、Bの成分の比を比べ、

Rが最大の場合、色相は-60°(300°)~60° (R方向の0°±60°)
Gが最大の場合、色相は 60°~180° (G方向の120°±60°)
Bが最大の場合、色相は 180°~300° (B方向の240°±60°)

の範囲内に色相は収まります。

 

 

以下、Rの値が最大の場合を例に取って説明したいと思います。

 

下図のように、2つの矢印の長さが分かれば、その矢印の比で角度60°を分割することで、角度(色相)を近似することが出来ます。

 

 

R、G、Bの大きさがR≧G≧Bの場合

 

色相H = 60° × (G – B) / (R – B)

R、G、Bの大きさがR≧B≧Gの場合

 

色相H = 60° × (G – B) / (R – G)

 

となります。
ただし、この場合、色相の値が負となるので、

 

色相H = 60° × (G – B) / (R – G) + 360°

 

とします。

 

と、なる理屈を理解するのに苦労しました...
図中に書いてある黄色い正三角形がポイント!
正三角形なので、三辺の長さが等しい分けで。
R以外のGやBが最大となる場合も理屈は同じです。
120°づつ回転させて考えてみると分かります。

 

この式を一般的に書くと、R、G、Bの成分のうち、最大の成分をImax、最小の成分をIminとすると

ImaxがRのとき

ImaxがGのとき

ImaxがBのとき

となります。

 

【明度Vの求め方】

明度は、もともとHSVの定義よりR、G、Bの成分のうち、最大の成分をImaxとすると

明度V = Imax

 

とします。
明度Vの範囲は0~1.0となります。

 

【彩度Sの求め方】
R、G、Bの成分のうち、最大の成分をImax、最小の成分をIminとすると

 

彩度S = (Imax – Imin) / Imax

 

となります。
彩度Sの範囲は0~1.0となります。

 

 

HLSの計算方法

【色相Hの求め方】
色相HはHSVの色相Hの求め方と同じです。

 

【明度Lの求め方】
明度Lは、もともとHLSの定義よりR、G、Bの成分のうち、最大の成分をImaxとすると

 

明度L = ( Imax + Imin ) / 2

 

とします。
明度Lの範囲は0~1.0となります。

 

【彩度Sの求め方】
R、G、Bの成分のうち、最大の成分をImax、最小の成分をIminとすると

 

L≦0.5のとき

彩度S = (Imax – Imin) / (Imax + Imin)

L>0.5のとき

彩度S = (Imax – Imin) / (2 – Imax – Imin)

 

となります。
彩度Sの範囲は0~1.0となります。

 

以下、補足説明です。
彩度Sは下図の外側の六角形に対して、内側の六角形の大きさの割合で求められます。

 

 

この六角形の大きさはR,G,Bの輝度値が最大となる軸上で考えると比較的分かりやすいと思います。
今回はRの値が最大となる場合とします。

 

HLSは双六角錐モデルであるため、明度Lが0.5以下の場合、外側の六角形の大きさ(上図のE’の位置)は

 

E’ = Imax + Imin

 

で求まります。

 

 

明度Lが0.5より大きい場合、外側の六角形の大きさ(上図のE’の位置)は

 

E’ = 2 – Imax – Imin

 

となります。

 

 

以上のことから、最初の彩度Sの式が求まります。

 

色相、彩度、明度を使った色判別時の注意点

色相および彩度を用いると、画像の明るさ(明度)が変動しても似た色の領域を抽出する事が可能となりますが、彩度の値が小さい場合、つまりR、G、Bの値がそれぞれ近い場合は色相の値が不安定になります。

 

例えば、
(R、G、B) = (121、120、120)の場合、 色相H = 0°
(R、G、B) = (120、121、120)の場合、 色相H = 120°
(R、G、B) = (120、120、121)の場合、 色相H = 240°

 

と、ほんの少しのR、G、Bの値の違いでも色相の値は大きく異なります。

 

また、色相Hは角度で表されるので、例えば1°も359°も値こそ離れていますが、どちらも0°±1°の範囲内で角度的には近いので、色相Hの値で単純に二値化処理することで色の領域を抽出する場合は注意して下さい。

 

画像処理アルゴリズムへ戻る

 

色相、彩度、明度の公式

カラーの画像処理をする時には、これら色相などの知識は必須となります。
Windows標準で付いてくるペイントで、色の作成の表示をすると、雰囲気が分かると思います。

 

 

基本的に以下の色相、彩度、明度を用いて色を表すのですが、変換式にいくつかの種類があります。

 

色相(Hue)

色合いを表します。
赤や緑、青などに色を0~360°(0~2π)の角度を用いて表します。

彩度(Saturation)

鮮やかさを表します。
と一般的に言われるのですが、鮮やかさ?と言われても、いまいちピンと来ませんが、下記に示した式から見ても分かるように、R,G,Bの値にどれだけ開きがあるか?を示しています。
このことは逆にいうと、R,G,Bの値に開きが無い場合は、グレーに近い事から、彩度は如何にグレーっぽく無いか?、という事から、どれだけ純色(赤、緑、青、黄、シアン、紫など)に近いか?を表しています。

明度(Brightness,Lightness,Intensity,Value)

色の明るさを表します。

 

HSV変換

6角錐モデルとも言います。

 

【RGB⇒HSV変換】

Imax = Max(R,G,B)
Imin = Min(R,G,B)
とすると

 

R = Imaxのとき

H = 60×(G – B) / (Imax – Imin)

G = Imaxのとき

H = 60×(B – R) / (Imax – Imin) + 120

B = Imaxのとき

H = 60×(R – G) / (Imax – Imin) + 240


S = (Imax – Imin) / Imax


V = Imax


【HSV⇒RGB変換】

h = floor(H / 60)     floor()は切り捨て処理
P = V × (1 – S)
Q = V × (1 – S × (H / 60 – h))
T = V × (1 – S × (1 – H / 60 + h))
とすると

 

h= 0のとき

R = V, G = T, B = P

h= 1のとき

R = Q, G = V, B = P

h= 2のとき

R = P, G = V, B = T

h= 3のとき

R = P, G = Q, B = V

h= 4のとき

R = T, G = P, B = V

h= 5のとき

R = V, G = P, B = Q


HLS変換

双6角錐モデルとも言います。

 

【RGB⇒HLS変換】

Imax = Max(R,G,B)
Imin = Min(R,G,B)
とすると

 

R = Imaxのとき

H = 60×(G – B) / (Imax – Imin)

G = Imaxのとき

H = 60×(B – R) / (Imax – Imin) + 120

R = Imaxのとき

H = 60×(R – G) / (Imax – Imin) + 240


L = (Imax + Imin) / 2

L ≦ 0.5のとき

S = (Imax – Imin) / (Imax + Imin)

L > 0.5のとき

S = (Imax – Imin) / (2 – Imax – Imin)


【HLS⇒RGB変換】

h < 0のとき

h’ = h  + 360

h ≧ 360のとき

h’ = h  – 360

その他

h’ = h

L ≦ 0.5のとき

M2 = L × (1 + S)

L > 0.5のとき

M2 = L + S – L × S


M1 = 2 × L – M2


h’ < 60のとき

X = M1 + (M2 – M1) × h’ / 60

60 ≦ h’ < 180のとき

X = M2

180 ≦ h’ < 240のとき

X = M1 + (M2 – M1) × (240 – h’ ) / 60

240 ≦ h’ ≦ 360のとき

X = M1

 

とすると

 

R = X ただし、h = H + 120とする

G = X ただし、h = Hとする

B = X ただし、h = H – 120とする

 

カラー変換用関数

【Win32APIの場合】 VBの表記例
‘HLS変換(Windows 2000以降、またはInternet Explorer 5.0がインストールされてある環境。(SHLWAPI.DLL Version 5.00以上)
‘h (色相)
‘赤(0)、黄(40)、緑(80)、シアン(120)、青(160)、マゼンダ(200)の順に定義0~239まで設定可
‘L (明度)
‘色の明るさをあらわす。0~240まで設定可。0が黒、240が白になる。
‘s (彩度)
‘0~240まで設定可。240が純色になる。
Public Declare Sub ColorRGBToHLS Lib “SHLWAPI.DLL” _

(ByVal clrRGB As Long, _
pwHue As Integer, _
pwLuminance As Integer, _
pwSaturation As Integer)

Public Declare Function ColorHLSToRGB Lib “SHLWAPI.DLL” _

(ByVal wHue As Integer, _
ByVal wLuminance As Integer, _
ByVal wSaturation As Integer) As Long

 

最初に紹介したペイントの色の作成では、この関数と同様の変換(設定値を含めて同じ)をしています。

 

【.NET Frameworkの場合】
System.Drawing.Color構造体にて

GetHueメソッド      HSBのH(色相)を取得
GetSaturationメソッド   HSBのS(彩度)を取得
GetBrightnessメソッド   HSBのB(明度)を取得

RGB⇒HSB変換はなし?

 

【OpenCVの場合】
cvCvtColor関数にて、以下の変換に対応
XYZ, YCrCb(YCC), HSV, HLS, L*a*b, L*u*v
その他 同じcvCvtColor関数で Bayer変換に対応

 

カラー画像処理例

そのカラー画像を色相、彩度、明度に分解し、それぞれの値(主に色相)でフィルタリング処理(バンドパスフィルタ)を行い、カラー画像に逆変換する事により、特定の色だけを抽出する事が可能になります。これにより、色の位置や個数などの検査をする事が可能となります。

処理前 処理後

ただし、彩度の値の小さな色(白やグレーに近い色)は彩度の値が不安的になりがちなので、カラー画像処理には不向きです。

 

画像処理アルゴリズムへ戻る