重心の計算方法

重心とは、重さの中心で、重心の位置で、力がつり合います。

 

重心の計算方法は、言葉で表すと

$$重心=\frac{(重さ\times位置)の合計}{重さの合計}$$

となります。

 

具体的な計算例を示すと、

のデータに関して、重心を計算すると、

$$重心=\frac{2\times0+5\times1+13\times2+15\times3+5\times4}{2+5+13+15+5}
=2.4$$

 

となります。

 

さらに二次元的な座標においても、各座標軸に関して、それぞれ計算を行います。

こちらも具体的に、以下のようなデータの場合、

$$重心のx座標=\frac{3\times0+10\times1+7\times2+5\times0+20\times1+7\times2+2\times0+9\times1+3\times2}{3+10+7+5+20+7+2+9+3}$$

$$= 1.1$$

$$重心のy座標=\frac{3\times0+5\times1+2\times2+10\times0+20\times1+9\times2+7\times0+7\times1+3\times2}{3+5+2+10+20+9+7+7+3}$$

$$= 0.9$$

となります。(分母の重さの合計は、計算の順番が分かりやすいように、順番を入れ替えています。)

 

画像処理において重心を計算する場合は、重さの値に画像の輝度値を用いますが、二値化した画像に対して重心の計算を行い、重さを考慮しない場合もありますが、この場合は、重心の座標は、しきい値以上となる画素の座標の平均と一致します。

ハイパースペクトルカメラとは?その原理は?

ハイパースペクトルカメラとは?

ハイパースペクトルカメラとは、1回の撮影で多くの波長(例えば100波長分など)ごとの画像を撮影できるカメラとなります。

多くの波長の画像を取得できると何がいいか?というと、撮影する被写体によって、特定の波長で暗くみえたりするのですが、この特定波長というのが、材料や状態(水分を多く含むなど)によって異なるため、材料の分類やキズの検出が可能になります。

具体的には食品の中に含まれる異物の検出や、農作物の打痕、リサイクル材料の分類など、一般的なカメラで撮影した画像だけでは困難な検査も可能になります。

ただ、実際には複数の分類が必要でない場合には、検査したい被写体がどのような波長特性を持つのか?を解析的に撮影し、実際の検査では、特徴的な波長だけで撮影するようにバンドパスフィルタを使って、一般的なカメラで撮影する場合もあります。

 

ハイパースペクトルカメラで撮影した画像

下の写真は、ポリスチレン、ポリプロピレン、アクリル、生米、ナイロンを一般的なカラーカメラで撮影した画像になりますが、この画像を通常の画像処理で分類しようとすると、ほぼ白いか、透明なので、これを分類するのは、意外と難しかったりもします。

 

この被写体を実際にハイパースペクトルカメラで撮影し、各波長ごとの画像を並べた物が以下の動画になります。

ここでの注目ポイントとしては波長を大きくしていくと、特定の波長で暗くなり、さらに波長を大きくすると、元の明るさに戻ったりしています。

この特定の波長というのが、材質により異なっています。

上の動画で、各材料ごとの輝度変化を横軸に波長、縦軸に輝度値をプロットした物が以下のグラフになります。

このグラフを見ると、例えばポリスチレンの1150nm付近が輝度値が落ち込んでいるのは、他の材料と比べて特徴的です。

他にもポリプロピレンでは1540nm付近で明るくなっています。

さらに、各波長のピンポイントで見るのではなく、波長による輝度変化全体を捉えると、グラフの線の形状が材質により異なるので、材質の分類が可能になります。

 

実際の撮影風景と、分類の処理を行った様子がこちら↓

 

ハイパースペクトルカメラの原理、仕組み

一般的なカメラでも、エリアセンサ、ラインセンサがあるように、ハイパースペクトルカメラでも、エリアセンサのように撮影するタイプや、ラインセンサのように被写体を動かして撮影する必要のあるラインスキャン方式があり、さらに、光を分光する回折格子にも、反射型や透過型があるのですが、ここでは、ラインスキャン方式で、透過の回折格子を使うハイパースペクトルカメラの仕組みを紹介します。

まず最初に一般的なラインセンサカメラでは、どのように撮影しているかというと、被写体の像をレンズを介してラインセンサ上に結像させます。

この状態で、被写体を移動しながら連続的に撮影することで被写体全体の画像を取得しています。

では、ハイパースペクトルカメラでは、どのように撮影しているか?というと、上図のラインセンサの位置にエアスリット(細長い穴が開いたもの)を配置し、スリットを通り抜けた光をレンズで平行光にします。

その平行光を回折格子(グレーティング)に斜めに入射するように配置すると、回折格子から出た光は波長ごとに異なる角度で回折します。

この回折した光をレンズを介してエリアセンサ上に結像させます。

すると、エリアセンサ上では、縦方向に同じ位置の波長の異なる光の成分が結像した状態になります。

この状態で、通常のラインセンサと同じように、被写体を移動しながら撮影し、横1ラインごと(波長の異なるラインごと)に画像を並び替えると、1回のスキャンで複数波長で撮影した画像を同時に得ることができます。

実際の撮影に関して

ハイパースペクトルカメラを用いると、被写体の材質や状態によって、特定波長において特徴的な変化をする場合があると言いましたが、実際に撮影したい被写体において、そのような変化をするものか?というのは、実際に撮影してみないと分からない部分が多くあります。

具体的に撮影ワークを検討している方は、私の会社の営業までお問い合わせください。

下記、ページより電話か、製品に関してのお問い合わせフォームよりお願いします。

経験豊富な営業が対応してくれると思います。

被写体の撮影評価を行うことも可能です。

https://www.avaldata.co.jp/contact

 

関連製品

ハイパースペクトルカメラ AHS-003VIR (450nm~1700nm)

ハイパースペクトルカメラ AHS-U20MIR (1300nm~2150nm)

Snap、Grabとは?リングバッファとは?

工業用のカメラを用いた画像の撮影方法に SnapGrab という言葉があります。

簡単に言ってしまえば、Snap静止画撮影で、Grab動画撮影となります。

SnapとGrabの厳密な定義は、各種画像入力ボードのメーカーやカメラメーカーにより異なってくるかとは思いますが、簡単に説明したいと思います。

Snap

Snapでは画像の取込を開始してから、実際に画像の撮影(画像データのメモリの転送)を行い、画像の取込を停止します。

この一連の処理をSnapと言います。

ただし、Snapでもスマホのように連射をすることはできますが、画像取込と画像取込の間に画像の取込開始/停止の処理が入っているため最速のフレームレートを出せない事に注意してください。

Snapでのメリットは、次の画像取込を行うまで、撮影した画像データが上書きされる事がないので、プログラム的に簡単になります。

Grab

Snapでは画像の取込開始/停止を繰り返していましたが、Grabでは画像の取込を開始し、次に画像の取込を停止するまで画像の取込を繰り返し行います。

画像取込と画像取込の間に余計な処理が入らないため、動画のように連続的に画像を取り込む場合は、Grabで撮影を行います。

Grabの場合、動画の撮影中に撮影した画像データに対して画像処理などを行う事が多いのですが、この処理はSnapと比べて、より複雑です。

実際の画像取込は、カメラのセンサが露光時間分露光し、撮影された画像データがPCのメモリへ配置されるまでの処理となります。

そのため、撮影された画像データへアクセスするには、画像データがメモリへの配置が完了するのを待ってから、画像データをコピーするなり、直接画像処理をする必要があります。

さらには、ある程度の時間、Grabで撮影する場合、すべての画像データをメモリ格納しておく事は、メモリ容量的に無理な場合が多いので、一般的にはリングバッファ(循環バッファ)と呼ばれるメモリ形式で画像データを上書きしながらメモリに格納します。

リングバッファ

リングバッファとは、有限数のメモリ領域を上書きしながら、メモリへデータを格納する方法です。

画像データの場合は、例えば

1枚目の画像データを画像メモリ[0]へ格納
2枚目の画像データを画像メモリ[1]へ格納
3枚目の画像データを画像メモリ[2]へ格納
4枚目の画像データを画像メモリ[3]へ格納
5枚目の画像データを画像メモリ[0]へ格納 ← これ以降、メモリの上書きが発生している
6枚目の画像データを画像メモリ[1]へ格納
        :

のようにメモリを上書きしながら画像データを格納していきます。

このリングバッファで良い事は、画像を撮影しながら画像処理などを行った場合、1枚1枚の画像処理時間は、通常、バラついてしまうため、画像処理時間が、画像が格納されてから、次の画像が格納されるまでの時間を時々超えてしまう場合でも、リングバッファの面数(上図の例では4面)が多いと画像処理中に、次の画像データに上書きされにくくなります。

まとめ

画像の撮影方法にはSnapとGrabという撮影方法があります。

それぞれの特徴は以下の通りです。

長所 短所
Snap プログラムが簡単 高速フレームレートで撮影できない
Grab 高速フレームレートで撮影できる プログラムが複雑になる

 

ハフ変換

ハフ変換そのものは座標の変換処理なのですが、画像処理では、ハフ変換を用いて画像中の直線部分を抽出するのに用いられます。

ハフ変換と言うだけで、あんに直線検出を指している事が多くあります。

また、ハフ変換を拡張して、円の検出に用いられる場合もあります。

ハフ変換で出来ること

画像の中から、直線が途切れていても、直線らしき部分を抽出したり、前処理でエッジ抽出を行い、輪郭部分を検出する事もできます。

(元画像)

(直線検出)

(元画像)

(輪郭検出)

直線検出のしくみ

まず初めに直線として検出したい場所を二値化して抽出します。

被写体の輪郭を検出したい場合は、SobelCannyなどの前処理を行います。

二値化された座標(XY座標)に関して、X座標をいくつかに分割し、Y軸方向に二値化された座標をカウントします。

このカウントを点を原点に基点に回転させながら、繰り返しカウントを行います。

すると、点が直線的に並んだ時にカウント数が最大となります。

直線なので、逆向き(回転角度が180度反対)の時もカウント数が最大となります。

このカウント数を横軸を回転角度、縦軸をX座標にして、二次元的に表示すると、下図のようになり、カウント値がピークとなるXとθの値から、直線を検出することができます。

ハフ変換のアルゴリズム

点を回転して特定方向に積算することで、直線を見つける事もできるのですが、ハフ変換では、各点を通る直線を回転させ、直線が重なりあう場所をみつける事で、直線を検出します。

点(x, y)を通る線を、下図のようにρθで表すと

$$\rho=x cos\theta+y sin\theta$$

となります。

これは、(x, y)座標が決まっていて、θを与えると、ρが計算できる事になります。

点(x,y)を通る直線をθを0~360°の範囲で刻むと下図のようになります。

この直線をρとθで表すと、下図のようにsinカーブとなります。

 

この処理を各点に関して行うと、点が直線的に並んでいる部分では特定のρとθに集中します。

このρとθの値が集中している点を抽出し、ρとθの値から直線を検出します。

実際のハフ変換

ハフ変換の角度は0~360°で計算すると、必ず180°離れた2か所でρとθが集中するので、0~180°までを計算します。

実際のハフ変換では、エッジ上のxy座標から、θの値を例えば1°おきに0~180°までに対応したρの値を計算し、ρの値の分解能を例えば1などに落として、ρーθの座標系へ投票し、投票した値のカウント数が高い部分が直線となる部分のρ、θとなります。

OpenCV(Python)のサンプルプログラム

import cv2
import math
import numpy as np

# 画像読込
src = cv2.imread('keyboard.jpg', cv2.IMREAD_GRAYSCALE);
# 二値化
_, src = cv2.threshold(src, 200, 255, cv2.THRESH_BINARY)

cv2.imshow("edge image", src)

# ハフ変換
lines = cv2.HoughLines(src, 3, np.pi / 180, 400)

# 結果表示用の画像を作成
dst = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR);

# 直線を描画
line_length = 1000
for line in lines:
    rho = line[0][0]
    theta = line[0][1]
    a = math.cos(theta)
    b = math.sin(theta)
    x0 = a * rho
    y0 = b * rho
    cv2.line(
        dst, 
        (int(x0 - line_length * b), int(y0 + line_length * a)), 
        (int(x0 + line_length * b), int(y0 - line_length * a)), 
        (0, 0, 255), thickness=2, lineType=cv2.LINE_4 )

cv2.imshow("result", dst)

cv2.waitKey()

(処理前の画像)

(処理後画像)

注意事項

ハフ変換を行うと、直線らしい部分が抽出できますが、この直線の位置の精度を高めようと、ハフ変換時のθとρの分解能を高め過ぎると、直線検出の安定性が悪くなります。

そのため、直線の位置精度を高めるには、ハフ変換で直線付近の座標を抽出し、その座標から回帰直線などを求めるようにします。

画像入力ボードとは?設定の勘所、CC信号とは?

画像入力ボードは、主に工業用のカメラを用いる時に、PCのスロットに刺して用いられます。
他にもフレームグラバ(frame grabber)やキャプチャボードと言ったりもしますが、キャプチャボードと言うと、民生品のビデオキャプチャボードを指す場合が多いので、私は画像入力ボードと言うようにしています。

画像入力ボードでは、一般的なWebカメラなどとは違って、様々な設定が出来る分だけ、ハマりやすいポイントもあるので、そのへんの勘所をまとめてみたいと思います。

 

まずは画像入力ボードを使った一般的なシステムを以下に示します。

画像入力ボードへは、移動する被写体の動きに合わせて撮影できるように、光電センサなどのトリガセンサの信号を入力したり、ベルトコンベアなどのような搬送系を用いる場合は、搬送速度のムラにも対応するためにエンコーダを接続します。

このトリガ信号やエンコーダ信号を用いて、画像入力ボードは同期信号を生成し、カメラへ送ります。
この同期信号では、カメラで撮影する画像の各フレーム1枚1枚の撮影タイミング(ラインセンサの場合は、各ラインの撮影タイミング)や露光時間を制御します。

工業用のカメラでは、この同期信号に連動して撮影できる事が大きな特徴ですが、この同期信号の事をCameraLinkというカメラの接続規格では Camera Control信号(略:CC信号)といいます。

さらに、カメラで撮影された画像データは一般的な画像データのように画像の左上から整然と輝度データは出力されない場合もあるので、画像入力ボードで画像の輝度データを整列し、PCのメモリへ格納します。

一般的なWebカメラと工業用カメラとの違い

一般的なWebカメラでは以下のような以下のような構成になります。

上図のように、一般的なWebカメラでは同期信号の入力がありません。

このことは、例えば30fpsのカメラでは、1/30秒ごとに画像の撮影しています。
この状態で移動する被写体を撮影すると、1/30秒ごとに被写体が画像の中心にあるとは限らないため、被写体の撮影位置がバラバラな状態になってしまいます。

(撮影画像)

これは、たとえIOボードを用いてトリガセンサを繋いだとしても、同期信号が無いと、各フレームの撮影タイミングは制御できないため、撮影位置がバラバラになってしまいます。

さらに画像データは圧縮されてUSBを介してPCへ転送され、CPUで画像データをデコードし、画像データをPCのメモリへ配置される場合もあるため、CPUに負荷がかかります。

また、データ圧縮は非可逆となる場合も多く、細かい欠陥を検査するような場合の用途では不向きです。

カメラの設定とボードの設定がある

画像入力ボードを使ってカメラの画像を撮影するには、カメラとボードの設定を、それぞれ行う必要があります。主な設定値には以下のようなものがあります。

カメラの設定 ボードの設定
画像の幅
画像の高さ
同期モード(内部、外部)
フレームレート(スキャンレート)
露光時間
ゲイン
オフセット
画像の幅
画像の高さ
同期信号出力の有効/無効
フレームレート(スキャンレート)
露光時間
トリガの有効/無効
エンコーダの設定

上記のように、似た設定がカメラとボードの両方にあるので、最初は混乱しやすいのですが、ちゃんと把握しておく必要があります。

画像の幅、高さ

カメラの画像の幅と高さの設定は、カメラから画像入力ボードへ転送される画像のサイズで、画像入力ボードの幅と高さは、カメラから送られてきた画像から部分的に切り取るサイズとなります。

ラインセンサカメラの場合、カメラから出力される画像の高さは1となるため、ボードの設定の高さは何ライン分の画像データを1画面分の画像データとするか?の設定となります。

同期モード、同期信号出力設定

カメラの同期モードの設定は、各フレームの撮影タイミング、露光時間をカメラ自身のタイミングで撮影する設定(フリーラン、自走モード)と、画像入力ボードから送られてきた同期信号に基づいて撮影する設定とがあります。前者の設定を内部同期フリーラン、自走モードなどと言い、後者の設定を外部同期ランダムシャッタなどを言います。

ボードの同期信号出力の設定は、画像入力ボードからカメラへ同期信号を送るか?送らないか?の設定になりますが、ボードから同期信号を出力していても、その同期信号を使う/使わないの設定はカメラの設定となるため、通常、同期信号は出力する設定にしておきます。

フレームレート、露光時間

カメラのフレームレートと露光時間の設定は、カメラがフリーラン(自走モード)の時に、カメラに設定されたフレームレートと露光時間で動作し、カメラが外部同期の場合は、ボードに設定されたフレームレートと露光時間で動作します。

ゲイン、オフセット

ゲイン、オフセットの設定は、カメラのセンサに対して行う設定となるため、カメラ特有の設定となります。

トリガの有効/無効設定

トリガという言葉は、カメラへ送られる同期信号の事をトリガという場合もあるので、ややこしいのですが、撮影開始タイミングをフォトセンサなどを通過したタイミングで撮影する場合は、トリガの設定を有効にします。ただし、トリガを有効にする場合は、各フレームの撮影タイミングをトリガのタイミングに合わせる必要があるので、カメラの同期モードを外部同期モードにする必要がります。

エンコーダの設定

エンコーダ信号に同期して撮影する場合は、撮影開始のタイミングをエンコーダの何パルス後に撮影するか?の設定や、エンコーダ何パルスごとに撮影するか?の設定があります。

同期信号(CC信号)のしくみ

画像入力ボードから、カメラへ送られる同期信号のお話です。

同期信号は下図のような矩形波(パルス信号)がカメラへ送られます。

この矩形波をカメラが受けて、カメラがどうのような挙動をするか?は、カメラの機能やカメラの設定次第な部分もありますが、代表的な例としては、上図のように、同期信号の立ち上がり部分でカメラの露光を開始し、信号のHigh期間分、露光し、信号が立ち下がると画像データをPCへ転送します。あとは、この繰り返しです。

大事なのは、このCC信号により、カメラの各フレームの撮影タイミングと露光時間を制御できるという事です。
※カメラによってはHighとLowが逆の場合もあります。

同期信号(CC信号)の生成(画像入力ボードの動作、設定)

画像入力ボードではトリガセンサの信号やエンコーダ信号を受けて同期信号(CC信号)を生成しますが、トリガセンサを使う/使わない、エンコーダを使う/使わない設定により、いくつかのパターンがあります。

トリガ、エンコーダを使わない場合

画像入力ボードに同期信号の周期(フレームレート、スキャンレート)とHigh期間の時間(露光時間)を設定し、定期的にCC信号を出力します。

 

 

フレームレートと露光時間を画像入力ボード側で制御が可能となります。

ただし、実際にカメラで撮影されるフレームレートと露光時間はカメラの設定次第となります。

トリガを使用し、エンコーダを使用しない場合

トリガ信号を有効にし、エンコーダを無効にする撮影は、ベルトコンベアのようなライン上を流れてくる被写体をエリアセンサで撮影する場合に、よく用いられます。

トリガ信号が画像入力ボードに入力されたら、CC信号を1パルス分出力します。
設定によりトリガ1パルスにつき、何パルスか出力する設定する事も可能です。

また、トリガ信号の立下りから、実際にCC信号が出力されるまでの時間を調整する事も可能です。

トリガ、エンコーダを使用する場合

ラインセンサの場合は、エンコーダ信号と同期させる場合が多くあります。

下図のように、トリガ信号が入力されたら、指定パルス数分遅らせてから最初のCC信号を出力します。
次のCC信号は、指定パルス数分のエンコーダパルスごとにCC信号を出力します。

下図の例では、トリガ信号入力後、8パルス後にCC信号を出力し、以降は4パルスおきにCC信号を出力する例です。

ただし、エンコーダ信号はA相、B相の両方をカウントして、エンコーダの呼称パルス数の2倍でカウントする2逓倍と呼ばれるカウント方法やA相、B相の立ち上がり、立下りをカウントし、4倍でカウントする4逓倍のカウント方法があります。

CC信号による同期撮影(カメラの動作、設定)

前項目の同期信号の生成では、画像入力ボードがどのような同期信号を生成するか?の話であって、実際にカメラがどうように同期信号に基づいて撮影をするか?はカメラ側の設定次第となります。

同期信号(CC信号)を使用しない場合

カメラに設定したフレームレートと露光時間に基づいて生成した信号に同期してセンサを露光します。

この設定を内部同期 フリーランと呼びます。

通常、カメラの初期値では、このフリーラン状態設定されています。

同期信号(CC信号)を使用する場合

カメラの外部(画像入力ボード)で生成された同期に同期してセンサを露光します。

この設定を外部同期 などと言います。

この設定を使用するには、カメラの設定をしないといけないのですが、「外部同期」という言葉はカメラメーカーによって、まちまちなため、最初は戸惑うと思います。(私も毎回戸惑ってます。。)

この外部同期で撮影しているつもりで、画像入力ボードの露光周期(フレームレート、スキャンレート)と露光時間を変更しても撮影した画像の明るさやフレームレートが変化しないな?と思ったら、まずは、カメラが外部同期の設定になっているかどうかを確かめて下さい。

様々な同期撮影モード

画像入力ボードは同期信号を生成してカメラへ入力しますが、その同期信号に基づいて、どのような露光時間で撮影するか?はカメラによっては、いくつかのモードがある場合があります。(モードが無い場合もあります。)

最初の方で説明したように、露光時間とフレームレート(スキャンレート)の設定は、カメラとボードのそれぞれに存在します。

この露光時間とフレームの設定を、どちらの設定を使うか?は、カメラ側の設定(露光モードなどと言われる)で決まります。

同期信号(CC信号)のHight期間分だけ露光するモード

比較的一般的な撮影モードです。

CC信号の立ち上がりから露光を開始し、CC信号がHigh期間分だけ露光をします。

カメラに設定された露光時間で露光するモード

ラインセンサカメラで比較的採用されているモードです。

CC信号の立ち上がりから露光を開始しますが、露光時間そのものは、カメラに設定された露光時間で露光します。

次の露光開始まで、可能な限りの最大露光時間で露光するモード

CC信号の立ち上がりから次の立ち上がりまでの間で可能な限りの露光時間で露光するモードです。

この事は、エンコーダと同期して撮影している場合、被写体の移動速度が変化すると、露光時間も変化してしまうので、使いづらいモードではあるのですが、TDIセンサでは、このモードになっている場合が多くあります。

 

ポイント!
カメラの最速フレームレート以上の周期でCC信号をカメラへ入力してはいけない

例えば、カメラの最速フレームレートが30fpsのカメラに1秒あたり50パルス(50fps相当)のCC信号をカメラへ入力してはいけません。

実際に必要以上にCC信号を入力してしまった場合、カメラが壊れる事はない?と思いますが、どのような挙動になるか?は使用するカメラによって異なるのですが、比較的多いパターンとしては

  • 必要以上のCC信号のパルスが無視される。
    →結果として、フレームレート、スキャンレートが想定以上に遅くなります。
    ラインセンサカメラの場合、縦が縮んだ画像になります。
  • 撮影した画像の一部が前のフレームの画像と混ざった画像になる。
  • カメラが反応しなくなる。

など。。

この状態は、エンコーダと同期して撮影する際に陥る事がよくあります。

何かおかしい!と思った場合は、搬送速度を遅くする、CC信号の出力周期を遅くなるように設定するなどしてください。このように遅くしていくと、途中から正規のCC信号になった瞬間、フレームレートがカメラの最速の状態で撮影が出来るので、確認ができると思います。

ポイント!
カメラの露光時間以下の周期でCC信号を生成しようとしてはいけない

露光時間より短い間隔で撮影する事ができないのは、当たり前のように思われるかもしれませんが、エンコーダと同期して撮影すると陥りやすい状態です。

この状態になると、前項と同じような症状になるので、まずは搬送速度を遅くする、CC信号の出力周期を遅くするように試してみてください。

ポイント!
エンコーダと同期撮影では、ほぼ最速のフレームレート(スキャンレート)は出せない

これは何故??と思われるかもしれませんが、そもそも、なぜエンコーダと同期させて撮影しようとしているかというと、搬送速度がバラついても歪みの無い画像を撮影するためであって、エンコーダ信号にもバラつきがあります。

このような状態で、CC信号の周期が速くなるような設定を行うと、ところどころでカメラの最速フレームレート(スキャンレート)を超えてしまいます。

それでも、搬送速度にバラつきが無いので、最速で撮影したい!と言われる場合があるのですが、その時はエンコーダとの同期をしない(フリーランで撮影する)と、カメラの最速が狙えます。

まとめ

露光時間とフレームレートの設定の概念は、画像入力ボード側とカメラ側の両方(別々)にあります。

自分が内部同期で撮影したいのか?外部同期で撮影したいのか?明確に意識して両方の設定をしてください。

また、特にエンコーダと同期して撮影する場合には、カメラの最速フレームレート、スキャンレートを超えないように注意してください。

何かおかしいな?と思ったときは、まずはフレームレートを遅くするように、搬送速度を遅くする(エンコーダの周波数を下げる)、スキャンレートを遅くするなど、してみてください。
ボード側の設定を変えてもフレートレート(スキャンレート)に変化が無い場合は、カメラの設定が内部同期になっている可能性が高いですし、フレートレート(スキャンレート)を遅くする事で、実際にカメラで撮影したフレートレート(スキャンレート)が速くなる場合は、カメラの最速のフレートレート(スキャンレート)以上の設定をしていた可能性が高いです。

参考

https://faq-avaldata.dga.jp/faq_list.html?category=4

https://www.avaldata.co.jp/products/imaging/category/imageInputBoard

ELP ソニー800万画素センサ搭載の激安USBカメラ購入

ELPというメーカーからソニーの800万画素センサを搭載し、CSマウントレンズ付きでケース付きの筐体でありながら、アマゾンで¥9,145という激安カメラがあり、気になって買ってみました。

8MP USBカメラ Webcam Linux windows video camera Webカメラ800万画素 Sony IMX179 sensor ウェブカメラ (2.8-12mm 可変焦点レンズ)

 

 

なぜか?コンクリートに固定用のネジが付いています。

三脚ねじ用の固定プレートも付いています。

CSマウントレンズもちゃんと取り外せます。

USBケーブルは本体から地下出しです。中継コネクタも見たことない。。

 

この構成で¥9,145って、どうしたら、この値段にできるんだろうか???

 

気になるのは画質ですが、少し古いのですが、LogicoolのC910というUSBカメラと撮影した画像を比較してみました。

 

Logicoolのカメラ(左側)と、ELPのカメラ(右側)を置いてキーボードを撮影しました。

ELPのカメラは最大3264×2448画素で撮影できるのですが、Logicoolのカメラが2592×1944画素までだったので、両方とも2592×1944画素で撮影しました。

ELP Logicool

 

こうして比べてみると、ELPのカメラは発色もいいし、くっきりしているので、すごく良く見えるのですが、ブロックノイズのような、変なノイズが目立つ事が多かったです。

 

ノイズの多い画像↓(画像をクリックして拡大して見てみてください)

上の画像の一部拡大↓

ただ、OpenCV等でこのカメラを使う事前提であれば、撮影した画像にメディアンフィルタをかけると、そこそこ良い感じの絵になってくれます。

メディアンフィルタを掛けた画像↓

 

カラー画像の比較(WD=300mmぐらいで撮影)

ELP Logicool

 

ということで、くっきりとは撮影できますが、ノイズが少し多めのこのカメラ。

自信をもって勧める事ができるか?!と言われると微妙なところですが、なにせ安いので、とりあえず買ってみるのもアリな感じのカメラでした。

 

(2020.3.31追記)

OpenCVで 3264 x 2448 画素 で撮影した画像がこちらです。

C#から使える画像処理ライブラリ

画像処理のプログラムでは、当然ながら画像の表示や、操作するボタンなどが欲しくなるので、GUIのプログラム作成が簡単なC#が割とよく用いられています。

しかし、画像処理そのものをC#でやるには処理速度に不満もあるので、GUIはC#、画像処理部はC言語で処理が書かれた画像処理ライブラリを用いる事となります。

 

そこで、C#から使える画像処理ライブラリにはどんなものがあるのか?紹介したいと思います。

 

個人で使うなら

ほぼ、OpenCvSharpで決まりだと思います。

USBカメラも使えるし、バージョンアップもされているし、作者は日本人なので。。

OpenCVをラップしているので、画像処理時間も普通にプログラムを組むよりは圧倒的に速いかと思います。

 

インストール方法については、GitHubに少し書かれていますが、NuGetからインストールするのが基本のよう。

詳細は「OpenCvSharp インストール」で検索してみて、新しめの記事を参照して頂ければわかると思います。

 

マニュアル

https://shimat.github.io/opencvsharp_docs/index.html

GitHub

https://github.com/shimat/opencvsharp

 

会社で使うなら

「会社で使う」というか、使用するカメラが工業用のカメラを使うなら、以下の2つの画像処理ライブラリが、よく使われているように感じます。

 

●Cognex Vision Pro

●MVTec HALCON

 

両方とも数十万円するので、個人で買えるようなレベルではありませんが、OpenCVと何か違うか?というと、私が思うにはテンプレートマッチングの性能と工業用のカメラに対応している部分だと思います。

 

テンプレートマッチングについては、OpenCVのテンプレートマッチングでは回転やスケール変動には対応していませんが、これらのライブラリは対応しています。

さらには、袋の表面に印刷された画像のように、画像が歪んだ状態でもマッチングしてくれる機能もあります。OpenCVにも特徴点ベースのマッチングはありますが、やっぱりこっちの方が良いかと思います。

 

工業用のカメラを使うと何がいいか?という部分についてですが、カメラの画素数やフレームレートなどもそうですが、一番大きいのは同期撮影が出来る点だと思います。

例えば、ベルトコンベア上を流れる製品を撮影するような場面では、被写体は毎回画像の中央で撮影したくなりますが、カメラのフレーム単位で撮影タイミングを制御できないと、毎回撮影位置がばらついてしまいます。

 

OpenCVからは工業用のカメラを制御することは、ほとんどの場合、出来ないのですが、カメラ専用のSDK(もしくは画像入力ボードのSDK)を用いて画像を撮影し、撮影したデータをOpenCVに渡して画像処理を行う事も可能なので、やっぱり、一番差が大きいのはテンプレートマッチングの性能でしょうかね。

 

ちなみに、マシンビジョン業界でPythonが使われる事はほとんどありません。(聞いた事がありません。)

Pythonが出来ない私。。

 

画像処理のためのC#へ戻る

画像の拡大

例えば、下図のように2x2画素の画像を4x4の画像に拡大する場合、アフィン変換を使えばいいんでしょ!と、安易に考えていると、思わぬ落とし穴があったりもします。

大事なポイントとして、

●画像の座標の原点は左上の画素の中心が原点(0.0、0.0)となる。(例外もあります)

●アフィン変換の拡大縮小は原点を基準として拡大縮小される。

 

となります。

これを気にせず、ただ、アフィン変換で画像を2倍に拡大すると、左上の画素の中心を基点に画像が拡大されます。

これで、一見良さそうにも感じるのですが、拡大後の画像において、画素の中心が原点であることから、4x4画素の領域は下図の四角で示した領域であり、画像全体が左上に0.5画素ズレた状態になっていまいます。

 

 

アフィン変換で画像を拡大する時の変換前と変換後の状態は、以下のようになるのが正解です。

 

この変換をアフィン変換で実現するには以下のように行います。

 

変換前の状態

 

①画像全体を右下に(+0.5,+0.5)画素移動
$$\begin{pmatrix} 1 & 0 & 0.5 \\ 0 & 1 & 0.5 \\ 0 & 0 & 1 \end{pmatrix}$$
 

②画像を2倍に拡大

$$\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}$$
 

③画像全体を左上に(-0.5,-0.5)画素移動

$$\begin{pmatrix} 1 & 0 & -0.5 \\ 0 & 1 & -0.5 \\ 0 & 0 & 1 \end{pmatrix}$$

 

となります。

この一連の変換をアフィン変換行列であらわすと

$$\begin{pmatrix} { x }^{ ‘ } \\ { y }^{ ‘ } \\ 1 \end{pmatrix}=\begin{pmatrix} 1 & 0 & -0.5 \\ 0 & 1 & -0.5 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 1 & 0 & 0.5 \\ 0 & 1 & 0.5 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} x \\ y \\ 1 \end{pmatrix}\\ \\ $$

$$\begin{pmatrix} { x }^{ ‘ } \\ { y }^{ ‘ } \\ 1 \end{pmatrix}=\begin{pmatrix} 2 & 0 & 0.5 \\ 0 & 2 & 0.5 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} x \\ y \\ 1 \end{pmatrix}\\ \\ $$

 

となり、単に拡大のアフィン変換行列だけを掛ければOKでは無いことが分かります。

 

ちなみに、C#で2x2画素の画像をPictureBoxのSizeModeプロパティをZoomにして、ImageプロパティにBitmapを設定すると、このようになります。

 

なんとなく、画像が左上にズレているようで、なんか怪しい!!

 

【関連記事】

【C#】画像の座標系

アフィン変換(平行移動、拡大縮小、回転、スキュー行列)

画素の補間(Nearest neighbor,Bilinear,Bicubic)の計算方法

画像の回転

 

画像処理のためのC#へ戻る

Intel RealSense D435を使って腕の血管撮影

腕の血管は近赤外線のカメラで撮影すると見えるそうなのですが、近赤外線のカメラはかなり高価な物が多くてなかなか手が出せません。。

 

血管を見る専用の機材もあるのですが、100万円ぐらいからと、こちらもかなり高額です。

(参考)静脈が見える!「血管可視化装置」の使い勝手は?

https://tech.nikkeibp.co.jp/dm/atcl/feature/15/030200065/071800017/?ST=health

 

しかし、よくよく考えたら、私も以前購入したIntel RealSenseのD435を持っているので、これで血管が撮影できないか?試してみました。

 

ここの資料

CIGS イメージセンサを用いた静脈血管の可視化に関する研究

https://www.ce.nihon-u.ac.jp/researchcenter/biomedical_engineering/pdf/mission2/murayama/h27_2-2.pdf

 

によると、血管をコントラスト良く撮影するには830nmぐらいが良いとのことで、
D435は850nmなので、かなりイケてそう!!

 

ということで、やってみました。

 

やり方はとても簡単。

プロジェクタの前にテープを貼って、近赤外カメラで撮影するだけ。

 

まず、D435のプロジェクタはドットパターンを投影するので、このパターンを消すためにプロジェクタの前にテープを貼りました。

 

使用したのは、光を良く拡散してくれそうな、メンディングテープです。

 

このテープをプロジェクタの部分に貼り付けます。

 

そしてビューアソフトで撮影するだけ。

 

実際に撮影してみた結果がこちら↓

 

血管は見えてはいますが、少しぼんやりとしていたので、画像処理でコントラストを調整したのがこちら↓

 

そこそこ良く見えているとは思いますが、この血管は、点滴や注射を打つときに参考になるかな??

【C#】画像の輝度値の取得

C#で画像ファイルの輝度値を取得するにはLockBits~UnlockBitsでポインタを取得して配列へコピーするなどするのが、C#では定番となっています。

例えば、下記のようなサンプルコード

var bmp = new Bitmap("01.png"); 

// Bitmapをロック 
var bmpData = bmp.LockBits( 
	new Rectangle(0, 0, bmp.Width, bmp.Height), 
	System.Drawing.Imaging.ImageLockMode.ReadWrite, 
	bmp.PixelFormat 
	); 

// メモリの幅のバイト数を取得 
var stride = Math.Abs(bmpData.Stride); 

// 画像データ格納用配列 
var data = new byte[stride * bmpData.Height]; 

// Bitmapデータを配列へコピー 
System.Runtime.InteropServices.Marshal.Copy( 
	bmpData.Scan0, 
	data, 
	0, 
	stride * bmpData.Height 
	);

// アンロック 
bmp.UnlockBits(bmpData);

このプログラムで、ほとんどの場合、問題ない事が多いのですが、モノクロ8Bitのpng画像ファイルを開くと、なぜか?32bitカラーの画像として認識してしまいます。

(評価に用いた画像) Deep Learningでは定番のMNISTの手書き文字に似せて作成した8bitモノクロ画像

(デバッグ画面)もとの画像は8bitモノクロ画像ですが、PixelFormatがFormat32bppArgbになっています。

 

8bitの画像が32bitとして認識してしまうという事は、無駄に画像データが4倍大きくなってしまうので、画像処理的には処理速度的にも不都合が起こります。

 

そこで、私は基本WindowsFormsを使っているのですが、クラスだけWPFのクラスを使う事で問題を解決します。

 

WPFのクラスを用いるにはプロジェクトの参照から

下記の2つを追加します。

PresentationCore
WindowsBase

 

これでWPFのクラスが使えるようになります。
そこで、最初に書いたBitmapクラスを用いたプログラムと同等のことをWPFのクラスを用いて作成すると

byte[] data; 

using (var fs = new System.IO.FileStream("01.png", System.IO.FileMode.Open, System.IO.FileAccess.Read)) 
{ 
	var bitmapFrame = System.Windows.Media.Imaging.BitmapFrame.Create( 
		fs, 
		System.Windows.Media.Imaging.BitmapCreateOptions.PreservePixelFormat, 
		System.Windows.Media.Imaging.BitmapCacheOption.Default 
		); 

	int stride = ((bitmapFrame.PixelWidth * bitmapFrame.Format.BitsPerPixel + 31) / 32) * 4; 

	// 画像データ格納用配列 
	data = new byte[stride * bitmapFrame.PixelHeight]; 
	
	// 輝度データを配列へコピー 
	bitmapFrame.CopyPixels(data, stride, 0); 
}

となります。

これでFormatもGray8となり、正しいサイズで画像データを取得できるようになります。

 

画像処理のためのC#テクニックへ戻る

関連記事

【C#】画像の輝度値の取得設定速度の比較

移動平均フィルタ VS ガウシアンフィルタ

いろいろと検索していたら、2008年の国家試験に以下のような問題があったらしい。


画像が最も平滑化される空間フィルタはどれか。

ただし、数字は重み係数を示す。

(参考)http://www.clg.niigata-u.ac.jp/~lee/jyugyou/img_processing/medical_image_processing_03_press.pdf


 

この問題、

1.ラプラシアンフィルタ

2.3x3の移動平均フィルタ

3.3x3のガウシアンフィルタ

4.5x5の移動平均フィルタ

5.5x5のσが小さめのガウシアンフィルタ

なので、正解は4番だとは思いますが、そもそも平滑化ってなに?

というところに引っかかった。。

 平滑化 = 画像をボヤかす  なら、4番が正解

 平滑化 = ノイズを除去する なら、3番か5番はどうだろう??

 

そもそも「ガウシアンフィルタは中心の画素からの距離に応じてσを小さくすると、平滑化効果が弱まり、σを大きくすると平滑化効果が強くなる」というのが教科書的な説明で、昔の私もそのように書いちゃってますね。。

ガウシアンフィルタの処理アルゴリズムとその効果

 

ただ、ガウシアンフィルタには ローパスフィルタの特性もある というのも大事な特徴だと思います。

 

試しにガウシアンフィルタを画像にかけてみると、

 

オリジナル画像
3×3移動平均フィルタ 3×3ガウシアンフィルタ

 

これだと、差が分かりにくいので、やや意図的なデータではあるのですが、1次元データに対して、1/3, 1/3, 1/3 という移動平均と 1/4, 2/4, 1/4  のガウシアンフィルタとで比べると、

 

オリジナルデータ
移動平均フィルタ
ガウシアンフィルタ

 

となって、ガウシアンフィルタの方がノイズ除去ができています。

上記データはあまりにも意図的なので、いまいち納得できないような部分もあるかと思いますが、連続する3点のデータにおいて、ノイズの成分がどのように加わっているのか?を考えると、理論値からのズレは

+-+

ー+-

++-

ー++

+--

ーー+

のように「+側のノイズが2個、-側のノイズ1個」もしくは「+側のノイズが1個、-側のノイズ2個」となるので、平均すると、+1/3 もしくは -1/3 余ってしまいます。

ガウシアンフィルタでは、少なくとも

+-+

ー+-

のパターンでは、+1/4-2/4+1/4 もしくは ー1/4+2/4ー1/4 となるので、誤差が打ち消しあってくれます。

その他の

++-

ー++

+--

ーー+

パターンでは+1/2 もしくは -1/2 となるので、移動平均よりもダメ!と思ったりもするのですが、この場合は5点以上のガウシアンフィルタを用いると誤差が消えてくれる可能性が高くなります。

 

...と、何が言いたかったかというと、ガウシアンフィルタでは、ローパスフィルタの効果があるため、高周波のノイズには移動平均フィルタよりガウシアンフィルタを用いた方が効果的な場合があります。

私の本職では検査装置などで使われる工業用のカメラを用いる事が多いのですが、工業用のカメラで撮影した画像のノイズと言えば、まずは高周波なノイズなので、ノイズを消したい場合は、移動平均フィルタよりも、まずはガウシアンフィルタを検討するようにしています。

ガウシアンフィルタの方が画像がボケないですし。

 

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

Canny edge detectionの処理アルゴリズム

Canny edge detectionは画像の輪郭部分を抽出するのに、よく用いられるのですが、詳細なアルゴリズムを理解しないまま使われている事も多いのではないでしょうか?(それ、私)

特に、ヒステリシスしきい値の部分などは、詳細な説明も少ないので、今回、まとめてみたいと思います。

 

まずは処理結果から。

 

処理前画像 Canny edge detection処理後

 

大まかな流れとしては

1.ノイズ除去

ガウシアンフィルタなどでノイズを除去します

 

2.輪郭抽出

ソーベルフィルタで輪郭を抽出します

 

3.非極大抑制

エッジの強さが極大となる部分以外を除外します。

詳細は後述

 

4.ヒステリシスしきい値処理

詳細は後述

 

完成!!

 

以上の4ステップで成り立っていますが、非極大抑制とヒステリシスしきい値処理がちょっとわかりづらいので、詳細は以下の通りです。

 

非極大抑制

ソーベルフィルタ後のエッジの強さを3D表示すると、こんな感じ↓になります。

 

この山の尾根のみを抽出するのが、非極大抑制となります。

 

具体的には、まず、ソーベルフィルタでエッジの強さを求めて、エッジの角度を求めます。

横方向

縦方向

エッジの強さ

エッジの角度(実際にはエッジの線に直行する向きが求まります)

 

エッジの向き(エッジの法線方向)が求まったら、

0°(-22.5°~22.5°)

45°(22.5°~47.5°)

90°(47.5°~112.5°)

135°(112.5°~157.5°)

の4つに分類します。

 

エッジの法線方向の3画素のエッジの強さを用いて、中央のエッジの強さが、残す2つの良さよりも大きければ、その部分が極大点ということになり、中央のエッジの強さが最大とならない部分を除外する処理が非極大抑制となります。

エッジの強さ 非極大抑制

 

この処理によりエッジの部分の細線化が行われます。

 

ヒステリシスしきい値処理

ヒステリシスしきい値の処理については、Webで探してもあまりわかりやすいのが無いような気がしますが、以下の通りです。

 

まず、非極大抑制処理で細線化された画像に対して、2つのしきい値を用いて二値化します。

2つのしきい値は、なんとなくエッジっぽい部分(しきい値「小」)と、確実にエッジな部分(しきい値「大」)となるしきい値を設定します。

 

非極大抑制処理画像

 

しきい値「小」 しきい値「大」

 

 

この2つの画像を用いて、しきい値「小」の中から、しきい値「大」につながっている部分のみを残します。

分かりやすいように、しきい値「小」の画像にしきい値「大」のエッジを赤くして重ね合わせて表示すると↓

 

 

この赤い線につながっていない部分を除外します。

 

この処理がまさにCanny edge detectionとなります。

 

(参考)

OpenCV 3.0.0-dev documentation Canny Edge Detection

 

関連記事

【OpenCV-Python】Canny(Canny edge detection)

 

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

カラーカメラはモノクロカメラを兼ねない

「カラーカメラはモノクロカメラを兼ねない」と言って、モノクロ画像が欲しいなら、カラーカメラで画像を撮影して、モノクロ画像に変換すればいいのでは?!

と私が工業用のカメラを扱う業界に属するようになる前はそう思っていました。

 

実際、カラーカメラもモノクロカメラも画素数が同じであるのなら値段も、ほとんど変わりません。

なら、やっぱりカラーの方がお買い得!!

と思ったりもします。

 

監視カメラのように画像を漠然と撮影する用途であれば、確かに、カラーカメラを買っておけばそれで、十分という場面もあるかと思いますが、マシンビジョンの世界では、0.1mmのキズを検査するのに3画素分で撮影して、欠陥を見つける!というように、1画素あたりの撮影分解能が重要な場合が多くあります。

このような場合、色情報が特に必要でない限り、モノクロカメラを用いた方が圧倒的に有利となります。

 

なぜか?

 

それを考える前に液晶TVなどでは、どのようにしてカラー画像を作り出しているのか?というと下の用な画像において

 

四角の部分を拡大したのがこちら↓

 

 

撮影の都合で画像が歪んでしまっておりますが、それは気にしないでもらって、上図のように縦長のR,G,Bの画素が3つずつ並んでおり、光の三原色である赤、緑、青の3色の色のバランスを調整することで、液晶モニタ全体としては、カラーの画像として見ることができのは比較的知られているのではないでしょうか?

 

この、液晶モニタにおいて、もし、モノクロの液晶モニタがあったとしたら、R,G,Bの画素の部分1つ1つがモノクロの画素となるので、横方向に3倍、解像度を上げることができそうだという事は理解して頂けると思います。

 

それでは、カメラ(センサ)のしくみはどのようになっているのか?というと、

カラーエリアCCDセンサのしくみ(単板式、三板式)

 

上記ページでも紹介しておりますが、モノクロのセンサ

 

 

の1画素1画素にR,G,BのBayerパターンと呼ばれる配置↓

 

 

で、光学的フィルタが取付られたものが、カラーセンサとなります。

こんなイメージ↓

 

 

もともと構造的にはモノクロのセンサと同じセンサの上にR,G,Bのフィルタを付けただけなので、RとBの画素数は全体の1/4、Gの画素数は1/2の画素数しかありません。

 

このセンサを使ってカラー画像にするのには、例えば赤の画素の位置では、上下左右に緑の画素があるので、その画素から緑の輝度値を補間し、同様に斜め方向に青の画素があるので、青の輝度値を補間して、不足している輝度値を算出し、それぞれの画素において、R,G,Bの輝度値として、カラー画像を生成します。

 

このようにして、結果として、カラーカメラではモノクロカメラと同じ画素数分だけR,G,Bのデータを取得しているのですが、あくまでも補間してR,G,Bの輝度値を得ている場所が多いという事に注意して下さい。

 

実際に、このようなセンサで撮影した生のデータ(RAWデータ)は、下図のようになります。

 

 

カラーセンサであっても、センサの構造的にはモノクロセンサと変わらないので、センサから出てくる生のデータは市松模様をしたモノクロデータとなります。

 

これを単純な補間方法でカラー画像に変換すると、

 

 

このように、エッジ部分がギザギザしたカラー画像となってしまいます。

 

こうならないようにカメラメーカ各社は、様々なノウハウで綺麗なカラー画像へと変換しています。

例えばデジカメでいうところの画像処理エンジンと呼ばれる、ニコンでいうとEXPEED、キヤノンのDIGICがこのカラー画像への変換処理を担っています。

 

割と単純なフィルタ処理をするだけでも、このように↓なるのですが、こうなると、もともとの生データがギザギザしていたことを忘れてしまいますね。

 

このようにカラーカメラは、ほとんどの画素が補間により作り出された画素であることから、数画素レベルの解像度が重要となる場合の多いマシンビジョンにおいては、「カラーカメラはモノクロカメラを兼ねない」となります。

 

数画素レベルの解像度が重要でしかもカラーが必要な場合には、R,G,Bそれぞれのセンサを用いた3CCDカメラや、モノクロカメラのレンズの前に、R,G,Bのフィルタを配置して、フィルタを切り替えながら3回R,G,Bの画像を撮影し合成することでカラー画像を生成したり、照明をR,G,B、3回に分けて撮影することで、カラー画像を生成する場合もあります。

これらのことから、工業用のカメラでは、なんで今どきモノクロカメラを使う場合が多いんだろう?

と昔は思っていたのですが、あえてモノクロカメラを使った方が解像度的には有利になるという点が重要です。

 

マシンビジョンへ戻る

FPGA処理によるカラー光切断法の公開(参考出品)

2016年6月8日~10日に開催される画像センシング展にて、これまで公開してきたカラー光切断の処理を画像入力ボード上のFPGAにて処理を行ったものを参考出品します。

 

 

処理をFPGAで処理していることからCPUの負荷がなく、あたかもラインセンサで撮影したかのようにテクスチャ画像とデプスマップ画像の2つが同時に取得されます。

CPUの負荷が無いので、PC側ではテクスチャ画像とデプスマップ画像を使った画像処理に集中できます。

 

また、FPGA処理がカメラ内部ではなく、画像入力ボード内で行っていることから、ある程度、使用するカメラを選ぶ事ができるので、フレームレート重視だったり、画像数重視だったりと、融通が利くのもメリットです。

 

カラー光切断法を画像機器展2014で公開

以前、公開しましたカラー光切断法ですが、今回は回転テーブルに対応して2014.12.3~12.5にパシフィコ横浜で開催されている国際画像機器展で展示しています。

 

この回転対応は、まだまだ参考出品状態なのですが、ご興味のある方は来場頂けると幸いです。

 

こちらは比較的撮影しやすい雪だるまの置き物

 

こちらは形状がゴツゴツしていて撮影が難しい↓

 

この手のワークは何回か撮影の向きを変えて合成したいところですが、まだ、そこまでの対応はできていません。

 

カラー光切断法公開

通常の光切断法による三次元測定ではレーザーをスリット光を用い、モノクロのエリアセンサで撮影し、スリット光の形状から、被写体の三次元形状を求めますが、CCSさんから発売されている、白色LEDのスリット光を用いてカラーのエリアセンサで撮影すると、立体形状がカラーのテクスチャ付きで取得できるのではないか?という事でカラーの光切断法を開発し、国際画像機器展2013で公開しました。

 

特長は簡単に言うと

  • 高速
  • 高分解能
  • カラーのテクスチャ付き

という感じ。

 

撮影している様子はこちら↓

 

 

そしてこちらは、高速のモノクロカメラを使った、高速版。

 

 

被写体の上部からスリット光をあて、これを斜め方向からカメラで撮影するという、スリット光が白色であること以外はいたって普通の構成です。

 

この状態で撮影し処理すると、こんな結果↓が得られます。

 

画面左上が高さを表しているデプスマップ(16bitモノクロ画像)と画面左下がそのテクスチャ(RGB画像24bit)となります。

 

この2つの画像を使って、OpenGLで三次元表示したものが、右側の画像。

 

この感じの画像で、撮影幅が38mmでVGA(640×480画素)の単板のカラーカメラを使っている割には、そこそこの測定解像力があるように思っています。

 

形状を測定するのが主な目的の場合、本来ならBayerパターンのカラーカメラなんかを使わず、モノクロカメラを使った方が有利なハズなのですが、カラーで処理すると、展示会では目をひきそうだし、単純に面白いのでカラーカメラを用いました。

 

また光切断法では、光の乱反射の影響による誤検知や測定スピードがネックとなりがちなのですが、今回開発した手法では、できるだけ乱反射の影響を受けずらく(※)、測定スピードも1フレームの撮影あたり複数ライン分(2、3ライン分ぐらい)のプロファイルデータを出力する事で、測定スピードの高速化を図りました。

※現状、反射の影響を完全に取りきれる訳ではありません。

 

測定例

【溶接形状】

レーザーを使った光切断では光の乱反射による影響で、うまく撮影できない場合が多かったのですが、LEDのスリット光を使ったせいか?比較的、反射の影響を受けないようです。

(部分拡大)

 

【指の指紋】

高さ分解能が実感できると思い、指の指紋を撮影してみました。

指の指紋の高さは0.1mm程度らしいのですが、そこそこ凹凸感がわかります。

(部分拡大)

 

【指の指紋】

光切断法は一般に光沢のある物、毛羽立った物などの測定にはあまり向いていないとされているので、試しにハンドタオルを撮影してみたのですが、糸がほつれている具合も確認できました。

【その他】

 

 

”カラー光切断法”とか言っておきながらモノクロのカメラを使う事ができます。
モノクロのカメラを使うと、Bayerパターンが影響する事がないし、処理速度も速くなり、形状重視ならモノクロの方が良くなります。

 

この処理に関するお問い合わせがありましたら、私の会社のWebページ
http://www.avaldata.co.jp/products/z2_imaging/opt_3d/opt_3d.htmlの下の方
よりお願い致します。

 

マシンビジョンへ戻る