基于OpenPose的卡通人物可视化

前言

去年打算用些现成的Pose做些展示,因为以前有在OpenPose做些识别等开发工作,所以这次我就简单在OpenPose上把骨架用动画填充上去,关于能够和人动作联系起来的动画,我找到了Unity提供的示例Anima2D,但是Unity学得不是很熟,我就用PhotoShop把Anima2D的每个部位截取保存下来,然后使用OpenCV把各个部位读取进去,做些数学计算,把各个部位贴到OpenPose得出的骨架结果上,最后得到一个简单的2D动作展示,代码我会贴出来,下面写下我的思路,方法很简单,不喜勿喷。

效果展示

思路描述
  1. 找个动画,把它的关节拆开,我选用了Anima2D的一个example。


  1. 用Photoshop把各个部位拆开,这样子方法用OpenCV读取各个关节来做旋转变化。

  1. 根据OpenPose的18个关节点的位置,制定切实可行的关节旋转计划,因为旋转需要其余点绕一个定点来旋转,而一个关节的旋转势必会带动与它相关连的所有点的旋转,所以这一部分要考虑清楚。下面是我当时做的各类型的草稿,大致内容是在研究怎么旋转,这里没有详细体现出来。

  1. 然后我设计了一个很大致的关节点联系的草图,大家看具体的关节点联系就好了,我当时是给每个关节标号了。

  1. 就是由上面这个玩意,我最后将各个部位一步一步组成一个完整形态的机器人,可能和官方的example有一点差距,但是过程中有些麻烦的东西我就给它去掉了。

  1. 代码细节我就不细讲了,就是些简单的数学旋转变化,再调一调就出来了,另外这个可以加入SVM,将关节点回归某些指定的动作,这样可以实现在动画过程中你做出指定的动作后动画界面做出一些反馈,最简单的就是你比划两下然后头部的颜色就从白色变成黑色,或把它背景颜色改一下,实现一些用户交互性的东西这些自己去研究,SVM这个简单可行,刚好加到VS里面编译一下就出来了,下面是代码,我就加了一些自己的东西。

    图片资源在CSDN下载那里搜索“Anima2D的Robot图片 ”就有了。

#include <chrono> 
#include <thread>
#include <gflags/gflags.h>
#ifndef GFLAGS_GFLAGS_H_
namespace gflags = google;
#endif
#include <openpose/headers.hpp>
#include <vector>  
#include <stdio.h>  
#include <opencv2/opencv.hpp>  
#include<Math.h>
#include<svm.h>
#define pi 3.1415926
#include <iostream>
#include<fstream>

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

void saveBead(cv::Mat *background, cv::Mat *bead, int X_, int Y_, int tarX, int tarY);
int cvAdd4cMat_q(cv::Mat &dst, cv::Mat &scr, double scale);
cv::Mat rotate(cv::Mat src, double angle);
void getPoint(int *point, int srcX, int srcY, double angle, int srcImgCols, int srcImgRows, int tarImgCols, int tarImgRows);
cv::Mat getRobot(op::Array<float> poseKeypoints,double scale);
double getAngle(double p0_x, double p0_y, double p1_x, double p1_y);
void resizeImg(double scale);

// Robot Param
int point[2] = { 0,0 };
double scale = 1;
cv::Mat
img0_s = cv::imread("D:/Robot/background0.png"),
img1_s = cv::imread("D:/Robot/1.png", -1),
img2_s = cv::imread("D:/Robot/2.png", -1),
head_s = cv::imread("D:/Robot/3.png", -1),
img4_s = cv::imread("D:/Robot/4.png", -1),
foot_s = cv::imread("D:/Robot/5.png", -1),
leg_s = cv::imread("D:/Robot/6.png", -1),
img7_s = cv::imread("D:/Robot/7.png", -1),
bead_s = cv::imread("D:/Robot/8.png", -1),
m1_s = cv::imread("D:/Robot/9.png", -1),
m2_s = cv::imread("D:/Robot/10.png", -1),
hand_s = cv::imread("D:/Robot/11.png", -1),
neck_s = cv::imread("D:/Robot/12.png", -1),
body_s = cv::imread("D:/Robot/13.png", -1),
circle_s = cv::imread("D:/Robot/14.png", -1),
img15_s = cv::imread("D:/Robot/15.png", -1),
handcenter_s = cv::imread("D:/Robot/16.png", -1), background,
b1= cv::imread("D:/Robot/background1.png")
;

cv::Mat img0 = img0_s.clone(),
img1 = img1_s.clone(),
img2 = img2_s.clone(),
head = head_s.clone(),
img4 = img4_s.clone(),
foot = foot_s.clone(),
leg = leg_s.clone(),
img7 = img7_s.clone(),
bead = bead_s.clone(),
m1 = m1_s.clone(),
m2 = m2_s.clone(),
hand = hand_s.clone(),
neck = neck_s.clone(),
body = body_s.clone(),
circle = circle_s.clone(),
img15 = img15_s.clone(),
handcenter = handcenter_s.clone();

int camera_rows = 720, camera_cols = 1280;
//int ccount = 0;
struct UserDatum : public op::Datum
{
	bool boolThatUserNeedsForSomeReason;

	UserDatum(const bool boolThatUserNeedsForSomeReason_ = false) :
		boolThatUserNeedsForSomeReason{ boolThatUserNeedsForSomeReason_ }
	{}
};

class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<UserDatum&
  • 14
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值