YOLOv8-Segment C++

news2024/11/20 18:43:08

YOLOv8-Segment C++

https://github.com/triple-Mu/YOLOv8-TensorRT

这张图像是运行yolov8-seg程序得到的结果图,首先是检测到了person、bus及skateboard(这个是检测错误,将鞋及其影子检测成了滑板,偶尔存在错误也属正常),然后用方框将他们标出,之后由分割将其轮廓标出。

接下来看看具体怎么实现的,这个程序主要由YOLOv8_seg::infer()与YOLOv8_seg::postprocess()函数实现,之后利用YOLOv8_seg::draw_objects()函数将结果展示在图像中。

segment

接下来分割部分进行解读:

YOLOv8_seg::postprocess()函数得到了objs, 其中包含了检测目标box的尺寸及位置,还包含了目标轮廓数据,在box中是目标的像素块的像素值为255,其余区域均为0。上面结果可以看到目标既被方框标出,又有颜色涂抹,这里其实是利用cv::addWeighted()函数实现的,是将两张图像按照不同权重融合在了一起。

下面这张图像是仅展现出了分割的效果:

所有被检测到的目标均被分割。如果只需要对person分割,由于person的标签序索引0,所以将检测到的目标标签与0作判断即可。

cv::Mat segmask = image.clone();
for (auto& obj : objs) {
    int        idx   = obj.label;
    if (idx == 0)
    {
        cv::Scalar mask_color =
            cv::Scalar(MASK_COLORS[idx % 20][0], MASK_COLORS[idx % 20][1], MASK_COLORS[idx % 20][2]);
        segmask(obj.rect).setTo(mask_color, obj.boxMask);
    }
}

于是就得到了:
在这里插入图片描述

看一下objs具体包含了什么样的数据

for (auto& obj : resultObjs)
{
std::cout << "----------------------------------------------" << std::endl;
std::cout << "Rect: " << obj.rect << std::endl;
std::cout << "Label: " << CLASS_NAMES[obj.label] << std::endl;
std::cout << "boxMask: " << obj.boxMask << std::endl;
}

循环中的一次输出:

----------------------------------------------
Rect: [77 x 324 from (2, 545)]
Label: person
boxMask: [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;

...
...
...;
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0]

从输出结果可以看出这个目标尺寸为77 x 324,从图像中坐标 (2, 545) 开始,目标类别是person,boxMask中的数据为255的则是目标所在的像素,数据为0的则是目标之外的像素。

boxMask的数据可以在yolov8-seg.hpp中找到其赋值语句:

objs[i].boxMask = mask(objs[i].rect) > 0.5f;

可以看出boxMask为什么只有0与255了。

获取坐标

那么根据输出结果我们可以利用rect与boxMask获取目标(这里的目标是person)的坐标,首先可以利用函数cv::findNonZero()找出boxMask中值为255的坐标,然后再加上rect包含的目标框的起点坐标就可以了

// 创建白色画布((1080,810)是图像尺寸,画布要与原图像尺寸一致)
cv::Mat segImg(1080, 810, CV_8UC3, cv::Scalar(255, 255, 255));
std::vector<cv::Point> segpoints;
cv::Mat segmask = image.clone();
for (auto& obj : objs) {
    int        idx   = obj.label;
    if (idx == 0)
    {
        cv::Scalar mask_color =
            cv::Scalar(MASK_COLORS[idx % 20][0], MASK_COLORS[idx % 20][1], MASK_COLORS[idx % 20][2]);
        segmask(obj.rect).setTo(mask_color, obj.boxMask);
        cv::Mat locations;
        cv::findNonZero(obj.boxMask == 255, locations);
        // 打印位置
        std::cout << "值为 255 的位置:" << std::endl;
        for (int i = 0; i < locations.rows; ++i) {
            std::cout << "(" << locations.at<cv::Point>(i).x << ", " << locations.at<cv::Point>(i).y << ")" << std::endl;
            // 这里是目标方框bbox中的坐标,之后需要加上方框起点
            cv::Point segpoint = locations.at<cv::Point>(i);
            segpoint.x += obj.rect.x;
            segpoint.y += obj.rect.y;
            // 将所有坐标(x,y)存储在segpoints中
            segpoints.push_back(segpoint);
        }
    }
}
for (const auto& segpoint : segpoints) {
    segImg.at<cv::Vec3b>(segpoint) = cv::Vec3b(255, 0, 0);
}
cv::imshow("segImg",segImg);
cv::imwrite("segImg.jpg",segImg);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1427825.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4D毫米波雷达——ADCNet 原始雷达数据 目标检测与可行驶区域分割

前言 本文介绍使用4D毫米波雷达&#xff0c;基于原始雷达数据&#xff0c;实现目标检测与可行驶区域分割&#xff0c;它是来自2023-12的论文。 会讲解论文整体思路、输入分析、模型框架、设计理念、损失函数等&#xff0c;还有结合代码进行分析。 论文地址&#xff1a;ADCNe…

Flink实时数仓同步:快照表实战详解

一、背景 在大数据领域&#xff0c;初始阶段业务数据通常被存储于关系型数据库&#xff0c;如MySQL。然而&#xff0c;为满足日常分析和报表等需求&#xff0c;大数据平台采用多种同步方式&#xff0c;以适应这些业务数据的不同存储需求。这些同步存储方式包括离线仓库和实时仓…

nvm 工具使用介绍

目录 1.背景2.nvm介绍3.下载和安装4.配置环境变量5.配置淘宝镜像5.1 方式一&#xff1a;直接执行命令5.2 方式二&#xff1a;修改配置文件 6.常用命令7.总结 下载地址&#xff1a; https://github.com/coreybutler/nvm-windows/releases 1.背景 在工作中&#xff0c;我们可能…

总分类账户和明细分类账户

目录 一. 设置二. 联系与区别三. 平行记账规则 \quad 一. 设置 \quad 根据总分类科目设置总分类账户 根据明细分类科目设置明细分类账户 \quad 二. 联系与区别 \quad \quad 三. 平行记账规则 \quad

【C++11(一)】列表初始化and右值引用

一、 统一的列表初始化 1.1 &#xff5b;&#xff5d;初始化 在C98中&#xff0c;标准允许 使用花括号{}对数组或者结构体元素 进行统一的列表初始值设定 C11扩大了用大括号 括起的列表(初始化列表)的使用范围 使其可用于所有的内置类型和 用户自定义的类型 使用初始化列表时…

bash脚本学习笔记

一、扫盲 脚本文件是一种文本文件&#xff0c;其中包含了一系列的命令和指令&#xff0c;可以被操作系统解释器直接解释执行。脚本文件通常被用来完成特定的任务或执行重复性的操作。 脚本文件通常以某种编程语言的语法编写&#xff0c;例如 Bash、Python、Perl、Ruby 等等。…

IDEA JDBC配置

一、在pom中添加依赖 <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency></dependencies> 然后同步一下 二、编写代码…

Linux 系统服务

一、CentOS 6 与 CentOS 7开机流程 1.CentOS 6 1.1.打开电源首先通过内核引导开机。 1.2.开机自检&#xff0c;加载 BIOS 硬件信息。 1.3.MBR 记录一般是在磁盘0磁道0扇区&#xff0c;共512个字节。前446个字节是 BootLoder。计算机不知道我们的系统在哪里&#xff0c;所以需…

【Java数据结构】模拟实现ArrayList

import java.util.Arrays;/*** ArrayList的模拟实现*/ class SeqList{private int[] elem;private int usedSize0;//记录当前顺序表有多少个有效数字public static final int DEFAULT_CAPACITY10;//默认大小是10public SeqList(){this.elemnew int[DEFAULT_CAPACITY];}//新增元…

基于FFT + CNN -Transformer时域、频域特征融合的电能质量扰动识别模型

目录 往期精彩内容&#xff1a; ​模型整体结构 1 快速傅里叶变换FFT原理介绍 第一步&#xff0c;导入部分数据&#xff0c;扰动信号可视化 第二步&#xff0c;扰动信号经过FFT可视化 2 电能质量扰动数据的预处理 2.1 导入数据 2.2 制作数据集 3 基于FFTCNN-Transform…

服务攻防-端口协议桌面应用QQWPS等RCEhydra口令猜解未授权检测

知识点&#xff1a; 1、端口协议-弱口令&未授权&攻击方式等 2、桌面应用-社交类&文档类&工具类等 章节点&#xff1a; 1、目标判断-端口扫描&组合判断&信息来源 2、安全问题-配置不当&CVE漏洞&弱口令爆破 3、复现对象-数据库&中间件&…

AS-V1000产品介绍:支持GA/T1400视图库标准(可通过GA/T1400接入海康、华为、大华等图传前端设备,实现图传功能)

目 录 一、概述 二、AS-V1000视频监控管理平台的特点 二、视频监控平台通过GA/T1400接入前端设备 &#xff08;一&#xff09;接入华为GA/T1400前端设备 &#xff08;二&#xff09;接入大华GA/T1400前端设备 &#xff08;三&#xff09;接入海康威视GA/…

QML ListView 列表视图

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 虽然 Repeater 在重复创建多个相似项的时候很方便,但是通常只适用于有限的简单元素,并且它还无法滚动浏览。而基于 Flickable 的视图组件(如 GridView、ListView、TableView、TreeView 等)则弥补了这些缺…

vue-3d-model

vue-3d-model - npm GitHub - hujiulong/vue-3d-model: &#x1f4f7; vue.js 3D model viewer component 通过该插件降低Threejs的使用难度 vue项目加载三维模型&#xff0c;我把模型放在了服务器的tomcat里面&#xff0c;需要对tomcat的fbx项目文件夹设置跨域&#xff0c;如…

Docker容器引擎(5)

目录 一.docker-compose docker-compose的三大概念&#xff1a; yaml文件格式&#xff1a; json文件格式&#xff1a; docker-compose 配置模板文件常用的字段&#xff1a; 二.Docker Compose 环境安装&#xff1a; 查看版本&#xff1a; 准备好nginx 的dockerfile的文…

微信小程序(三十一)本地同步存储API

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.存储数据 2.读取数据 3.删除数据 4.清空数据 源码&#xff1a; index.wxml <!-- 列表渲染基础写法&#xff0c;不明白的看上一篇 --> <view class"students"><view class"item…

银行数据仓库体系实践(16)--数据应用之财务分析

总账系统 在所有公司中&#xff0c;财务分析的基础都是核算&#xff0c;那在银行的系统体系中&#xff0c;核算功能在业务发生时由业务系统如核心、贷款、理财中实现登记&#xff0c;各业务系统会在每天切日后统计当天各机构的核算科目的发生额与余额&#xff0c;并统一送到总账…

k8s二进制及负载均衡集群部署详解

目录 常见部署方式 二进制部署流程 环境准备 操作系统初始化配置 关闭防火墙 配置SELinux 关闭SWAP 根据规划设置主机名 在master添加hosts&#xff0c;便于主机名解析 调整内核参数 配置时间同步 部署docker引擎 在所有node节点部署docker引擎 部署etcd集群 签发…

shell脚本自动备份数据库表

今日目标&#xff1a;shell脚本自动备份数据库中的表并记录执行日志和mysql输出日志 编写思路&#xff1a; &#xff08;1&#xff09;shell脚本运行mysql命令 &#xff08;2&#xff09;脚本输出记录到日志中 &#xff08;3&#xff09;定时任务自动执行shell脚本 1、she…

王子公主来扫雷0^0

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 今日主菜&#xff1a;扫雷小游戏&#xff0c; 主厨&#xff1a;邪王真眼 所属专栏&#xff1a; C语言知识点 主厨的主页&#xff1a;Chef‘s blog 引言&a…