스플래툰 동영상을 분석해 보았습니다.
스플래툰 동영상 분석 해 보았습니다.
스플래툰의 관전 동영상에서 플레이어의 위치 정보를 해석해 보았습니다.
전 재료는, 홋카이도 고시엔(?)의 오징어 자랑 콘테스트로 유명 팀의 해석을 실시하고 싶었고, 흥미가 있었으므로 자신도 해 보았습니다.
분석 결과
INPUT은 관전 시점의 동영상.
OUTPUT은 각 플레이어의 위치 정보 분포입니다.
예를 들어 한 경기의 네 명의 위치 정보는 다음과 같습니다.
슈터 쪽이 스테이지를 골고루 움직이고 있는 것을 알 수 있군요-.
■리터
■스퍼터리
■프라임
■스퀴크
분석 방법
이런 느낌입니다
① 관전 동영상을 찍는다(수수하게 허들 높다. 설명은 할애)
②동영상을 흑백 변환
③ 흑백 변환된 동영상에서 각 플레이어 이름의 이미지를 추출
④openCV의 패턴 매칭으로 위치 정보 취득
⑤④에서 취득한 위치정보의 주변도 적당히 가중하여 위치정보를 화상으로 출력
⑥스테이지 화상을 ⑤의 화상을 합성
해석 방법의 상세
① 관전 동영상을 찍다
캡처 보드를 샀습니다.
배달자 찾아 풀어 섞어 주었습니다.
②동영상을 흑백 변환
그레이스케일로 변환하여 220을 임계값으로 하여 흑백 변환하였다.
소스 분위기만 쓰면 이하. 보다 편리한 방법 있는 생각도 하지만.
color2gray.py# 閾値の設定
threshold = 220
fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') # ファイル形式(ここではmp4)
#グレースケールの場合は、ライターの最後の引数をFalseにする(カラーの場合はTrueか省略)
out = cv2.VideoWriter('./video/g_area_1_gray_2.mp4', fmt, frame_rate, (width,height),False) # ライター作成
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
#グレースケール化
gray_cv = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
# 二値化(閾値thresholdを超えた画素を255にする。)
ret, img_thresh = cv2.threshold(gray_cv, threshold, 255, cv2.THRESH_BINARY)
# write the flipped frame
out.write(img_thresh) #output.aviにframe毎書込み
cv2.imshow('gray_cv',img_thresh) #グレースケールframeを表示
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
③ 흑백 변환된 동영상에서 각 플레이어 이름의 이미지를 추출
여기는 수작업. . .
일단 화상 잘라내기 위한 소스는 이하.
cutImage.pyimport cv2
playerImg = cv2.imread('./XXX.jpg')
playerImg = playerImg[0:30, 80:150]#ここで切り取る箇所指定
cv2.imwrite('./YYY.jpg', playerImg)
cv2.imshow('playerImg',playerImg)
cv2.waitKey(0)
cv2.destroyAllWindows()
④openCV의 패턴 매칭으로 위치 정보 취득
openCV에서 패턴 매칭.
1프레임마다 위치 정보가 튜플로 반환되므로 리스트에 보관.
매칭에는 몇가지 알고리즘이 있는 것 같고, 어느 것이 좋은가는 잘 모르겠습니다. 비교하는 것도 귀찮아서 적당히 선택했다.
소스는 분위기 이하.
getLocation.py###読み込む動画(②で白黒変換した動画)###
cap = cv2.VideoCapture('./grayMovie.mp4')
###テンプレート画像(#③で切り取ったプレイヤー名の画像)###
template = cv2.imread('./XXX.jpg',0)
###パターンマッチングのアルゴリズム###
method = cv2.TM_CCOEFF
#位置情報のリスト
player1_locations = []
###パターンマッチング###
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
# Apply template Matching
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(frame,template,method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
center = ((top_left[0]+bottom_right[0])//2,(top_left[1]+bottom_right[1])//2)
player1_locations.append(center)
⑤④에서 취득한 위치정보의 주변도 적당히 가중하여 위치정보를 화상으로 출력
취득한 위치 정보만을 화상에 맵핑하면 정말 미묘한 외형이 되기 때문에, “빛나”하기 위해 했습니다.
작성된 2차원 배열에서 수치가 큰 곳일수록 오랫동안 거주하게 됩니다.
소스 할애하지만, 수치가 클수록 색을 진하게 하고, 플레이어의 위치 정보를 화상으로 합니다.
makeLocationImg.py#player1のmap上の統計情報を2次元配列で定義
player1_location_statistics_around = np.array([[0] * (width) for i in range(height)], dtype=float)
#player1のmap上の統計情報を計算
for x,y in player1_locations:
x=int(x)
y=int(y)
player1_location_statistics_around[y:y+50,x-50:x+50] += 1
player1_location_statistics_around[y:y+30,x-30:x+30] += 1
player1_location_statistics_around[y:y+20,x-20:x+20] += 2
player1_location_statistics_around[y:y+10,x-10:x+10] += 3
player1_location_statistics_around[y:y+5,x-5:x+5] += 5
⑥스테이지 화상을 ⑤의 화상을 합성
스테이지 이미지와 ⑤ 플레이어의 위치 정보 이미지를 합성하여 완성🎊
gosei.pyimport cv2
stageImg = cv2.imread('./stage_pic/hujiSport.jpg')
player1LocationImg = cv2.imread('./XXX.png')
dst = cv2.addWeighted(stageImg, 1.0, player1LocationImg, 1.0, 0)
cv2.imwrite('./result.jpg', dst)
cv2.imshow('location',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
끝에
스플래툰을 좋아해서 즐겁게 구현할 수 있었습니다.
오인식해 버리는 곳도 있어 완벽하지는 않지만, 상당히 간편하게 가시화할 수 있어 openCV의 패턴 매칭 굉장히 되어 있지요.
보다 좋은 실장(정밀도 높다든가, 화상 빛나는 아이디어라든지) 있으면 가르쳐 주었으면 합니다.
읽어 주셔서 감사합니다.
Reference
이 문제에 관하여(스플래툰 동영상을 분석해 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kumapower1115/items/889c9f77b8b5f6907a56
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# 閾値の設定
threshold = 220
fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') # ファイル形式(ここではmp4)
#グレースケールの場合は、ライターの最後の引数をFalseにする(カラーの場合はTrueか省略)
out = cv2.VideoWriter('./video/g_area_1_gray_2.mp4', fmt, frame_rate, (width,height),False) # ライター作成
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
#グレースケール化
gray_cv = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
# 二値化(閾値thresholdを超えた画素を255にする。)
ret, img_thresh = cv2.threshold(gray_cv, threshold, 255, cv2.THRESH_BINARY)
# write the flipped frame
out.write(img_thresh) #output.aviにframe毎書込み
cv2.imshow('gray_cv',img_thresh) #グレースケールframeを表示
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
import cv2
playerImg = cv2.imread('./XXX.jpg')
playerImg = playerImg[0:30, 80:150]#ここで切り取る箇所指定
cv2.imwrite('./YYY.jpg', playerImg)
cv2.imshow('playerImg',playerImg)
cv2.waitKey(0)
cv2.destroyAllWindows()
###読み込む動画(②で白黒変換した動画)###
cap = cv2.VideoCapture('./grayMovie.mp4')
###テンプレート画像(#③で切り取ったプレイヤー名の画像)###
template = cv2.imread('./XXX.jpg',0)
###パターンマッチングのアルゴリズム###
method = cv2.TM_CCOEFF
#位置情報のリスト
player1_locations = []
###パターンマッチング###
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
# Apply template Matching
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(frame,template,method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
center = ((top_left[0]+bottom_right[0])//2,(top_left[1]+bottom_right[1])//2)
player1_locations.append(center)
#player1のmap上の統計情報を2次元配列で定義
player1_location_statistics_around = np.array([[0] * (width) for i in range(height)], dtype=float)
#player1のmap上の統計情報を計算
for x,y in player1_locations:
x=int(x)
y=int(y)
player1_location_statistics_around[y:y+50,x-50:x+50] += 1
player1_location_statistics_around[y:y+30,x-30:x+30] += 1
player1_location_statistics_around[y:y+20,x-20:x+20] += 2
player1_location_statistics_around[y:y+10,x-10:x+10] += 3
player1_location_statistics_around[y:y+5,x-5:x+5] += 5
import cv2
stageImg = cv2.imread('./stage_pic/hujiSport.jpg')
player1LocationImg = cv2.imread('./XXX.png')
dst = cv2.addWeighted(stageImg, 1.0, player1LocationImg, 1.0, 0)
cv2.imwrite('./result.jpg', dst)
cv2.imshow('location',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
스플래툰을 좋아해서 즐겁게 구현할 수 있었습니다.
오인식해 버리는 곳도 있어 완벽하지는 않지만, 상당히 간편하게 가시화할 수 있어 openCV의 패턴 매칭 굉장히 되어 있지요.
보다 좋은 실장(정밀도 높다든가, 화상 빛나는 아이디어라든지) 있으면 가르쳐 주었으면 합니다.
읽어 주셔서 감사합니다.
Reference
이 문제에 관하여(스플래툰 동영상을 분석해 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kumapower1115/items/889c9f77b8b5f6907a56텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)