Program/딥러닝

[Open CV] 딥러닝활용 _ OpenPose 포즈 인식

사막여유 2022. 7. 31. 21:44
728x90

 

사람의 포즈 또는 자세를 인식할 때 사용되고있는 Open Pose라는 딥러닝 알고리즘을 OpenCV에서 실행하는 방법에
대해서 알아본다.

 

OpenPose란?

 - 카네기 멜론 대학에서 만든 딥러닝 기반 동작 인식 라이브러리 ( CVPR , 2017 )

 - OpenPose represents the first real-time multi-person system to jointly detect human body, hand, facial, and foot keypoints ( 관절 ) ( in toal 135 keypoints ) on single images.

 - Caffe, OpenCV, C++

 - GitHub - CMU-Perceptual-Computing-Lab/openpose: OpenPose: Real-time multi-person keypoint detection library for body, face, hands, and foot estimation

 - 위 링크에서 OpenPose에 대한 자세한 설명을 볼 수 있다.

 

OpenPose 네트워크 구조

 - F : Feature map

 - L : Set of 2D vector fileds of part affinity ( limb )

 - S : Set of 2D confidence maps of body part locations ( elbow, kneel, etc. )

 

앞부분에서는 인식에 관한 VGG19 알고리즘을 사용하고있고 이후 Feature map 이 나오게되고

L이라는 관절과 관절사이의 관계를 표현하는 2D vector Limb값이 나오고

마지막으로 S라는 실제 관절의 Point 값을 받아오게 된다.

그래서 위 네트워크는 관절의 Point (S) 와 관절사이의 관계를 나타내는 (L) 값이 히트맵이라는 형태로 Output으로 나온다.

따라서 내가 찾고자하는 관절을 히트맵에서 찾아서 사용하는 형태로 동작될 수 있다.

 

OpenPose 학습 데이터셋 : COCO ( 18 parts )

 

 

OpenPose ( COCO, 18 parts ) 모델 & 설정 파일 다운로드

 -  일단 GitHub - CMU-Perceptual-Computing-Lab/openpose: OpenPose: Real-time multi-person keypoint detection library for body, face, hands, and foot estimation 링크에서 openpose 전체 Zip 파일을 다운로드 받고 
models 폴더에서 getModels.bat 파일실행 또는 아래 모델파일 링크로 다운로드

 - 모델파일 : http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/coco/pose_iter_440000.caffemodel

 - 설정 파일 : https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/models/pose/coco/pose_deploy_linevec.prototxt

 - 다운로드 받은 파일을 실행폴더에 복사

 - MPI, Face, Hand 등의 모델은 GitHub - CMU-Perceptual-Computing-Lab/openpose: OpenPose: Real-time multi-person keypoint detection library for body, face, hands, and foot estimation에서 getModels.bat 파일 참고

 

OpenPose 입력 

 - Size : ( 368, 368 )

 - Scale : 0.00392 ( 1/255. )

 - Mean : [ 0, 0, 0 ]

 - RGB : false

위 Mean과 RGB값은 Default값으로 안줘도 되는 값

 

OpenPose 출력 ( COCO )

 - out.shape = (1, 57, 46, 46)

 - 57 = 18 keypoint confidence Maps
        + 1 background
        + 19*2 Part Affinity Maps

출력은 위에서 보다싶이 복잡하게 출력되기 때문에 후처리가 많이 들어가야한다.

네트워크 함수에서 forward를 호출하게되면 out으로 주는 ndarray가 ( 1,57,46,46 )값으로 나오는데 
여기서 나오는 46x46은 Heat Map형태의 영상을 뜻하고 57은 Heat Map 개수를 뜻한다.

그럼 여기서 나오는 57에서 앞 18개는 Confidence Map ( Heat Map ) 을 의미하고 관절점의 가장 그럴듯한 위치를 나타낸다.

 

위 이미지처럼 18개의 각각의 관절에 가장 가까운 부분을 float 의 행렬 형태로 반환해준다. ( 18개 행렬 값 )

그리고 1개의 background는 제외하고 남은 19*2 Part Affinity Maps라는 관절과 관절사이의 2D Vector 형태의 값을

반환해준다. 그래서 해당 벡터값을 잘 활용하게 되면 여러사람이 있다고해도 잘 구분할 수 있게 된다.

그런데 이렇게까지 들어가면 후처리코드가 굉장히 복잡해지기 때문에 예제 코드에서는 사람이 한명만 있다고 가정하고

코드를 작성하셨다고 한다.

그래서 background와 19*2 Parts Affinity Maps의 값은 사용하지 않는다.

 


코드리뷰

 

전체 관절의 개수는 18이니 관절과 관절을 잇는 선의 개수는 17로 설정해준다.

그리고 각각의 관절을 어떻게 이을것인지에 대한 정보를 pose_pair의 행렬로 정리해준다.

이후 코드는 위에서 설명하였음.

 

그래서 결론은 블롭 생성 & 추론부분에서 네트워크를 생성하는 부분은 끝이 난것이고

남은 뒷부분에서는 결과를 그려주는 코드인 것이다.

728x90