IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 基于openCV绘制自定义形状骨骼线 -> 正文阅读

[人工智能]基于openCV绘制自定义形状骨骼线

??现在市面上很多人体追踪产品都有实时展示人体骨骼线的需求,绝大部分的骨骼线和骨骼点都是使用 line()circle() 来解决的。这种方式简单明了,只需要知道两个骨骼点的位置就可以实现。实现的效果基本和下图类似:
????在这里插入图片描述

??但是这种单一的线条缺乏视觉上的冲突感。所以希望利用同样的骨骼点信息画出更有“感觉”的骨格线。这里介绍一种实现方式,希望能给到大家一些启发。

??首先确定骨格线需要是什么形状的。这里介绍一种菱形骨格线。
????????????????????????在这里插入图片描述
??按照原本的画线,最直观的信息就是两个骨骼点的坐标,通过坐标就可以计算向量以指定骨格线的方向,还可以计算骨骼点之间的距离,利用这两个点的坐标可以计算出两点连线上任意点的坐标。这里定义连线上距离起点 1/8 处的坐标为中间点并计算骨骼点连线的法向量,可以获得经过中间点并且与骨骼点连线垂直的直线上任意点的坐标。这样菱形的4个顶点坐标就都能计算出来了。

#pragma once
#include <memory>
#include <string>


struct else_two_point
{
    double left_point_x;
    double left_point_y;
    double right_point_x;
    double right_point_y;
};
//已知两点计算菱形另外两点坐标,你们也可以不用这样返回值,这样是为了方便直接调用。
else_two_point calculate_else_two_point(double point1_x, double point1_y, double point2_x, double point2_y) {
	//声明中间点
    k4a_float2_t center_point;
    //骨骼点之间的距离
    double distance4p1p2 = sqrt(pow(point1_x - point2_x, 2) + pow(point1_y - point2_y, 2));
    //以起点到终点1/8处坐标定义中间点
    center_point.xy.x = point1_x - (point1_x - point2_x) / 8;
    center_point.xy.y = point1_y - (point1_y - point2_y) / 8;
    //声明另外两点
    else_two_point else_two;
    //通过法向量和一定距离定义另外两点
    else_two.left_point_x = center_point.xy.x + ((distance4p1p2 / 8) * ((point2_y - point1_y) / distance4p1p2));
    else_two.left_point_y = center_point.xy.y - ((distance4p1p2 / 8) * ((point2_x - point1_x) / distance4p1p2));
    else_two.right_point_x = center_point.xy.x - ((distance4p1p2 / 8) * ((point2_y - point1_y) / distance4p1p2));
    else_two.right_point_y = center_point.xy.y + ((distance4p1p2 / 8) * ((point2_x - point1_x) / distance4p1p2));
    //返回另外两点
    return else_two;
}

??利用比例关系还能让这种菱形在固定形状的同时可以随骨骼点距离和位置改变大小和方向。
??????????????????????在这里插入图片描述
上面知道了如何获取菱形的其他两个顶点,下面介绍如何画出图形。主要是利用openCV中的fillPoly()函数。

//所处位置 imgproc.hpp
//第一个参数是画布
//第二个参数是每个多边形的顶点集(可以通过2维数组定义不同的多边形的顶点)
//第三个参数是要绘制多边形的顶点个数
//第四个参数是要绘制图形的数量
//第五个参数是填充颜色
//第六个参数是线型
CV_EXPORTS void fillPoly(Mat& img, const Point** pts,
                         const int* npts, int ncontours,
                         const Scalar& color, int lineType = LINE_8, int shift = 0,
                         Point offset = Point() );

先看代码比较枯燥,所以先看看效果吧。
????????????????????????在这里插入图片描述
然后上完整代码,下面代码能画出一条骨骼线,在需要画线的骨骼点之间调用 draw_bone() 即可达到上图效果。

//绘制菱形
void drawPoly(Mat& src, Point** pts, int npts)
{
    const Point* ppt[1] = { pts[0] };
    int npt[] = { npts };
    int lineType = LINE_AA;
    fillPoly(src, ppt, npt, 1, Scalar(255, 255, 85), lineType);
}
//已知两点计算菱形另外两点坐标
else_two_point calculate_else_two_point(double point1_x, double point1_y, double point2_x, double point2_y) {
    k4a_float2_t center_point;
    double distance4p1p2 = sqrt(pow(point1_x - point2_x, 2) + pow(point1_y - point2_y, 2));
    center_point.xy.x = point1_x - (point1_x - point2_x) / 8;
    center_point.xy.y = point1_y - (point1_y - point2_y) / 8;
    else_two_point else_two;
    else_two.left_point_x = center_point.xy.x + ((distance4p1p2 / 8) * ((point2_y - point1_y) / distance4p1p2));
    else_two.left_point_y = center_point.xy.y - ((distance4p1p2 / 8) * ((point2_x - point1_x) / distance4p1p2));
    else_two.right_point_x = center_point.xy.x - ((distance4p1p2 / 8) * ((point2_y - point1_y) / distance4p1p2));
    else_two.right_point_y = center_point.xy.y + ((distance4p1p2 / 8) * ((point2_x - point1_x) / distance4p1p2));
    return else_two;
}
//绘制自制两个骨骼点之间菱形线
void draw_bone(Mat& src, double point1_x, double point1_y, double point2_x, double point2_y) {

    // 定义多边形的顶点
    Point** rook_points = new Point * [1];
    rook_points[0] = new Point[4];
    rook_points[0][0] = Point(point1_x, point1_y);
    rook_points[0][2] = Point(point2_x, point2_y);
    else_two_point else_two = calculate_else_two_point(point1_x, point1_y, point2_x, point2_y);
    rook_points[0][1] = Point(else_two.left_point_x, else_two.left_point_y);
    rook_points[0][3] = Point(else_two.right_point_x, else_two.right_point_y);
    // 绘制菱形
    drawPoly(src, rook_points, 4);
    imshow("菱形骨格线", src);
}

大家可以开放脑洞,尝试绘制其他图形。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章           查看所有文章
加:2022-03-04 15:33:38  更:2022-03-04 15:38:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 17:23:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码