Image Registrationによる外観検査
はじめに
前回、位相限定相関法によるImage Registration手法で遊んでみました。
nsr-9.hatenablog.jp
Image Registrationの一つの応用先として、外観検査装置があります。
外観検査装置は、工場のラインで流れてくる製品を高速度カメラで撮影し、傷や付着物などの品質不良が無いか自動的に判別するシステムです。
以下の動画の6:40あたりから外観検査装置が登場しています。
youtu.be
外観検査装置は画像処理技術が最も早く社会実装された応用先だと思います。
今回は、pythonとOpenCVを用いて、簡単な外観検査アルゴリズムを作ってみたいと思います。
画像処理による外観検査
外観検査のやり方は多種多様なものがありますが、その中でも最も簡単なものはテンプレートの差分を求める手法だと思います。
逐次ラインから流れてくる製品をカメラで撮影し、品質不良の無い理想のテンプレート画像と比較する事で異常を検出します。
テンプレートと比較する際は、一般的に画像差分を行います。
シンプルに実装すると次のようになります。
import cv2 img = cv2.imread("img.jpg") tmp = cv2.imread("tmp.jpg") cv2.asbdiff(img, tmp)
しかしながら、そのままこれで実行しようとすると、製品の画像がずれていた場合、悲しいことになってしまいます。
画像1 | 画像2 | 差分画像 |
---|---|---|
差分画像について、色がついている部分がテンプレートと異なる領域なのですが、特に異常が無いにもかかわらず大部分が異なる領域であると出力されています。
これだと異常検知ができないので、前回遊んだImage Registrationを適用します。
import cv2 import sys import numpy as np if __name__ == "__main__": img1 = cv2.imread(sys.argv[1]) img2 = cv2.imread(sys.argv[2]) gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY).astype(np.float32) gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY).astype(np.float32) (x, y), r = cv2.phaseCorrelate(gray1, gray2) print(x, y, r) W = img1.shape[1] H = img1.shape[0] if x < 0: x11, x12 = abs(int(x)), W x21, x22 = 0, W-abs(int(x)) else: x21, x22 = abs(int(x)), W x11, x12 = 0, W-abs(int(x)) if y < 0: y11, y12 = abs(int(y)), H y21, y22 = 0, H-abs(int(y)) else: y21, y22 = abs(int(y)), H y11, y12 = 0, H-abs(int(y)) print(W, x12-x11, x22-x21) cv2.imwrite("out1.png", img1[y11:y12, x11:x12]) cv2.imwrite("out2.png", img2[y21:y22, x21:x22])
Image Registrationを行った後に差分をとると次のようになります。
画像1 | 画像2 | 差分画像 |
---|---|---|
Image Registration後の差分画像を見るとほとんどの領域の輝度値が0に近くなっている事がわかります。
では、いよいよ異常検知をやってみます。
以下の画像の様に、異常データとして黒のマジックでXマークをつけてみました。
画像1 | 画像2 | 差分画像 |
---|---|---|
ちょっと分かりにくいので、差分画像を拡大してみました。
いい感じにXマークの部分が強調されていますね!
まとめ
Image Registrationと差分法で簡単な外観検査装置(の一部の機能)を作ってみました。
外観検査装置はさまざまな事に応用できるはずなので、これを使って色々作ってみたいと思います。