初めての質問で慣れていない点がございますが、回答よろしくお願いします
前提・実現したいこと
指に青色の丸いシールを貼り指の重心の速さを検出するようなプログラムを作成したいと思っています。
発生している問題・エラーメッセージ
実際にプログラムを動かすと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を使っています.
「1フレームごとの重心の変化量」を求めているのは示されたコードのどこですか?
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フレームの重心の変化量と考えております。
^2 は 二乗ではありません。
簡単な関数も覚えておらず申し訳ありません。
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
このように重心位置の変化がない場合でも速度が表れてしまいます。
while-loop の内と外の双方に int x_g , int y_g が定義されているのはマチガイではありませんか?
定義を1つにしたら計算をしっかり行うことが出来ました.
丁寧な回答ありがとうございました。
あなたの回答
tips
プレビュー