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

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

ただいまの
回答率

90.49%

  • Python

    12184questions

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

  • OpenCV

    1552questions

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

ボールトラッキング ball tracking

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,186
退会済みユーザー

退会済みユーザー

質問

私はボールトラッキングをしようとしています。ここのプログラム実行させると私が求めていたものに非常に近いので使いたいのですが、初めの方に書いてあるap = argparse.ArgumentParser()からの6行、pts = deque(maxlen=args["buffer"])の意味がよくわからず、while文の中でもそれが使われているところがあり理解できません。指定した色の範囲以外の色を黒くしてしまい、そこから中心を求め、円を描画しているのだろうと思います。基本的な部分かもしれませんが教えていただきたいです。
あとteratailで質問を書く際にソースコードに行の番号を書きいれることはできますか?(地道に書き入れる以外の方法です。)宜しくお願いします。

該当のソースコード

from collections import deque
import numpy as np
import argparse

import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
    help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
    help="max buffer size")
args = vars(ap.parse_args())

# define the lower and upper boundaries of the "green" 
# ball in the HSV color space, then initialize the
# list of tracked points
greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
pts = deque(maxlen=args["buffer"])

# if a video path was not supplied, grab the reference
# to the webcam
if not args.get("video", False):
    camera = cv2.VideoCapture(0)
# otherwise, grab a reference to the video file

else:
    camera = cv2.VideoCapture(args["video"])

camera.set(3,320)
camera.set(4,240)
# keep looping
while True:
    # grab the current frame
    (grabbed, frame) = camera.read()

    # if we are viewing a video and we did not grab a frame,
    # then we have reached the end of the video
    if args.get("video") and not grabbed:
        break

    # resize the frame, blur it, and convert it to the HSV
    # color space
    #frame = imutils.resize(frame, width=600)
    # blurred = cv2.GaussianBlur(frame, (11, 11), 0)
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # construct a mask for the color "green", then perform
    # a series of dilations and erosions to remove any small
    # blobs left in the mask
    mask = cv2.inRange(hsv, greenLower, greenUpper)
    mask = cv2.erode(mask, None, iterations=2)
    mask = cv2.dilate(mask, None, iterations=2)

    # find contours in the mask and initialize the current
    # (x, y) center of the ball
    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                            cv2.CHAIN_APPROX_SIMPLE)[-2]
    center = None

    # only proceed if at least one contour was found
    if len(cnts) > 0:
        # find the largest contour in the mask, then use
        # it to compute the minimum enclosing circle and
        # centroid
        c = max(cnts, key=cv2.contourArea)
        ((x, y), radius) = cv2.minEnclosingCircle(c)
        M = cv2.moments(c)
        center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

        # only proceed if the radius meets a minimum size
        if radius > 10:
            # draw the circle and centroid on the frame,
            # then update the list of tracked points
            cv2.circle(frame, (int(x), int(y)), int(radius),
                       (0, 255, 255), 2)
            cv2.circle(frame, center, 5, (0, 0, 255), -1)

    # update the points queue
    pts.appendleft(center)

    # loop over the set of tracked points
    for i in xrange(1, len(pts)):
        # if either of the tracked points are None, ignore
        # them
        if pts[i - 1] is None or pts[i] is None:
            continue

        # otherwise, compute the thickness of the line and
        # draw the connecting lines
        thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
        cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)

    # show the frame to our screen
    cv2.imshow("Frame", frame)
    key = cv2.waitKey(1) & 0xFF

    # if the 'q' key is pressed, stop the loop
    if key == ord("q"):
        break

# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

フレームごとに球の検出と重心の計算をしてキューに保存し、描画するプログラムのようですね。


キューについて
どこまで理解されているかわからないので、とりあえずここから。
キューはデータ構造の一つで、古いデータから順に抜き取る(FIFO)ときに便利です。
このプログラムでは、一定以上古い重心は捨てているようで、そのためにキューが用いられています。
詳しくはググった方が早いです。

argparseについて
コマンドライン引数を処理している部分です。

  • buffer: キューの長さ(どれくらい古い重心まで残すか)。デフォルトで64。
  • video : ビデオか/Webカメラか。デフォルトで後者。

ビデオに対する処理が出来るのは便利ですね。
ap.add_argumentなどのメソッドは、上記を設定している部分になります。

pts = deque(maxlen=args["buffer"])
ptsに、コマンドライン引数bufferで指定された長さのキューのインスタンスを代入しています。

処理の流れについて
かなり詳しくコメントが入っているコードなので、そちらをしっかり読むことをおすすめします。
まあ、基本的な流れとしては、以下の感じですかね。

  1. 緑色の部分をくりぬいてノイズ除去
  2. 輪郭を検出
  3. 一番大きな輪郭の重心を計算
  4. ある程度輪郭の半径があれば、キューに書き出し
  5. キューの中の重心を順に描画

また、以下の部分は、単に見た目をそれっぽくしているだけです。

thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)

thicknessに適当に定数値を代入してみると意味がわかるかと思います。


コードに番号を付けられるか?
すみません、私は知らないです。
ただ、今回のように、githubへのリンクが張ってあるのであれば、不要な気もします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/26 14:22

    ありがとうございます。

    キャンセル

+2

argparseはコマンドライン引数を簡単に扱えるモジュールです。
python video_ball_tracking.py -b 10からargs["buffer"]10という値が取り出せます。

またptsdequeですが、ざっとソース見る限り、直近"buffer"個分のトラッキング位置を保持し、これらの(履歴)点をつないで軌跡として描画しているようです。

あとteratailで質問を書く際にソースコードに行の番号を書きいれることはできますか?(地道に書き入れる以外の方法です。)宜しくお願いします。

ヘルプを見る限り、できないようです。
ただ、質問者様のように完全なコードを提示していれば、各自がエディタにコードコピーすれば行番号は分かるので行番号を書き入れる必要性はあまりないかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/26 14:22

    ありがとうございます。

    キャンセル

同じタグがついた質問を見る

  • Python

    12184questions

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

  • OpenCV

    1552questions

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