本サイトは広告・プロモーションが含まれています
プログラミング実践

【Python】OpenCVを使って動画に映る人の上に別の画像を貼る【フリーランス案件】

この記事はこんな人におすすめ

・PythonのライブラリOpenCVの参考になるコードをさがしている
・Pythonのフリーランスの仕事がどんなものがあるのか知りたい方
・実際フリーランスの依頼された仕事が、どれくらいの時間がかかるのか知りたい方
・ど

どうもこんには。
最近は雑用仕事から工事手配に仕事が変わりつつあるコンです。
プログラミングの時間どんどん減ってきているなぁ。。。

今日は、フリーランス案件を紹介しているサイトから
Pythonを使った仕事の案件を見つけだし
最近プログラミングできてないので、トライしてみたいと思います。

コン
コン
プログラミングを使った仕事をしたいんじゃい!!

見つけてきた案件はこちら

【案件】
OpenCVを使用し、動画内の人を認知し,別画像を組み込むプログラム作成(Python)
【報酬】
1万円

正直openCVは正直あんまりやってないですけど
とりあえずやってみます!

作業

動画の選定

Pz-LinkCard
– URLの記述に誤りがあります。
– URL=

OpenCVのGitHubにこの動画がありましたので
今回はこの動画に写っている人を検出していきます。

手法の選定

今回はOpenCV のカスケード分類器 CascadeClassifier を使用して、人の体を検出する方法を使用しました。

実は初めて知った手法なので、全然詳しくありません(笑)。


調べてみると
大量の画像からある物体の特徴を学習し、この特徴をまとめたデータのことを「カスケード分類器」呼ぶらしいです。

この分類器の人の体全体を検出してくれるバージョンを使えば
動画から人を検出してくれるらしい!!

ということで採用(笑)

このような検出手法には
手法によって独特な検出パラメータのチューニングだったりが精度に関わる部分があるのですが。。。
今回は省略省略!!

Pythonコードを書く

上のサンプル動画に写っている人を検出し、体の位置に画像をつけるコードを書いていきます。
ついでに、何人検出しているかも表示してみます。

import numpy as np
import cv2
import time

# 体全体のカスケードファイル(パスはカスケード分類器のxmlファイルを指定)
fullbody_detector = cv2.CascadeClassifier("/Users/hts/Documents/python_work/work1/haarcascade_fullbody.xml")
# サンプル動画
cap = cv2.VideoCapture('sample.avi')
# 人の上に表示する画像
mark = cv2.imread('mark.png')
height, width = mark.shape[:2]

# Shi-Tomasiのコーナー検出パラメータ
feature_params = dict( maxCorners = 10,
                       qualityLevel = 0.1,
                       minDistance = 1,
                       blockSize =  7)

# Lucas-Kanade法のパラメータ
lk_params = dict( winSize  = (10,10),
                  maxLevel = 2,
                  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

# 画像保存用


# 最初のフレームの処理
end_flag, frame = cap.read()
# グレースケール変換
gray_prev = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#動画サイズ取得
width_org = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height_org = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
#フレームレート取得
fps = cap.get(cv2.CAP_PROP_FPS)

#フォーマット指定
fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
#注)グレースケールの画像を出力する場合は第5引数に0を与える
writer = cv2.VideoWriter('output.mp4', fmt, fps, (width_org, height_org))
writer_2 = cv2.VideoWriter('origin.mp4', fmt, fps, (width_org, height_org))
# 元の配列と同じ形にして0を代入
mask = np.zeros_like(frame)

while(end_flag):
    # グレースケールに変換
    writer_2.write(frame)
    gray_next = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    start = time.time()  
    # 全身の人を検出 
    # minSize:物体が取り得る最小サイズ。これよりも小さい物体は無視される
    # minNeighbors:物体候補となる矩形は,最低でもこの数だけの近傍矩形を含む
    body = fullbody_detector.detectMultiScale(gray_next,scaleFactor=1.1, minNeighbors=3, minSize=(40, 40))
    end = time.time()  
    # 検出時間を表示  
    print("{} : {:4.1f}ms".format("detectTime", (end - start) * 1000))

   
    
    # 人検出した数表示のため変数初期化
    human_cnt = 0
    # 人検出した部分を長方形で囲う
   
    
    for (x, y, w, h) in body:
        cv2.rectangle(frame, (x, y),(x+w, y+h),(0,255,0),2)
        frame[y+30:y+30+height, x:x+height]=mark
        # 人検出した数を加算
        human_cnt += 1
        

    # 人検出した数を表示
    cv2.putText(frame, "Human Cnt:{}".format(int(human_cnt)),(10,550), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1, cv2.LINE_AA)
    # ウィンドウに表示
    cv2.imshow('plant_programer', frame)
    writer.write(frame)
    

   # ESCキー
    k = cv2.waitKey(1)
    if k == 27:
        break

    # 次のフレーム、ポイントの準備
    gray_prev = gray_next.copy()
    end_flag, frame = cap.read()

# 終了処理
writer.release()
cv2.destroyAllWindows()
cap.release()

ネットでコードを見つけそのまま使いました

完成した動画

上のコードを走らせた結果が以下になります。

かかった時間

1. 動画の選定:1時間
2. 手法の選定:1時間
3. コード書く:2時間

くらいの時間をかけて作成しました。
コードに時間がかかったのは、numpyの座標とopenCVの座標の違いに
久しぶりで戸惑ってしまいました。

案件が1万円だから、時給2500円くらい??
でも実際仕事で受け持つと、もうちょっと下調べを行い、2倍は時間をかけるので
8時間くらいはかけると思うので。。。

1日1万円のアルバイトくらい(笑)
試験監督アルバイトかな??( ; ; )

振り返り

動画を見ていただいた人には、ツッコミを入れてもらったかもしれないのですが。。。

変な画像を動画につけてしまい、申し訳ございません!!!

小学生のノリが30前にもなって抜け切らずにおります_| ̄|○

ペン太郎
ペン太郎
本当にヤバい人

動画の内容の話をすると
とりあえずカスケード分類器で適当なパラメーター使用しました。

そうすると下の写真のように人を検出。


街頭の影に隠れている人以外は検出できている!!

と思いきや

う〜ん。。。
右の男性の精度があんまりかな。。。

街灯の近くにいる人たちも検出できていないな。。。。

動画も全体的に、あまり良い精度ではなかった気がします。

もっといい精度だせとクライアント側から要求があれば
もちろんパラメータ調整も行うかもしれませんが

SSDであったり、OpenCVとは別のAIの手法を提案するかもしれません。



COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA