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

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

ただいまの
回答率

90.03%

競輪選手の検出 アプローチ方法を教えて下さい

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 96

AndoJun

score 0

前提・実現したいこと

OpenCVを使い、競輪選手を検出し、選手間の位置を把握したいと考えています。
競輪選手を検出するにはどの手法を用いれば良いでしょうか?
画像解析のアプローチ方法を教えて下さい。

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

選手は1番から9番まで色分けされている事を利用して色検出させましたが、他のものを検出します。
イメージ説明

該当のソースコード

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class TestRacerColors {

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        String[] colors = new String[] {"white","black","red","blue","yellow","green","orange","pink","purple"};

        Scalar[] sBasic = new Scalar[] { new Scalar(  0, 0, 255), new Scalar(  0,   0,  0), new Scalar( 0, 255, 255), new Scalar( 80, 255, 255), new Scalar(30, 255, 255), new Scalar(60, 255, 255), new Scalar(20, 255, 255), new Scalar(175, 60, 255), new Scalar(150, 120, 170)};
        Scalar[] sStart = new Scalar[] { new Scalar(  0, 0,   0), new Scalar(  0,   0,  0), new Scalar(170, 50, 150), new Scalar(100,  50, 150), new Scalar(10,  50, 150), new Scalar(30,  50, 150), new Scalar( 0,  50, 150), new Scalar(160, 50, 150), new Scalar(120,  50,  80)};
        Scalar[] eEnd   = new Scalar[] { new Scalar(179, 5, 255), new Scalar(179, 255, 80), new Scalar(180,255, 255), new Scalar(120, 255, 255), new Scalar(25, 255, 255), new Scalar(80, 255, 255), new Scalar(15, 255, 255), new Scalar(170,255, 255), new Scalar(135, 255, 255)};
        int idx = 0;

        Mat image = Imgcodecs.imread("image_013.png");
        Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2HSV);
        Mat result = image.clone();

        for(String color:colors) {
            Mat mask = new Mat();
            Core.inRange(image, sStart[idx], eEnd[idx], mask);
            String[] values = MatHelper.getStat(mask);

            // 面積最大ブロブの中心座標を取得
            Point center = new Point();
            center.x = Double.parseDouble(values[0]) + ( Double.parseDouble(values[2]) / 2 );
            center.y = Double.parseDouble(values[1]) + ( Double.parseDouble(values[3]) / 2 );

            // 該当箇所を丸で囲う
            Imgproc.circle(result, center, 30, sBasic[idx], 3, Imgproc.LINE_AA);

            Imgproc.cvtColor(mask, mask, Imgproc.COLOR_GRAY2BGRA);
            Imgcodecs.imwrite("image_013_" + color + ".png", mask);
            idx++;
        }
        Imgproc.cvtColor(result, result, Imgproc.COLOR_HSV2BGR);
        Imgcodecs.imwrite("image_013_new.png", result);
    }
}

試したこと

Rangeの値を何回か変えて実行しましたが、改善されませんでした。
カスケード分類器によるUpperBody検索を実行しましたが、改善されませんでした。
DNNの利用を検討しています。

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

0penCV 4.1.2
Java 1.8

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2019/11/09 08:05

    もっと簡単な題材にしては…

    キャンセル

回答 2

checkベストアンサー

0

Java使いではありませんが手法は参考になると思います。

カスケード分類器によるUpperBody検索を実行しましたが、改善されませんでした。

人の上部のみの検索、ということでしょうか?
自転車に乗っていますので、自転車と人をコミコミで物体検出をしてはいかがでしょうか?
正解画像をもとに背景と合成して、データ増強した画像で学習させる、
ということが(少なくともPythonでは)OpenCVでできます。
HAAR-LIKEのキーワードで探すと色々出てきます。

人が移っていると思しき部分からさらに同アルゴリズムの頭の検出をすれば、
それなりの確率で頭の位置のみを検出できるはずです。
そこから何色に近い?をHSVか何かで比較したらよさそうです。

この方法にはDNNほどの精度や検出漏れのなさはないかもしれませんが、
これが現実的な線引きではないかと思います。

DNNの利用を検討しています。

既存のデータがそのまま使えるかどうかわかりませんが、
上記の方法より処理は重くデータをそろえるのも大変かと思います。
OpenPoseで人っぽい部分、その人の頭っぽい部分を検出、さらにそこの色が何に近いかを検出というような流れでしょうか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/11/09 18:02

    ご回答ありがとうございます。
    ご認識の通り、OpenCVに同梱されているカスケードファイルの(haarcascade_upperbody.xml)を使用して上半身の検出を行いました。

    ご提案いただいた案(自転車と人->頭->色)の検出器の構築した場合、どのぐらいの精度になるものかわかりますでしょうか?
    感覚的なもので構いませんのでお教え頂けると助かります。
    目指すところとしては8割(1枚の画像で9人中7人)検出させたいと考えております。

    キャンセル

  • 2019/11/10 08:49

    > 自転車と人->頭->色)の検出器の構築した場合、どのぐらいの精度になるものかわかりますでしょうか?
    根拠はありませんが、恐らく七割くらいは見分けられると思います。
    検出対象の「人と自転車の見た目」はそれほど変わらないので、手動でアノテーションしていけばもっと制度は上がると思います。

    キャンセル

  • 2019/11/11 23:10

    実際の検証はできていませんが、アプローチ方法がわかりましたのでベストアンサーとさせていただきます。

    キャンセル

0

アイディアを適当に羅列してみます。(記載順に意味はありません。)

  • テロップとか不要な部分はマスキングしてから処理をする
  • まずは2値化して形状を検出してから色判定する
  • 楕円を検出して自転車の位置を当たり付ける(横からの画像が多くないと出来ない)
  • トラック(コース)を検出してからその領域内だけを選手検出対象にする

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/11/09 21:19 編集

    ご回答ありがとうございます。
    コースのどの部分を走っているかを知る必要があり、トラックの検出は別途行ないました。
    色による単純な二値化しか試していなかったので適応的しきい値処理を試そうと思います。

    キャンセル

  • 2019/11/09 21:33

    おもしろい題材なんでぜひ頑張ってみて下さい!

    キャンセル

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

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

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