# From Python # It requires OpenCV installed for Python import sys import cv2 import os from sys import platform import argparse# 导入argparse模块,用于解析命令行参数 try: # Import Openpose (Windows/Ubuntu/OSX) # 获取当前脚本文件的目录路径 dir_path = os.path.dirname(os.path.realpath(__file__)) try: # 检查操作系统类型 # Windows Import # 对于Windows系统 if platform == "win32": # 修改这些变量以指向正确的文件夹(如Release/x64等) # 使用 os.path.join 来避免路径分隔符的问题 openpose_path = os.path.join(dir_path, '../../python/openpose/Release') sys.path.append(openpose_path) #sys.path.append(dir_path + '/../../python/openpose/Release'); #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;' # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件 # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件 # 使用 os.pathsep 来确保路径分隔符的正确性 os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \ + os.pathsep + os.path.join(dir_path, '../../bin') # 导入OpenPose的Python接口 import pyopenpose as op else: # 对于Linux或MacOS系统 # 修改这些变量以指向正确的文件夹(如Release/x64等) # 这里假设OpenPose的Python库位于相对于脚本的固定路径下 sys.path.append('../../python') # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it. # sys.path.append('/usr/local/python') # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块 # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径 # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径 # sys.path.append('/usr/local/python') # 从openpose模块导入pyopenpose from openpose import pyopenpose as op except ImportError as e: # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常 print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?') # 打印原始异常信息 print(e) # 重新抛出异常,以便调用者可以处理它 raise e # Flags # 创建一个ArgumentParser对象,用于处理命令行参数 parser = argparse.ArgumentParser() # 添加一个命令行参数 --image_path,它有一个默认值,用于指定要处理的图像文件路径 # 这个参数接受所有标准的图像格式(如jpg, png, bmp等) parser.add_argument("--image_path", default="../../../examples/media/COCO_val2014_000000000192.jpg", help="Process an image. Read all standard formats (jpg, png, bmp, etc.).") # 解析命令行参数,并获取已知的参数和未知参数(如果有的话) # parse_known_args()方法返回两个值:一个是已知参数的Namespace对象,另一个是未知参数的列表 args = parser.parse_known_args() # 创建一个字典params,用于存储自定义参数 # 这些参数通常用于配置OpenPose的行为,但不在默认的命令行参数中 params = dict() # 设置一个自定义参数model_folder,指定OpenPose模型文件的存储路径 params["model_folder"] = "../../../models/" # 遍历args[1](未知参数的列表),以处理可能通过命令行传递的额外自定义参数 # 注意:args[0]是Namespace对象,包含已知参数;args[1]是未知参数的列表 for i in range(0, len(args[1])): curr_item = args[1][i] # 当前项 # 检查是否还有下一个项,并设置next_item的值 # 如果当前项是列表中的最后一个项,则假设下一个项为"1"(这里可能是一个简化的处理方式) if i != len(args[1]) - 1: next_item = args[1][i + 1] else: next_item = "1" # 检查当前项和下一个项是否都以"--"开头,这通常意味着它们都是命令行参数(但这里逻辑可能不完全准确) # 如果两个都是参数,则忽略它们,因为这里的逻辑可能不适用于处理真正的命令行参数 # 注意:这里的逻辑可能是一个错误或简化的处理方式,因为通常不会这样检查参数 if "--" in curr_item and "--" in next_item: key = curr_item.replace('-', '') # 移除参数名中的'-'并作为字典的键 if key not in params: # 如果该键不在params字典中,则添加它,并赋值为"1"(这可能不是预期的行为) params[key] = "1" # 如果当前项以"--"开头但下一个项不是,则假设当前项是一个参数,而下一个项是该参数的值 elif "--" in curr_item and "--" not in next_item: key = curr_item.replace('-', '') # 同样移除'-' if key not in params: # 如果该键不在params字典中,则添加它,并将next_item作为值 params[key] = next_item # Construct it from system arguments # op.init_argv(args[1]) # oppython = op.OpenposePython() # Starting OpenPose # 初始化OpenPose的WrapperPython对象 # WrapperPython是OpenPose提供的Python接口的主要类,用于封装OpenPose的功能 opWrapper = op.WrapperPython() # 使用自定义参数配置OpenPose # params是一个字典,包含了OpenPose运行所需的配置参数 # 这些参数可以影响OpenPose的性能、输出等 opWrapper.configure(params) # 启动OpenPose # 在配置完成后,需要调用start方法来初始化OpenPose的内部结构 opWrapper.start() # 处理图像 # 创建一个Datum对象,Datum是OpenPose用于存储输入和输出数据的类 datum = op.Datum() # 使用OpenCV读取图像 #args是一个元组且args[0]是Namespace对象,则应该是args[0].image_path imageToProcess = cv2.imread(args[0].image_path) # 将读取的图像设置为Datum对象的输入数据 datum.cvInputData = imageToProcess # 调用emplaceAndPop方法处理图像 # 这个方法将Datum对象(包含输入图像)放入OpenPose的处理队列中,并等待处理结果 # 处理完成后,结果会被放入Datum对象的输出字段中 # 注意:这里传递了一个包含datum的VectorDatum对象,因为emplaceAndPop方法期望接收一个VectorDatum作为参数 opWrapper.emplaceAndPop(op.VectorDatum([datum])) # 显示处理结果 # 打印出图像中的人体关键点信息 # poseKeypoints是一个包含关键点信息的列表或数组 print("Body keypoints: \n" + str(datum.poseKeypoints)) # 使用OpenCV显示处理后的图像 # cvOutputData是Datum对象中包含的处理后图像数据 cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", datum.cvOutputData) # 等待用户按键后关闭窗口 cv2.waitKey(0) except Exception as e: print(e) sys.exit(-1)