ポスログ

ぽすとぐれすの日常

【raspberry PiでOpenCVしよう!】~特徴量抽出編~

raspberry piのカメラ画像を用いた特徴量の抽出方法について述べたいと思います.
OpenCVを用いると,非常にシンプルなソースコードで画像処理が可能ですが,
バージョンごとに関数の命名が変更されてしまい,サンプルのソースコードがそのまま使えないという場合も多々あると思います.
そこで,今回私がPython言語を用いた特徴量抽出について詰まった点,そして,それをどのように解決したかを今回は書きます.

実行結果

f:id:matsuda1991528:20161230131423p:plain

SIFT等特徴量を抽出する関数の呼び出し

まず,引っかかったのがこれ.バージョン2.3あたり(定かではない...)までは特徴量を抽出する関数の呼び出しは
以下のようにして行えていた.

cv2.SIFT()

しかし,最近では,呼び出し方が変わったらしく以下のようにしなければならない

sift = cv2.FeatureDetector_create('GFTT')

特徴点を画像ファイルへの書き込み

通常は特徴点を画像ファイルへ書きこむ場合,以下の関数を呼び出す事でできるっぽい

out = cv2.drawKeypoints(img, keypoints, None)

しかし,なぜか私の場合は出来なかった...なんでだろ...
OpenCVのバージョンを変えて入れなおしても呼び出せず...
そこで,drawKeypoints関数を自作すればよいとの話がありまして自作する事に.
自作した関数は以下の通り

def draw_keypoints(vis, keypoints, color = (0, 255, 255)):
	cnt = 0
	for kp in keypoints:
		x, y = kp.pt
		cv2.circle(vis, (int(x), int(y)), 2, color)
		cnt+=1
	print cnt

これにて,特徴点書き込みの関数呼び出せない問題も無事に解決しました.

最後に,RaspberruPiを用いて特徴点を抽出するプログラムを記載します.
ちなみに,用いているカメラはPicameraです.

import io
import picamera
import cv2
import numpy as np

def draw_keypoints(vis, keypoints, color = (0, 255, 255)):
	cnt = 0
	for kp in keypoints:
		x, y = kp.pt
		cv2.circle(vis, (int(x), int(y)), 2, color)
		cnt+=1
	print cnt

cascade_path = "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_path)

stream = io.BytesIO()

CAMERA_WIDTH = 320
CAMERA_HEIGHT = 240

color = (255,255,255)

camera = picamera.PiCamera()
camera.resolution = (CAMERA_WIDTH, CAMERA_HEIGHT)

for i in xrange(10):
	camera.capture(stream, format='jpeg')
	data = np.fromstring(stream.getvalue(), dtype=np.uint8)
	image = cv2.imdecode(data, 1)
	cv2.imshow('image', image)
	cv2.waitKey(16)

	image_output = image

	sift = cv2.FeatureDetector_create('GFTT')
	kp = sift.detect(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY))
	draw_keypoints(image_output, kp, (255, 0, 0))

	cv2.imshow('image_out', image_output)
	cv2.waitKey(16)

	stream.seek(0)
	print "captured %d" %(i)

かなり汚いソースコードです...きれいなソースコードの書き方も勉強しなくては...

参考