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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenCV

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

Q&A

0回答

1379閲覧

Opencvを用いて指の速度検出

chihichihi

総合スコア1

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenCV

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

0グッド

0クリップ

投稿2020/11/20 12:26

初めての質問で慣れていない点がございますが、回答よろしくお願いします

前提・実現したいこと

指に青色の丸いシールを貼り指の重心の速さを検出するようなプログラムを作成したいと思っています。

発生している問題・エラーメッセージ

実際にプログラムを動かすと1フレームごとの重心の変化量から速さが検出できていません。

該当のソースコード

c++

1 2#include <opencv2/opencv.hpp> 3#include <iostream> 4#include<math.h> 5 6using namespace std; 7using namespace cv; 8 9int main(void) 10{ 11 // 動画ファイルを取り込むためのオブジェクトを宣言する 12 VideoCapture video; 13 // 動画ファイルを開く 14 video.open(3); 15 if (video.isOpened() == false) { 16 // 動画ファイルが開けなかったときは終了する 17 return 0; 18 } 19 20 int width, height; 21 double fps; 22 width = (int)video.get(CAP_PROP_FRAME_WIDTH); // フレーム横幅を取得 23 height = (int)video.get(CAP_PROP_FRAME_HEIGHT); // フレーム縦幅を取得 24 fps = video.get(CAP_PROP_FPS); // フレームレートを取得 25 26 printf("画像サイズ %d%d, %ffps\n", width, height, fps); 27 28 int x_g = 0; 29 int y_g = 0; 30 31 Mat image;// 画像を格納するオブジェクトを宣言する 32 while (1) { 33 video >> image; // videoからimageへ1フレームを取り込む 34 if (image.empty() == true) break; // 画像が読み込めなかったとき、無限ループを抜ける 35 Mat channels[3], red, red_bin; 36 split(image, channels); // RBGに分解 37 red = channels[2]; 38 threshold(red, red_bin, 50, 255, THRESH_BINARY_INV); //閾値50で二値化 39 40 int xb = 0; 41 int yb = 0; 42 double v; 43 44 45 Moments m = moments(red_bin, true); //二値化画像に重みをもたせる 46 double area = m.m00; 47 48 49 xb = x_g; 50 yb = y_g; 51 52 int x_g = m.m10 / m.m00; //xの重心を求める 53 int y_g = m.m01 / m.m00; //yの重心を求める 54 v = sqrt((x_g - xb) ^ 2 + (y_g - yb) ^ 2)*60; 55 cout << x_g << "" << y_g << endl; 56 57 Point2f mc = Point2f(x_g, y_g); 58 circle(image, mc, 10, Scalar(0, 0, 255), -1)// 元動画に重心を表示 59 printf("xg,""%d,""yg,""%d,""v,""%lf", x_g, y_g,v); // 重心の座標、速度を表示 60 61 62 imshow("R二値化", red_bin); 63 imshow("Rチャンネル",red); 64 imshow("元動画", image); 65 66 if (cv::waitKey(1) == 'q') break; //qを押すと終了 67 } 68 return 0; 69}

試したこと

x_g,y_g,xb,ybの部分をどのように書けばいいのかを工夫して色々試してみましたがうまくいきませんでした

補足情報(FW/ツールのバージョンなど)

visual studio 2017とOpencv4.5を使っています.

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

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

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

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

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

episteme

2020/11/20 13:21

「1フレームごとの重心の変化量」を求めているのは示されたコードのどこですか?
chihichihi

2020/11/20 13:33

v = sqrt((x_g - xb) ^ 2 + (y_g - yb) ^ 2)*60 のx_g - xbとy_g - ybの部分になります。 while文の中の xb = x_g; yb = y_g; で前のフレームの重心を保存して int x_g = m.m10 / m.m00; int y_g = m.m01 / m.m00; で新しく重心を取得してその差を1フレームの重心の変化量と考えております。
episteme

2020/11/20 13:44

^2 は 二乗ではありません。
chihichihi

2020/11/20 14:15

簡単な関数も覚えておらず申し訳ありません。 pow関数を実装して動かしてみましたが xg,417,yg,290,v,30475.570544418290 xg,418,yg,290,v,30524.848894418290 xg,418,yg,290,v,30524.848894418290 xg,418,yg,290,v,30524.848894418291 xg,418,yg,291,v,30559.090301418291 このように重心位置の変化がない場合でも速度が表れてしまいます。
episteme

2020/11/21 00:05 編集

while-loop の内と外の双方に int x_g , int y_g が定義されているのはマチガイではありませんか?
chihichihi

2020/12/01 03:54

定義を1つにしたら計算をしっかり行うことが出来ました. 丁寧な回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問