C++程序中使用openpose预测关节点坐标的简易实现

2023-11-20

C++程序中使用openpose预测关节点坐标的简易实现

虽然在openpose的官网上已经给出了很多可用的demo,但是如果我们在自己的C++项目中想要使用openpose来预测三维关键点官网给出的例子不是很适用,所以我现在给出了C++程序中使用openpose预测关节点坐标的简易实现,包括CMakeLists.txt的书写.
当然我的程序还是要求先配置好openpose和opencv
这里有一篇很好的博客对于如何使用openpose官方demo做了非常详细的介绍,是使用openpose官方demo非常好的工具:OpenPose命令行参数记录

(1)预测关节点坐标的简单封装op.h

#ifndef CAFFETEST_OP_H
#define CAFFETEST_OP_H
#include "caffe/caffe.hpp"
 //OpenPose dependencies
#include <openpose/core/headers.hpp>
#include <openpose/filestream/headers.hpp>
#include <openpose/gui/headers.hpp>
#include <openpose/pose/headers.hpp>
#include <openpose/utilities/headers.hpp>
using namespace std;
#define FLAGS_logging_level 3
#define FLAGS_output_resolution "-1x-1"
#define FLAGS_net_resolution "-1x368"
#define FLAGS_model_pose "BODY_25"
#define FLAGS_alpha_pose 0.6
#define FLAGS_scale_gap 0.3
#define FLAGS_scale_number 1
#define FLAGS_render_threshold 0.05
#define FLAGS_num_gpu_start 0
#define FLAGS_disable_blending false
#define FLAGS_model_folder "/home/litchi/project/openpose/models/"

class OpenPose{
public:
    std::unique_ptr<op::PoseExtractorCaffe> poseExtractorCaffe;
    std::unique_ptr<op::PoseCpuRenderer> poseRenderer;
    std::unique_ptr<op::FrameDisplayer> frameDisplayer;
    std::unique_ptr<op::ScaleAndSizeExtractor> scaleAndSizeExtractor;

    OpenPose(){
        caffe::Caffe::set_mode(caffe::Caffe::GPU);
        caffe::Caffe::SetDevice(0);

        op::log("OpenPose Library Tutorial - Example 1.", op::Priority::High);
        // ------------------------- INITIALIZATION -------------------------
        // Step 1 - Set logging level
        // - 0 will output all the logging messages
        // - 255 will output nothing
        op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
        op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__);
        // Step 2 - Read Google flags (user defined configuration)
        // outputSize
        const auto outputSize = op::flagsToPoint(FLAGS_output_resolution, "-1x-1");
        // netInputSize
        const auto netInputSize = op::flagsToPoint(FLAGS_net_resolution, "-1x368");
        // poseModel
        const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
        // Check no contradictory flags enabled
        if (FLAGS_alpha_pose < 0. || FLAGS_alpha_pose > 1.)
            op::error("Alpha value for blending must be in the range [0,1].", __LINE__, __FUNCTION__, __FILE__);
        if (FLAGS_scale_gap <= 0. && FLAGS_scale_number > 1)
            op::error("Incompatible flag configuration: scale_gap must be greater than 0 or scale_number = 1.",
                      __LINE__, __FUNCTION__, __FILE__);
        // Logging
        op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__);
        // Step 3 - Initialize all required classes
        scaleAndSizeExtractor = std::unique_ptr<op::ScaleAndSizeExtractor>(new op::ScaleAndSizeExtractor(netInputSize, outputSize, FLAGS_scale_number, FLAGS_scale_gap));

        poseExtractorCaffe = std::unique_ptr<op::PoseExtractorCaffe>(new op::PoseExtractorCaffe{poseModel, FLAGS_model_folder, FLAGS_num_gpu_start});

        poseRenderer = std::unique_ptr<op::PoseCpuRenderer>(new op::PoseCpuRenderer{poseModel, (float)FLAGS_render_threshold, !FLAGS_disable_blending,
                                                                                    (float)FLAGS_alpha_pose});
        frameDisplayer = std::unique_ptr<op::FrameDisplayer>(new op::FrameDisplayer{"OpenPose Tutorial - Example 1", outputSize});


        // Step 4 - Initialize resources on desired thread (in this case single thread, i.e. we init resources here)
        poseExtractorCaffe->initializationOnThread();
        poseRenderer->initializationOnThread();
    }

    string forward(const cv::Mat& inputImage, bool display = false){
        op::OpOutputToCvMat opOutputToCvMat;
        op::CvMatToOpInput cvMatToOpInput;
        op::CvMatToOpOutput cvMatToOpOutput;
        if(inputImage.empty())
            op::error("Could not open or find the image: ", __LINE__, __FUNCTION__, __FILE__);
        const op::Point<int> imageSize{inputImage.cols, inputImage.rows};
        // Step 2 - Get desired scale sizes
        std::vector<double> scaleInputToNetInputs;
        std::vector<op::Point<int>> netInputSizes;
        double scaleInputToOutput;
        op::Point<int> outputResolution;
        std::tie(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution)
                = scaleAndSizeExtractor->extract(imageSize);
        // Step 3 - Format input image to OpenPose input and output formats
        const auto netInputArray = cvMatToOpInput.createArray(inputImage, scaleInputToNetInputs, netInputSizes);
        // Step 4 - Estimate poseKeypoints
        poseExtractorCaffe->forwardPass(netInputArray, imageSize, scaleInputToNetInputs);
        const auto poseKeypoints = poseExtractorCaffe->getPoseKeypoints();

        if(display){
            auto outputArray = cvMatToOpOutput.createArray(inputImage, scaleInputToOutput, outputResolution);
            // Step 5 - Render poseKeypoints
            poseRenderer->renderPose(outputArray, poseKeypoints, scaleInputToOutput);
            // Step 6 - OpenPose output format to cv::Mat
            auto outputImage = opOutputToCvMat.formatToCvMat(outputArray);

            // ------------------------- SHOWING RESULT AND CLOSING -------------------------
            // Step 1 - Show results
            frameDisplayer->displayFrame(outputImage, 0); // Alternative: cv::imshow(outputImage) + cv::waitKey(0)
            // Step 2 - Logging information message
            op::log("Example 1 successfully finished.", op::Priority::High);
            // Return successful message
        }
        return poseKeypoints.toString();
    }
};

#endif //CAFFETEST_OP_H


这一部分需要注意的是
#define FLAGS_model_folder “/home/litchi/project/openpose/models/” 这里需要换成自己的机器中openpose/model的位置
#define FLAGS_model_pose “BODY_25” 这里可以选择输出的数据类型,比如"COCO"等

对这个封装的调用

#include <iostream>
#include<opencv2/opencv.hpp>
#include "op.h"
using namespace std;
int main() {
    string videopath="/home/litchi/data/20193.mp4";
    cv::VideoCapture capture;
    cv::Mat frame;
    frame= capture.open(videopath);
    if(!capture.isOpened())
    {
        cout<<"cant open"<<endl;
        return -1;
    }
    OpenPose op;
    while(capture.read(frame)){
        string point = op.forward(frame);
        std::cout<<point;
    }
}

在videopath中写上路径即可这样就是简易的预测了图片中任务的关节点的坐标,输出的数据注意第三项是x,y估计的准确度.

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(easyopenpose)
set(CMAKE_CXX_STANDARD 14)
set(INC_DIR /usr/include
        /usr/local/cuda/include #cuda的include位置 修改为自己的机器的正确的地方
        /home/litchi/project/openpose/3rdparty/caffe/include #机器中正确的caffe位置
        /home/litchi/project/openpose/3rdparty/caffe/src #机器中正确的caffe位置
        )
set(LINK_DIR /usr/lib
        /usr/lib/x86_64-linux-gnu/
        /usr/local/cuda/lib64 #cuda的lib位置 修改为正确的地方
        /home/litchi/project/openpose/3rdparty/caffe/build/lib #caffe的lib位置 修改为正确的地方
        )
set(OpenCV_DIR /usr/local/share/OpenCV) #opencv的位置
find_package(OpenCV REQUIRED)
find_package(OpenPose REQUIRED)
include_directories(${INC_DIR}${OpenCV_INCLUDE_DIRS}${OpenPose_INCLUDE_DIRS}${EIGEN3_INCLUDE_DIR})
link_directories(${LINK_DIR}${OpenCV_LIBS}${OpenPose_LIBS})
add_executable(easyopenpose main.cpp op.h)
target_link_libraries(easyopenpose
        caffe
        boost_system
        glog
        jsoncpp
        ${OpenPose_LIBS}
        ${OpenCV_LIBS}
        )

CMakeLists.txt的书写只需要根据楼主给出的注释修改路径就可以用了
验证结果是否正确可以视频文件用官方demo运行比较结果
根据我测试的数据,楼主这份代码和官方demo运行结果完美fit
源码可以在楼主上传的资源中下载

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++程序中使用openpose预测关节点坐标的简易实现 的相关文章

  • 如何把ipa文件(iOS安装包)安装到iPhone手机上? 附方法汇总

    苹果APP安装包ipa如何安装在手机上 很多人不知道怎么把ipa文件安装到手机上 这里就整理了苹果APP安装到iOS设备上的方式 仅供参考 苹果APP安装包ipa如何安装在手机上 使用过苹果手机的人应该深有感触 那就是苹果APP安装要比安卓
  • 深度态势感知

    1 引 言 从某种意义上说 人类文明是一个人类对世界和自己不断认知的过程 所为认知就是对有用的数据 信息进行采集过滤 加工处理 预测输出 调整反馈的全过程 纵观人类最早的美索不达米亚文明 距今6000多年 古埃及文明 距今6000年 及其衍
  • 前端使用layui结合canvas实现图片验证码

    fieldset class layui elem field layui field title style margin top 20px legend 图形验证码 legend fieldset
  • 基于PCA的人脸识别(MATLAB)

    项目描述 采用数据库为剑桥大学ORL人脸数据库 包含40个人的400张人脸图像 每人对应10张 图像为92x112灰度图像 256灰度级 对于每个人的10张图像 随机选择7张用来训练 另外3张用于测试 采用2范数最小匹配 对每个人的另外3张
  • 网站更换IP会对收录有什么影响?

    IP对于网站来说相当于是一个身份证 如果频繁换新对网站还是会带来一些波动的 那么 网站更换IP会有什么影响 接下来百万号快排系统小编就跟大家聊聊更换IP会给网站带来的影响 一起来看看吧 1 百度快照停止搜索和收录 企业建立IP之后 在百度快

随机推荐

  • 不同kNN模型在R语言中的比较

    不同kNN模型在R语言中的比较 k近邻 k Nearest Neighbors 简称kNN 是一种常见的机器学习算法 被广泛用于分类和回归问题 它基于一个简单的假设 与某个样本集中距离最近的k个样本具有相似的特征和标签 本文将探讨在R语言中
  • std::future、std::promise、std::packaged_task、std::async

    include
  • 使用下标给string类型赋值之后,cout输出变量为空的问题。

    今天写创建文件夹的时候 怎么创建都不会 反复修改 确定错误是出在了string类型的变量上面 看下面代码 这个一个函数中的代码 函数参数是string fileurl s int len fileurl s length std strin
  • 栈的基本操作(创建栈,压栈,出栈,遍历栈,清空栈,判断是否为空栈)

    include
  • arthas 线上更新代码不生效的问题Memory compiler error, exception message: Compilation Error

    arthas 线上更新代码的场景 线上代码bug 参数值不对 if判断 代码写错了 应用场景不对 导致代码报错出现问题 这个时候我们可以避免版本的发布就不走hostfix分支发布 应为自动化部署比较麻烦 需要jenkins打包推镜像 我们小
  • ubuntu 20.04 docker安装emqx 最新版本或指定版本

    要在Ubuntu 20 04上使用Docker安装EMQX EMQ X Broker 的4 4 3版本 您可以执行以下步骤 1 更新系统包列表 sudo apt update 2 安装Docker sudo apt install dock
  • MAttNet

    PyTorch Implementation of MAttNet Introduction This repository is Pytorch implementation of MAttNet Modular Attention Ne
  • 继承,重载函数,派生函数

    继承是类与类之间的关系 是一个很简单很直观的概念 与现实世界中的继承 例如儿子继承父亲财产 类似 继承 Inheritance 可以理解为一个类从另一个类获取成员变量和成员函数的过程 例如类B继承于类A 那么B就拥有A的成员变量和成员函数
  • 【软硬件通信】ESP32 Arduino 服务端 控制舵机

    1 安装esp32开发环境 搭建ESP32开发环境 2 编写舵机驱动程序 include
  • javaScript基础面试题---找出多维数组最大值

    function fnArr arr var newArr arr forEach item index gt newArr push Math max item return newArr console log fnArr 4 5 1
  • python 猫狗二分类简单实现

    1 数据集介绍 需要数据集可以在下面留言 数据集一共有猫图片 6000张 有狗图片 6000张 图片已经被命名为 0 1 jpg 0 6000 jpg 猫 1 0 jpg 1 6000 jpg 狗 照片读取代码如下 import numpy
  • C/C++在线编译器

    一直以来都喜欢用手机看书 尤其是在上班时 看的最多的是编程一类的书 主要是C 看着就想写写代码 可是电脑用不能用 怎么办 于是想到用UC浏览器找找看网上有没有在线的编译器 想什么时候写代码都可以验证 于是就找了几个 各有千秋吧 中文的我没找
  • python中用于返回元组中元素最小值的是_10个示例带你掌握python中的元组

    数据结构是任何编程语言的关键部分 为了创建强大而性能良好的产品 必须非常了解数据结构 在本文中 我们将研究Python编程语言的重要数据结构 元组 元组是用逗号分隔并括在括号中值的集合 与列表不同 元组的元素是不可变的 不变性可以视为元组的
  • 阿里巴巴开发手册-并发处理

    强制 获取单例对象要线程安全 在单例对象里面做操作也要保证线程安全 说明 资源驱动类 工具类 单例工厂类都需要注意 强制 线程资源必须通过线程池提供 不允许在应用中自行显式创建线程 说明 使用线程池的好处是减少在创建和销毁线程上所花的时间以
  • 图像数据压缩方法

    数据压缩方法 数据能够进行压缩 是因为数据中存在或多或少的冗余信息 而对于视频和音频等多媒体信息 更可以利用人类自身的感知冗余 失真 特点来实现更高的压缩比例 衡量压缩算法的三个主要性能指标如下 压缩比 压缩质量 失真 压缩与解压缩效率 注
  • 企业如何实现上云、选云和买云的三步走

    云计算的发展进入稳定期后 客户的关注点已经聚焦到了混合云 从混合云的视角出发来看 公有云厂家的产品已经琳琅满目非常成熟了 从传统的虚拟服务器 存储 网络 到数据库 中间件到 Docker 等 各大主流公有云厂商都推出了具有相当竞争力的产品
  • 交叉连接查询课程号

  • C++的引用

    C 的引用 一 什么是引用 1 1声明方法 1 2为什么C 要加入引用类型的变量 引用类型与指针类型的比较 二 引用类型在函数中的实际使用 2 1传参数时特殊情况 临时变量 三 引用的更多使用 3 1 常引用 C 引用就是一个变量的别名 一
  • Java实现文件传输

    Java实现文件传输 在Java编程中 我们可以使用各种方法实现文件传输 文件传输是将文件从一个位置传输到另一个位置的过程 可以用于各种应用场景 如文件备份 文件共享等 下面我将介绍一种基于Socket的Java文件传输实现方法 首先 我们
  • C++程序中使用openpose预测关节点坐标的简易实现

    C 程序中使用openpose预测关节点坐标的简易实现 虽然在openpose的官网上已经给出了很多可用的demo 但是如果我们在自己的C 项目中想要使用openpose来预测三维关键点官网给出的例子不是很适用 所以我现在给出了C 程序中使