반응형
OpenPose를 활용한 이미지 속 인물들의 뼈대(skeleton)를 검출해보겠습니다. 테스트 전 필요한 모델 파일은 하단 링크를 참조하여 다운로드하면 되겠습니다.
https://prlabhotelshoe.tistory.com/25?category=1005609
이번 테스트에 필요한 파일인 pose_deploy_linevec_faster_4_stages.prototxt 파일은 다운받은 openpose 폴더의 openpose-master -> models -> pose -> mpi 의 경로에 위치해 있습니다.
추가적으로 필요한 pose_iter_160000.caffemodel 파일의 경우 하단 링크를 통해 직접 내려받을 수 있습니다.
http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/mpi/pose_iter_160000.caffemodel
소스코드
import cv2
#-- 파츠명 선언
BODY_PARTS = { "Head": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
"LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
"RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "Chest": 14,
"Background": 15 }
POSE_PAIRS = [ ["Head", "Neck"], ["Neck", "RShoulder"], ["RShoulder", "RElbow"],
["RElbow", "RWrist"], ["Neck", "LShoulder"], ["LShoulder", "LElbow"],
["LElbow", "LWrist"], ["Neck", "Chest"], ["Chest", "RHip"], ["RHip", "RKnee"],
["RKnee", "RAnkle"], ["Chest", "LHip"], ["LHip", "LKnee"], ["LKnee", "LAnkle"] ]
#-- 모델 파일 불러오기
protoFile = "./pose_deploy_linevec_faster_4_stages.prototxt" #-- 자신의 환경에 맞게 경로 변경할 것
weightsFile = "./pose_iter_160000.caffemodel" #-- 자신의 환경에 맞게 경로 변경할 것
#-- network 불러오기
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
#-- 이미지 불러오기
image = cv2.imread("./img.jpg")
imageHeight, imageWidth, _ = image.shape #-- 불러온 이미지에서 height, width, color를 가져옴
inpBlob = cv2.dnn.blobFromImage(image, 1.0 / 255, (imageWidth, imageHeight), (0, 0, 0), swapRB=False, crop=False) #-- network에 적용하기 위한 전처리
net.setInput(inpBlob)
output = net.forward()
H = output.shape[2]
W = output.shape[3]
#-- 검출된 키포인트 적용
points = []
for i in range(0,15):
probMap = output[0, i, :, :]
minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
#-- 원본 이미지에 맞도록 포인트 위치 적용
x = (imageWidth * point[0]) / W
y = (imageHeight * point[1]) / H
#-- 검출된 포인트가 BODY_PARRTS와 대응되면 포인트 추가(검출 결과가 0.1보다 크면) / 검출했으나 해당 파츠가 없는 경우 None
if prob > 0.1 :
cv2.circle(image, (int(x), int(y)), 3, (0, 255, 255), thickness=-1, lineType=cv2.FILLED) #-- circle(이미지, 원의 중심, 반지름, 컬러)
cv2.putText(image, "{}".format(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, lineType=cv2.LINE_AA)
points.append((int(x), int(y)))
else :
points.append(None)
#-- 생성된 POSE_PAIRS에 맞게 라인 생성
for pair in POSE_PAIRS:
partA = pair[0] #-- 머리
partA = BODY_PARTS[partA]
partB = pair[1] #-- 목
partB = BODY_PARTS[partB]
if points[partA] and points[partB]:
cv2.line(image, points[partA], points[partB], (0, 255, 0), 2)
cv2.imshow("OpenPoseImgTest",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
테스트
출력 결과
이미지 속 한 명의 인물에 대해선 대체적으로 검출이 잘 되는 모습이다. (머리카락 끝을 오른쪽 팔꿈치로 인식한 오류가 있다..)
여려명에 대해서의 출력 결과
아무래도 한 명에 대해서만 검출이 가능하여 인물이 여려명일 경우 인식이 제대로 이루어지지 않는 점을 볼 수 있다.
반응형
'Python > OpenPose' 카테고리의 다른 글
[OpenPose] 영상 인물 뼈대(skeleton) 검출 (2) | 2022.02.23 |
---|---|
[OpenPose] 영상 손가락 마디&관절 인식 (2) | 2022.02.19 |
댓글