画像処理入門

周南ロボコンの際ねじやナットが大量に混ざり合い何時間もかけて

分別・収納する期間があります。

メカトロ部の1年生も毎年オフシーズンに苦労するそうです。

 

というわけで近いうちにねじの分別装置作ろうと思います!

今回はその前段階というわけで先輩の記事を参考にマッチング処理をしてみます。


m12watanabe1a.hatenablog.com


こちらの後半にあるプログラム、基本どんな画像でもマッチングしてくれます。

今回はマッチするかどうかでON or OFFをさせたいのでその部分を紹介致します。


マッチしているかを判断する方法はいくつかあると思いますが、今回でいうと描画する線の数が気になるところです。

それをどこで判断しているかというと# マッチング精度が高いもののみ抽出のところ。

ratioがマッチング判断の範囲を表しているわけですが、goodという配列を用意して
画素の特徴量を1つずつ検証して高いものだけを追加しているようです。

つまり
good内の要素の数=マッチした画素の数(描画する線の数)
となっていることが分かる。
配列の要素の数はlen関数で求まるので以下のようになる。

# マッチング精度が高いもののみ抽出
MIN_MATCH_COUNT = 8
ratio = 0.8
good = []
for m, n in matches:
    if m.distance < ratio * n.distance:
        good.append([m])
if len(good) < MIN_MATCH_COUNT:
    print("OFF")
if len(good) > MIN_MATCH_COUNT:
    print("ON")

すこし論証みたいになってしまいましたが、あとは基準を決めて線が何個以上ならON(今回は8個)以下ならOFFにするか決めて必要な処理を書いてやるだけです。

ついでにラズパイでのOpenCVのセットアップ方法とラズパイカメラを使ったマッチング処理プログラムを載せておくので参考にしてみてください!

*install of opencv の方だけでopencvは基本動作しますが、Akaze自体の導入は比較的最近なので今回の場合は additional の方も必要になります。

# install of opencv
$ sudo apt-get update
$ sudo apt-get install libopencv-dev python-opencv

# additional install for Akaze
$ sudo pip3 install opencv-contrib-python
$ sudo apt-get install libatlas-base-dev
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO
import time
import picamera
import subprocess

import cv2
import numpy as np

from datetime import datetime

MIN_MATCH_COUNT = 8

camera = picamera.PiCamera()
camera.resolution = (640,480)
filename = datetime.now().strftime('assets/img/sample/test.jpg')


# 画像読み込み先のパス,結果保存用のパスの設定
template_path = "assets/img/template/"
template_filename = "maku.jpg"

sample_path = "assets/img/sample/"
sample_filename = "test.jpg"

result_path = "assets/img/result_AKAZE/"
result_name = "perfect.jpg"

akaze = cv2.AKAZE_create() 

camera.capture(filename)

# 文字画像を読み込んで特徴量計算
expand_template=2
whitespace = 20
template_temp = cv2.imread(template_path + template_filename, 0)
height, width = template_temp.shape[:2]
template_img=np.ones((height+whitespace*2, width+whitespace*2),np.uint8)*255
template_img[whitespace:whitespace + height, whitespace:whitespace+width] = template_temp
template_img = cv2.resize(template_img, None, fx = expand_template, fy = expand_template)
kp_temp, des_temp = akaze.detectAndCompute(template_img, None)

# 間取り図を読み込んで特徴量計算
expand_sample = 2
sample_img = cv2.imread(sample_path + sample_filename, 0)
sample_img = cv2.resize(sample_img, None, fx = expand_sample, fy = expand_sample)
kp_samp, des_samp = akaze.detectAndCompute(sample_img, None)

# 特徴量マッチング実行
bf = cv2.BFMatcher()
matches = bf.knnMatch(des_temp, des_samp, k=2)


# マッチング精度が高いもののみ抽出
ratio = 0.8
good = []
for m, n in matches:
    if m.distance < ratio * n.distance:
        good.append([m])
if len(good) < MIN_MATCH_COUNT:
    print("OFF")
if len(good) > MIN_MATCH_COUNT:
    print("ON")