在Windows上编译OpenPose Python Wrapper

由于一些原因,我现在需要在Windows上同样运行OpenPose。虽然OpenPose提供了Windows版的二进制可执行文件,但并没有提供二进制的Python Wrapper,想要使用Python Wrapper还是必须要自行编译。此文主要介绍在Windows上编译OpenPose及其Python Wrapper的过程。

有关于OpenPose安装过程的具体分析,请参阅我之前写的文章:在Ubuntu 18.04LTS上部署OpenPose+CUDA+CuDNN

由于Windows平台的特点,大部分第三方库都是以二进制的格式发布的,这无疑给我们带来了很大的便利。首先,请下载并安装下列的工具:

  • NVIDIA显卡驱动,这个一般的电脑都是已经装好的,如果没装到官网下载安装一个即可。
  • CUDA 10.0:官网链接,操作系统根据实际情况选择合适的Windows版本即可,这里主要是使用它的编译器nvcc。(NVIDIA官网有国内CDN,无需使用代理即可满速)
  • cuDNN 不需要下载,具体原因后文会提。
  • CMake  官网链接,选择最新Windows版即可。(速度较慢,可在文末网盘下载)
  • Visual Studio:官网链接,我使用的是2017的,现在好像只能下载2019版本,应该也没有什么问题。

准备好上述工具之后,接下来我们需要到GitHub下载OpenPose的源代码。下载的时候,需要注意使用递归下载,以便下载pybind11包,我已经下载好的源代码可以在文末连接中找到,与Linux下是相同的。此处我将其解压到D:\openpose,之后的操作均以此为基础。 在使用CMake配置之前,由于网络原因,我们需要手动下载一些二进制包,并手动复制并解压到源代码目录中,否则下载将超时退出,导致配置失败。下载文末网盘链接中的caffe_15_2019_05_16.zipopencv_411_v14_15_2019_09_24.zipcaffe3rdparty_15_2019_03_14.zip三个文件(这三个文件与我提供的源代码包相对应,时效截止文章完成之时,不排除未来更新的可能),并将其复制到D:\openpose\3rdparty\windows中,然后将三个压缩包均解压到当前文件夹,并保留原始文件(防止重新下载)。该文件夹下的文件结构如下图所示。

https://img.yuanze.wang/posts/build-openpose-python-api/screenshot1.jpg
文件结构

值得一提的是,在官方提供的caffe二进制包内,包含了CUDA和cuDNN的动态库,因此我们无需再另外下载cuDNN,所安装的CUDA只是提供了一个编译器。 接下来同样为了避免下载,我们删除D:\openpose\models文件夹,并下载文末网盘链接中的models文件夹,复制到原处。到此为止,我们已经完成了所有准备工作。 打开CMake,设置源代码位置为D:\openpose,并新建D:\openpose\build文件夹,用作编译文件夹。接下来,点击Configure按钮,选择你安装的VS版本,并选择平台为x64,点击Finish即可。

https://img.yuanze.wang/posts/build-openpose-python-api/screenshot2.jpg
CMake配置

不出意外的话,CMake会在最下面显示Configuring done,这时我们勾选上方变量中的BUILD_PYTHON(请确保已经安装了64位Python),如果不需要演示程序的话也可以取消勾选BUILD_EXAMPLES,之后再点击一次Configure按钮。不出意外的话,配置应该也是成功的。我们可以检查一下CUDA_TOOLKIT_ROOT_DIRCaffe_INCLUDE_DIRSCaffe_LIBCaffe_Proto_LIBOpenCV_LIBS中有没有NOTFOUND字样,没有的话说明我们的依赖二进制文件也没有问题。

https://img.yuanze.wang/posts/build-openpose-python-api/screenshot3.jpg
CMake配置

我们点击Genetate按钮,生成VS工程文件,并点击Open Project来打开工程,并在上方Target中选择Release

https://img.yuanze.wang/posts/build-openpose-python-api/screenshot4.jpg
Visual Studio工程

从上图中,我们可以在左侧看到整个解决方案中的所有项目。我们需要的是OpenPose Library中的openpose的OpenPose动态链接库以及pyopenpose的Python API这两个项目,只需要直接右键点击pyopenpose项目,点击生成即可。生成过程中,将会报非常多的warning,它们是因为中文编码与英文不兼容导致的,可以不去管它们。看到生成成功的提示后,我们可以在D:\openpose\build\python\openpose\Release目录中找到pyopenpose.cp37-win_amd64.pyd,此文件即为OpenPose的Python Wrapper(文件名根据python版本不同可能不同)。 我们新建一个名字为openpose的文件夹,将D:\openpose\build\python\openpose\Release\pyopenpose.cp37-win_amd64.pyd文件及D:\openpose\build\python\openpose\__init__.py文件复制进去。然后,将D:\openpose\build\bin中的所有文件也复制进openpose文件夹,最后将D:\openpose\build\x64\Release\openpose.dll复制进文件夹,这个openpose便是可以被我们本机对应版本Python调用的OpenPose库了。文件夹结构如下图所示。

https://img.yuanze.wang/posts/build-openpose-python-api/screenshot5.jpg
OpenPose文件夹结构

我们将D:\openpose\models文件夹复制到此文件夹里,并新建下面的文件,保存为openpose_demo.py保存在上一级目录,运行此文件即可演示Python对OpenPose API的调用。

import cv2
import sys
import timeit
import openpose.pyopenpose as op

params = dict()
params["model_folder"] = 'openpose\\models'
params["net_resolution"] = '128x192'
params["render_pose"] = '1'

opWrapper = op.WrapperPython()
opWrapper.configure(params)
opWrapper.start()

cap = cv2.VideoCapture(0)
print('Video device Initialized.')

frame_start_time = timeit.default_timer()
frame_cnt = 0

while True:  # Process Image
   datum = op.Datum()
   ret, img = cap.read()  # Read camera
   imageToProcess = img
   datum.cvInputData = imageToProcess
   opWrapper.emplaceAndPop([datum])

   # print("Body keypoints: \\n" + str(datum.poseKeypoints))
   cv2.imshow("Openpose Python - Press Q to Exit", datum.cvOutputData)

   frame_end_time = timeit.default_timer()
   if frame_end_time - frame_start_time > 1:
      print('fps:{}'.format(frame_cnt))
      frame_cnt = 0
      frame_start_time = frame_end_time

   frame_cnt = frame_cnt + 1

   if cv2.waitKey(1) & 0xFF == ord('q'):
      break

cap.release()
cv2.destroyAllWindows()
exit(0)

 百度云下载 提取码:d2he