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

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

ただいまの
回答率

91.06%

  • Python 3.x

    3710questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • OpenCV

    795questions

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

検出結果を修正・拡張したいです

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 129
退会済みユーザー

退会済みユーザー

前提・実現したいこと
移動しているボール(ジャグリングなど)を検出して円を描くプログラムです。OpenCVで移動体検出を使ったサンプルをいくつかつなぎ合わせたハリボテプログラムなので、余計な部分があるかもしれませんが、あまり気にしないでいただけると……
実現したいこととしては、
①余計に表示されてしまっている円をボール上だけにしたいこと(円の数を減らしたい)
②加えてボールの軌跡を描くこと(軌跡の描き方は分かっているのですが、それぞれのボール(円)ごとに区別するやりかたがわかりません)
の二つです。
どうかよろしくお願い致します。

該当のソースコード

import cv2
import numpy as np
from collections import deque
import argparse
import math

kernel = np.ones((5,5),np.uint8)

neiborhood4 = np.array([[1, 1, 1],
                        [1, 1, 1],
                        [1, 1, 1]],
                        np.uint8)

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
    help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=10,
    help="max buffer size")
args = vars(ap.parse_args())

# フレーム差分の計算
def frame_sub(src1, src2, src3, th):
    # フレームの絶対差分
    d1 = cv2.absdiff(src1, src2)
    d2 = cv2.absdiff(src2, src3)

    # 2つの差分画像の論理積
    diff = cv2.bitwise_and(d1, d2)

    # 二値化処理
    diff[diff < th] = 0
    diff[diff >= th] = 255

    # メディアンフィルタ処理(ゴマ塩ノイズ除去)
    mask = cv2.medianBlur(diff, 3)

    return  mask

def main():

    pts1 = deque(maxlen=args["buffer"])
    # カメラのキャプチャ
    cap = cv2.VideoCapture("動画ファイル")

    cv2.namedWindow("Frame2",cv2.WINDOW_NORMAL)
    cv2.namedWindow("Douga",cv2.WINDOW_NORMAL)


    # フレームを3枚取得してグレースケール変換
    frame1 = cv2.cvtColor(cap.read()[1], cv2.COLOR_RGB2GRAY)
    #frame2 = cv2.cvtColor(cap.read()[1], cv2.COLOR_RGB2GRAY)


    frame3 = cv2.cvtColor(cap.read()[1], cv2.COLOR_RGB2GRAY)


    while True:
        #(grabbed, frame) = cap.read()
        count=0
        frame2_rgb = cap.read()[1]
        frame2 = cv2.cvtColor(frame2_rgb, cv2.COLOR_RGB2GRAY)
        #if not grabbed:
        #    break

        # フレーム間差分を計算
        mask = frame_sub(frame1, frame2, frame3, th=30)
        #太くして面積を広く
        mask = cv2.dilate(mask,neiborhood4,iterations = 1)
        #輪郭の取得
        image, cnts, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

        center=None

        if  len(cnts) > 0:
            for i, contour in enumerate(cnts):

                # area:面積
                area = cv2.contourArea(contour)
                if  area < 100:
                    continue

                # moments:重心
                M = cv2.moments(contour)
                if M["m00"] != 0:
                    cx = int(M["m10"] / M["m00"])
                    cy = int(M["m01"] / M["m00"])
                else:
                    cx, cy = 0, 0

                # 最小外接円
                (x, y), radius = cv2.minEnclosingCircle(contour)
                center = (int(x),int(y))
                radius = int(radius)
                frame2_rgb = cv2.circle(frame2_rgb,center,radius,(255,255,0),2)
                pts1.appendleft(center)

                count=count+1


        # 結果を表示
        cv2.imshow("Frame2", frame2)
        cv2.imshow("Mask", mask)
        cv2.imshow("Douga",frame2_rgb)
        print(count) 

        # 3枚のフレームを更新
        frame1 = frame2
        frame2 = frame3
        frame3 = cv2.cvtColor(cap.read()[1], cv2.COLOR_RGB2GRAY)
        # qキーが押されたら途中終了
        key = cv2.waitKey(50) & 0xFF
        if key == ord("q"):
            break
    cap.release()
    cv2.destroyAllWindows()

if __name__ == '__main__':
    main()

試したこと

試しに、軌跡を描くプログラムを追加してみたのですが、中心の位置が区別できていないため、あっちこっちにぶれて描かれてしまいました。

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

windows7/Anaconda3.4.4/Spyder3(Python3.5)/OpenCV 3.1.0

イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2018/01/12 19:23

    動画だとTeratailにアップロードできませんので、かわりに検出前の動画から数フレーム分の画像をアップすることはできますか?

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2018/01/13 17:41

    ありがとうございます。https://qiita.com/itoru257/items/228a91404fa77c780fd4の感じでJPEGから動画を起こして試してみます。

    キャンセル

回答 1

+1

余計に表示されてしまっている円をボール上だけにしたいこと(円の数を減らしたい)

ボールが緑色と決まりきっているのであれば、緑色のみを抽出すればよいですね。
以下の関数をframe2frame3に突っ込むことでだいぶ良くなると思います。

def color_binary(img):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower_green = np.array([45,64,128])
    upper_green = np.array([100,255,180])

    mask = cv2.inRange(hsv, lower_green, upper_green)
    res = cv2.cvtColor(cv2.bitwise_and(img,img, mask= mask), cv2.COLOR_RGB2GRAY)
    _, res = cv2.threshold(res , 1,255, cv2.THRESH_BINARY)
    return res

加えてボールの軌跡を描くこと(軌跡の描き方は分かっているのですが、それぞれのボール(円)ごとに区別するやりかたがわかりません)

terarailの過去の投稿に同じような問題がありました。
# 結果を表示の前に以下のコードを挟むとある程度動くと思います。
が、手元の6枚の写真から作った動画では動作確認ができる状態ではなかった(3フレームの差分を取るため、2フレームくらいしか出てこない)ので私にできるのはここまでです。ごめんなさい。

    # update the points queue
    pts1.appendleft(center)

    # loop over the set of tracked points
    for i in range(1, len(pts1)):
        # if either of the tracked points are None, ignore
        # them
        if pts1[i - 1] is None or pts1[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(frame2_rgb, pts1[i - 1], pts1[i], (0, 0, 255), thickness)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/01/14 14:12

    回答ありがとうございました。①の方は解決しましたが、②に関してはうまく動いてくれませんでした。
    改めて実現したいことを書くと、中心点を区別して、円から伸びる軌跡が円ごとに独立して描かれてほしいです。
    厚かましいとは思いますが、どうかよろしくおねがいします。

    キャンセル

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

  • ただいまの回答率 91.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    C++のCAD上で作成した図形の輪郭切り取り

    C++ ```###前提・実現したいこと CADで図のような立体画像を作成し、この画像の赤い部分のような、輪郭画像を抽出するプログラムを作成しました。このプログラムを使用し現在

  • 解決済

    python3+OpenCVで、特定色の箇所を白い線で囲いたい

    お世話になっております。 今回は、python3 + opencvにて以下のようなことをやりたいと考えているのですが、どのようにすれば実現できるのか分からない為、ご質問させて

  • 解決済

    SQLパラメーター式テーブルの値をand検索する

    実現したいこと fruit_id : 1 -> apple fruit_id : 2 -> mikan fruit_id : 3 -> banana テーブル名 : f

  • 解決済

    Python2.7.10のIndexError: only integers, sliceの対処方

    前提・実現したいこと Python2.7.10を使用してparticlefilterを実装したいです. python + numpyで緑色の物体を追跡する (パーティクルフ

  • 受付中

    ER図について

    つぶやきアプリを作っているのですが、 ER図を作るとする例えばどんなものがありますか?? サンプル程度でいいので教えていただきたいです

  • 受付中

    XamarinFormsでTabbedPageのアイコンの設定ができない

    XamarinFormsにて、タブページのアプリの作成中です。 MainPage.xamlにて、TabbedPageの下にContentPageを複数定義し、 ContentPag

  • 解決済

    RenderTextureの実装方法

    前提・実現したいこと ここに質問したいことを詳細 RenderTextureを使ってカメラで撮影したエフェクト(Particle System)をCanvasの配下にあるRawIm

  • 解決済

    UnityでSpriteを使って一部を透明化する方法

    最近、シーンチェンジを実装するために基礎となる画像をSpriteを用いて一部透明化しようと考えたのですが、当たり前ですが単純に配置しても基礎画像が表示されてしまいます。(以下参考画

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

  • Python 3.x

    3710questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • OpenCV

    795questions

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