・PythonのライブラリOpenCVの参考になるコードをさがしている
・Pythonのフリーランスの仕事がどんなものがあるのか知りたい方
・実際フリーランスの依頼された仕事が、どれくらいの時間がかかるのか知りたい方
・ど
どうもこんには。
最近は雑用仕事から工事手配に仕事が変わりつつあるコンです。
プログラミングの時間どんどん減ってきているなぁ。。。
今日は、フリーランス案件を紹介しているサイトから
Pythonを使った仕事の案件を見つけだし
最近プログラミングできてないので、トライしてみたいと思います。
見つけてきた案件はこちら
【案件】
OpenCVを使用し、動画内の人を認知し,別画像を組み込むプログラム作成(Python)
【報酬】
1万円
正直openCVは正直あんまりやってないですけど
とりあえずやってみます!
作業
動画の選定
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の手法を提案するかもしれません。