OpenCV3とPython3で形状のある物体の輪郭と方向を認識する(主成分分析:PCA、固有ベクトル)
OpenCV3とPython3で形状のある物体の輪郭と方向を認識する(主成分分析:PCA、固有ベクトル)
こちらのコードを参考に動かしてみた。一か所修正で動いた。
コードの意味はまだよくわからないが、すごいな。
ラベルの外観検査の傾き検出に使えそうだ。
実行結果
コードの意味はまだよくわからないが、すごいな。
ラベルの外観検査の傾き検出に使えそうだ。
# -*- coding: utf-8 -*-
import cv2
import math
import numpy as np
# ベクトルを描画する
def drawAxis(img, start_pt, vec, colour, length):
# アンチエイリアス
CV_AA = 16
# 終了点
end_pt = (int(start_pt[0] + length * vec[0]), int(start_pt[1] + length * vec[1]))
# 中心を描画
cv2.circle(img, (int(start_pt[0]), int(start_pt[1])), 5, colour, 1)
# 軸線を描画
cv2.line(img, (int(start_pt[0]), int(start_pt[1])), end_pt, colour, 1, CV_AA);
# 先端の矢印を描画
angle = math.atan2(vec[1], vec[0])
print(angle)
qx0 = int(end_pt[0] - 9 * math.cos(angle + math.pi / 4));
qy0 = int(end_pt[1] - 9 * math.sin(angle + math.pi / 4));
cv2.line(img, end_pt, (qx0, qy0), colour, 1, CV_AA);
qx1 = int(end_pt[0] - 9 * math.cos(angle - math.pi / 4));
qy1 = int(end_pt[1] - 9 * math.sin(angle - math.pi / 4));
cv2.line(img, end_pt, (qx1, qy1), colour, 1, CV_AA);
if __name__ == '__main__':
# 画像を読み込む
src = cv2.imread("pca_test1.jpg")
# グレースケールに変換
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# 2値化
retval, bw = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 輪郭を抽出
# contours : [領域][Point No][0][x=0, y=1]
# cv2.CHAIN_APPROX_NONE: 中間点も保持する
# cv2.CHAIN_APPROX_SIMPLE: 中間点は保持しない
#img, contours, hierarchy = cv2.findContours(bw, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
contours, hierarchy = cv2.findContours(bw, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
# 各輪郭に対する処理
for i in range(0, len(contours)):
# 輪郭の領域を計算
area = cv2.contourArea(contours[i])
# ノイズ(小さすぎる領域)と全体の輪郭(大きすぎる領域)を除外
if area < 1e2 or 1e5 < area:
continue
# 輪郭を描画する
cv2.drawContours(src, contours, i, (0, 0, 255), 2, 8, hierarchy, 0)
# 輪郭データを浮動小数点型の配列に格納
X = np.array(contours[i], dtype=np.float).reshape((contours[i].shape[0], contours[i].shape[2]))
# PCA(1次元)
mean, eigenvectors = cv2.PCACompute(X, mean=np.array([], dtype=np.float), maxComponents=1)
# 主成分方向のベクトルを描画
pt = (mean[0][0], mean[0][1])
vec = (eigenvectors[0][0], eigenvectors[0][1])
drawAxis(src, pt, vec, (255, 255, 0), 150)
# 表示
cv2.imshow('output', src)
cv2.waitKey(0)
# 終了処理
cv2.destroyAllWindows()
実行結果
コメント
コメントを投稿