質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

2回答

2411閲覧

Webカメラから動画を取り込み、OpenCV(PythonもしくはProcessing)で複数個の形をリアルタイムで識別し位置を取得したい

Nannana

総合スコア12

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

0クリップ

投稿2018/11/01 03:54

編集2018/11/01 04:33

前提・実現したいこと

初めて質問します。主にProcessingを用いたインタラクションデザインを学んでおります。
テンプレートマッチングどころか、OpenCVも初めて触るレベルでして、凄く初歩的な質問でしたら申し訳ございません。

現在、リアルタイムの動画をwebカメラから取り込み、映ったもの(幾何学模様が2,3個を想定)の位置を認識するプログラミングを調べています。

最終的に目指しているのは、アクリル板の台の下にwebカメラを置き、台の上に置かれたものの底に幾何学模様を貼り付けて、その位置に映像を上から映し出す作品です。

テンプレートマッチングで実装出来そうなのですが、参考に出来るようなサンプルプログラムが見つからず、お手上げの状態です。
また、テンプレートマッチングだと認識できる位置が、テンプレート画像内での位置になってしまうかと思うのですがいかがでしょうか。。。

現状でのコードを一応貼って置きます。画像によるテンプレートマッチングです。

一歩でも動き始められるようなヒントでも良いので、どなたか助言を下されば幸いです。

何卒宜しくお願い致します。

##現状でのコード

Processing

1import processing.video.*; 2import gab.opencv.*; 3import org.opencv.core.Mat; 4import org.opencv.core.CvType; 5import org.opencv.imgproc.Imgproc; 6import org.opencv.core.Core.MinMaxLocResult; 7import org.opencv.core.Core; 8 9//Capture Camera; //本当はこれで読み込むビデオを入力画像として使いたい 10 11// 入力画像の準備 12PImage inputImage = loadImage("tiisakusita1.jpg"); 13OpenCV inputCV = new OpenCV(this, inputImage); 14Mat inputMat = OpenCV.imitate(inputCV.getGray()); 15 16// テンプレート画像の準備 17PImage templateImage = loadImage("tiisakusita2.jpg"); 18 19OpenCV templateCV = new OpenCV(this, templateImage); 20Mat templateMat = OpenCV.imitate(templateCV.getGray()); 21 22// 結果格納用の行列の準備 23int resultCols = inputMat.cols() - templateMat.cols() + 1; 24int resultRows = inputMat.rows() - templateMat.rows() + 1; 25Mat resultMat = new Mat(resultRows, resultCols, CvType.CV_32FC1); 26 27// テンプレートマッチングを実行 28Imgproc.matchTemplate(inputCV.getColor(), templateCV.getColor(), resultMat, Imgproc.TM_CCOEFF_NORMED); 29 30// 結果を描画 31println("OK!"); 32size(400, 300); 33image(inputImage, 100, 0); 34image(templateImage, 10, 10,80,80); 35 36MinMaxLocResult mmlr = Core.minMaxLoc(resultMat); 37 38if (mmlr.maxVal > 0.1) { 39 println("Val: " + mmlr.maxVal); 40 stroke(255, 0, 0); 41 strokeWeight(3); 42 noFill(); 43 rect((int)mmlr.maxLoc.x + 100, (int)mmlr.maxLoc.y, templateMat.cols(), templateMat.rows()); 44}

###参考動画
1
2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

単純なテンプレートマッチングで
やりたいことを実現可能なのかどうかを調査すべきです.

台の上に置かれたもの

の置かれ具合(底面の模様の回転の有無)がどの程度かに依るでしょう.


(私は使った経験無いので,本当に使えるかどうかわからないのですが)
AR toolkit とか使えないか調べてみると良いのかも?

投稿2018/11/01 05:40

fana

総合スコア11632

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nannana

2018/11/01 05:48

ご回答をくださり誠にありがとうございます。 回転がある場合には、やはりテンプレートマッチングは難しいですよね。。 AR toolkitについて調べてみたいと思います。 ご提案くださりありがとうございます。
fana

2018/11/01 06:15

回転があるなら, {何か回転不変な特徴を利用できる,あるいは回転方向が簡単に推定できる}ように模様側デザインを決めると良いかと. また,リアルタイム性のために縮小した画像上で処理することも考えると,細かいデザインではない方が良いと思います.
Nannana

2018/11/04 03:39

そうですね、、貼り付ける側のデザインについても考慮してみたいと思います。 為になるアドバイスをくださり、ありがとうございます。
guest

0

ベストアンサー

テンプレートマッチングが使える条件

  • 検出対象の大きさが固定
  • 検出対象が回転していない

また、テンプレートマッチングだと認識できる位置が、テンプレート画像内での位置になってしまうかと思うのですがいかがでしょうか。。。

元画像の座標系での位置で検出できます。

テンプレートマッチングの仕組み

模様が形状で判断できる場合

findContours() で輪郭を抽出する方法がよいと思います。


追記

輪郭抽出ベースだと以下のような感じになります。
形状が丸、四角、三角、円など単純な形であれば、輪郭抽出ベースのやり方をおすすめします。

イメージ説明

import cv2 import matplotlib.pyplot as plt import numpy as np # 画像を読み込む。 img = cv2.imread('sample.png') img = cv2.flip(img, 1) # 輪郭抽出する。 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 輪郭を近似する。 approx_contours = [] for cnt in contours: # 輪郭の周囲の長さを計算する。 arclen = cv2.arcLength(cnt, True) # 輪郭を近似する。 approx_cnt = cv2.approxPolyDP(cnt, epsilon=0.005 * arclen, closed=True) approx_contours.append(approx_cnt) # 判定する。 for cnt in approx_contours: num_points = len(cnt) cv2.drawContours(img, [cnt], -1, (0, 0, 255), 3) if num_points == 3: cv2.drawContours(img, [cnt], -1, (255, 0, 0), 3) print('三角形') elif num_points == 4: cv2.drawContours(img, [cnt], -1, (0, 255, 0), 3) print('四角形') else: cv2.drawContours(img, [cnt], -1, (0, 255, 255), 3) print('その他') # 画像を表示する。 fig, axes = plt.subplots(figsize=(6, 6)) axes.imshow(img) axes.axis('off') plt.show()

イメージ説明
結果

三角形が赤
四角形が緑
それ以外が水色
で検出されています。位置ももちろん、取得できます。

追記

python

1 2import cv2 3 4device_id = 0 5cap = cv2.VideoCapture(device_id) 6 7while True: 8 # 1フレームずつ取得する。 9 ret, frame = cap.read() 10 if not ret: 11 break # 映像取得に失敗 12 13 result = detect(frame) # フレームから図形を検出する。 14 # 検出結果を使ってなにかする。 15 16 cv2.imshow('Frame', frame) 17 if cv2.waitKey(1) & 0xFF == ord('q'): 18 break # q キーを押したら終了する。 19 20cap.release() 21cv2.destroyAllWindows()

投稿2018/11/01 04:49

編集2018/11/02 04:00
tiitoi

総合スコア21954

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nannana

2018/11/01 05:03

回答を下さり誠にありがとうございます。 リンクに貼って下さりましたサイトを拝見しました。テンプレート画像内以外の場所に入力画像が現れた場合は認識されないのですね。ということはテンプレートマッチングは不適でしょうか? 形は物体の底に貼り付けるもので、円や四角形等単純な形です。 引き続きアドバイスを下されば非常に幸いです。 宜しくお願い致します。
tiitoi

2018/11/01 05:10

画像内以外とはどういうことでしょうか? カメラに写っていないものは、どんな方法でも検出できないと思いますが。
Nannana

2018/11/01 05:46

言葉足らずで申し訳ございません。 「テンプレート画像内以外の場所に入力画像が現れた場合は認識されないのですね」は勘違いでした。 テンプレート画像をカメラからの入力動画に変更する場合についてご教授いただければ幸いです。
tiitoi

2018/11/01 06:29 編集

テンプレート画像というのは、予め用意しておくものです。 テンプレートマッチングの場合、予め模様の画像を用意しておいて、カメラで取得した画像に対して、テンプレート画像をスライドさせながら類似度を計算していく仕組みになります。 輪郭ベースのやり方について、具体的な方法を記載しました。 Python 版の OpenCV ですが、OpenCV の API は各言語共通なので、そのまま他言語に流用できます。
Nannana

2018/11/01 07:11

具体的に示してくださり大変参考になります。 Processingで動かす場合についてもう少し詳しく教えていただけますでしょうか。。
tiitoi

2018/11/02 04:04

追記に OpenCV でカメラから映像を取得する方法も書きました。 やりたいことを実現するには以下の流れになると思います。 1. 映像を取得する。 2. 映像から模様を2値化して、輪郭抽出で検出する。 3. 検出結果を使ってなにかする。(映像を上から映し出す?) Processing は使ったことがないのでわからないです。 OpenCV を使うのであれば、言語にかかわらず API は共通なので、Python のコードを参考にすればできるはずです。
Nannana

2018/11/04 03:38

詳しく教えてくださりありがとうございます。 Pythonをほぼ触ったことがないので、なんとかProcessingに変換したいと思います! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問