依星源码资源网,依星资源网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

【好消息,好消息,好消息】VIP会员可以发表文章赚积分啦 !
查看: 106|回复: 0

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部署

[复制链接] 主动推送

1万

主题

1万

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
12874
发表于 2024-12-3 11:10:34 | 显示全部楼层 |阅读模式
基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部署
c++跨平台版本的服务端(cmake),支持windows和linux系统
技术架构
  • AI盒子端
    使用CMake跨平台或使用python开发的跨平台版本
  • 盒子后台
    vue2.0全家桶
  • AI预警云
    springcloud alibba为服务版,shardingsphere分库分表,mysql数据库
  • AI预警端
    vue2.0全家桶
  • AI移动端
    uniapp框架

开发技术
(1)C++版本
  • C++11
    里面使用了一些C++11以上的新语法,对于老程序员来说,语言只是一种工具,花时间熟悉一下新语法即可,问题不大。
  • Boost
    C++跨平台库,C++11中的大部分新特性都是来自Boost准标准库,但是还有很多新特性暂时并未引入到c++中,它可以跨平台编码,开发人员并不需要写一些预编译语法来适应不同平台,只需要一套代码即可实现所有平台,这就是它的优势,也是为什么C++新语法基本都出自它的原因。
  • mysql
    系统涉及到的一些模型数据、设备、场景、报警、配置等数据的存储既可以使用mysql存储,也可以使用sqlite存储,根据自己需要,可以通过配置文件配置存储方式,唯一的区别是mysql需要安装数据库而已。
  • sqlite
    同上,AI盒子数据存储支持使用sqlite存储,所以需要用到sqlite库。
  • oatpp
    一个开源的支持多语言的成熟http库,跨平台,支持DTO数据封装、SSL等,一个非常不错的HTTP协议库。
  • spdlog
    一个开源的系统日志库,支持控制台打印、文件日志打印、支持自动清理、按日存储等功能。
  • opencv
    一个很关键的一个库了,python使用pt模型,c++使用onnx模型,这里就是基于跨平台opencv来加载onnx模型实现推理的。
  • vue2.0
    AI盒子提供了一个web管理端,通过其实现模型管理、设备管理、场景管理、报警管理、录像管理、系统配置、预警监控等功能。
    注:此开源版本提供基于vue2.0开发的web管理端,提供与AI盒子内部通信的交互操作控制台,如果需要定制自己的模型、设备、场景、配置等,可能需要修改web后台管理端源码,需要此部分的源码,需联系作者付费采购,感谢理解。
  • yolov8
    c++版本使用的yolov8的模型,通过yolov8模型或yolov5模型转换的onnx模型实现模型推理和目标识别。

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

这里从下至上进行一一说明
  • 设备层
    AI盒子接入的设备为网络摄像机,当然也支持本地摄像头的采集和分析(一般用于做demon),AI盒子作为边缘计算盒,一般部署在与网络摄像机相同的局域网内,通过标准的RTSP协议采样抽帧的方式分析摄像机的视频流,然后对采样的图像帧使用yolov8模型库进行一一分析,这里的摄像头采用标准的rtsp协议,可以是任意厂家的摄像头,包括常见的海康、大华、安士讯等。
  • 接入层
    接入层其实就只我们本文介绍的主角,也就是AI智能盒子,它作为边缘计算盒子,与摄像机同属一个局域网(当然排除服务云端化后提供云识别接口之外),它通过局域网与摄像机相连,通过USB或Lane接口连接,通过USB连接IO控制器(如果AI盒子需要控制IO开关如信号灯、语音喊话、硬件信号输入到其他系统等),AI盒子通过分析网络摄像机视频流,当分析到检测预警时,记录报警信息(时间、设备、类型、报警图片、报警前后n秒录像片段),实时存储到AI盒子本地,并异步将报警信息推送到第三方平台。
  • 服务层
    sass云服务时一个多租户平台,主要功能就是提供基于AI盒子的高级应用,包括预警推送(手机、短信、公众号等)、预警处理、视频播放、预警统计、设备管理、云模型管理、策略管理、第三方数据对接、数据推送等功能应用。
  • 应用层
    基于sass云的移动端应用和管理,用户可以通过手机端接收系统预警信息、处理预警、处理各自的任务、实时查看预警和视频等功能。

功能介绍
智能AI盒子提供了如下功能(部分c++版本功能可能没有,python版本有,后面会指出来,感兴趣的各位网友,也希望可以私下联系共同开发新增)
web管理端
web管理端指AI盒子的启动后台的交互网页终端,它基于AI盒子提供的HTTP接口实现AI盒子的数据管理、配置等功能。
  • 资源国际化
    为适应不同用户的需求,AI盒子web管理端提供了中文简体、中文繁体、英文3种语言的切换。
  • 模型管理
    管理端提供模型管理功能,包括模型上传、模型添加、模型修改、模型删除、模型更新等功能,具体见演示效果。
  • 设备管理
    管理端提供了设备管理功能,包括设备添加、更新、移除、查询、设备区域范围配置、图片预览等功能。
  • 场景管理
    管理端提供指定设备的多场景管理,包括一个设备添加多个场景、查询设备场景、更新设备场景、移除设备场景功能。
  • 系统配置
    可以通过web端动态配置AI盒子的常用配置,包括盒子编码(对接第三方唯一id)、盒子保存数据天数、是否展示识别标签、第三方平台推送地址等。
  • 重启盒子
    如果有必要,可以通过web端重启AI盒子(linux下部署时候需要root权限部署才能正常重启,启动后自动启动AI盒子服务程序)

AI盒子端
  • HTTP、websocket协议
    AI盒子支持通过Http协议管理AI盒子配置、模型、设备、场景等(如AI的WEB端),也可以通过websocket协议下发和操作AI盒子,实现与AI和的多协议交互。
  • 模型热加载
    模型可以在系统启动后随时进行更新,盒子自动检测变化重新加载模型信息。
  • 设备热加载
    被检测的设备更新后,AI盒子自动侦测信息变化,自动重新加载分析设备(如分析时间段、分析帧率等)
  • 场景热加载
    一个分析视频设备,可以叠加多种分析场景算法,当某一算法发生变化后,AI盒子自动更新加载对应场景。
  • 配置热加载
    系统配置会实时更新到内存中,实时更改对应系统配置(如保存时长、是否显示label、是否自动重启等)
  • 抽帧采样分析
    AI盒子可以根据用户配置动态分析设备抽帧采样帧率,如25帧分析一张(1秒一张)
  • 多算法分析
    一个分析设备,可以叠加多种分析场景算法,也就是分析的某张图可以叠加n种分析算法(串行叠加分析)
  • 分析时段控制
    可以根据用户需要配置不同时间段进行分析,如晚上18:00-23:00时间段内进行分析,不在改时间段则停止分析。
  • 分析区域配置
    python版本支持划定的多边形内的目标进行分析,也支持多个线段进行越界侦测分析。
  • 模型推理分析
    支持yolov5、yolov8的模型进行推理分析,其中python版本使用yolov5的pt模型,yolov8使用的是onnx模型
  • 报警存储
    当AI盒子检测到对应预警类型的目标后,将指定时间、设备、预警类型、预警图片、预警前后5秒(预录前5秒)的录像临时保存下来,然后异步推送到第三方平台。
  • 报警录像
    当AI盒子检测到预警类型的目标后,AI盒子根据用户配置进行是否录像,录制事件发生前5秒和后5秒的录像(mp4格式或flv)
  • GPIO录像
    AI盒子支持抓取GPIO信号,进行联动,开启或停止录像。
  • GPIO抓拍
    AI盒子支持抓取GPIO信号,进行联动,开启关联摄像机的图片抓拍。
  • 报警推送
    AI盒子可以配置报警推送http地址(https),然后将报警信息(设备、报警类型、时间、图片、录像)推送至第三方平台。
  • 报警广播
    AI盒子自带的web端具有报警预览功能,当进入AI盒子报警预览页面后,发现报警会自动推送到web端,并使用tts语音播报方式将对应的报警内容以语音的形式播放出来。
  • 报警清理
    AI盒子sd卡存储能力有限,为了保证AI盒子能够持续工作,AI盒子会自动覆盖最老的报警信息(主要包括数据和录像清理)
  • 视频播放
    AI盒子与IPC摄像机一般处于同一个局域网,所以AI盒子具有能直接访问摄像机的条件,而云端要看摄像机的视频必须通过盒子(或其他第三方视频云平台)转发,AI盒子正好集成了改功能,它通过websocket下发指令启动视频的开始、停止播放(rtmp推送到服务端),启动远程抓拍功能。
  • 远程抓拍
    如上说,AI盒子既具备视频转发能力,也具备远程控制抓拍功能。
  • 远程录像
    AI盒子及支持关联摄像机(或非关联但是与其摄像机在同一张局域网内)的实时视频转发,也具有开启远程录像、停止远程录像的手动录像功能,录像完成后AI盒子会立即将录像信息推送到第三方云平台中(mp4格式-可以在web端播放)。
  • 自动重启
    如果有必要,可以配置AI盒子自动重启(每晚12点),但是一般情况下不会这么做,除非网络有问题。
  • 自动校时
    AI盒子会定时与第三方云平台进行心跳,为了保证AI盒子时间与云平台保持一致,在心跳的时候云平台如果返回服务器时间则AI盒子会自动将服务器时间设置为本地时间,以便与服务器进行时间对齐。
  • 分析接口
    AI盒子具有自己抓取摄像头图片进行分析的能力,此外,AI盒子也提供的对外的http接口,用户可以通过接口将推送推送给AI盒子,然后进行识别,最后将结果以接口结果形式返回的第三方平台(不推荐使用)

示例下载windows
如果windows是win7或者xp系统,可能运行demon报缺少ucrtbase.dll,该文件可以在源码路径中找到,找到后放exe所在目录即可
AiBoxrdpartylibwin32

(1)默认80分类检测模型demon
windows7或win10以上,编译打包的下载链接如下
链接:https://pan.baidu.com/s/1tCrcjAK-1lERMut013kPXw?pwd=abcd 提取码:abcd

使用:下载后直接解压到当前文件夹,然后运行AiBox.exe即可
注意,如果电脑没有摄像头,请插入usb摄像头后尝试!
(2)安全帽反光衣检测模型demon
链接:https://pan.baidu.com/s/1UkfkLnTFGgn_w87xQ6u0bA?pwd=62h3 提取码:62h3

ubuntu
(1)默认80分类检测模型demon
x64_86架构的,系统为ubuntu20.04版本编译的demon连接如下
链接:https://pan.baidu.com/s/1dGd4SYjWtIKEmcEbYlYrGA?pwd=abcd 提取码:abcd

使用
tar -zxvf ai_box_ubuntu20.04.tar.gzcd ai_box/./AiBox

注意:
如果是WMWare Workshop启动的虚拟机,请将主机的摄像头共享给Ubuntu虚拟机,操作步骤如下:
  • windows打开服务:ctrl+r输入services.msc,然后找到VM的USB服务,名字为VMware USB Arbitration Service,设置为开机启动,并手动启动该服务。
  • 重启WMWare Workshop及Ubuntu虚拟机(如果usb重启的情况下必须重启)
  • 启动Ubuntu20.04机器
  • 在VM上选择该机器,鼠标右键菜单,选择对应设备,然后连接即可

    基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

    基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...
  • 使用ubuntu再带的茄子工具cheese打开测试摄像头是否可用

orangePI
(1)默认80分类检测模型demon
国产华为升腾芯片(主要跑NPU,还没空适配NPU,目前也是跑CPU)demon下载链接如下
链接:https://pan.baidu.com/s/1j3FzFwx1uNKNnwVGRg95hQ?pwd=abcd 提取码:abcd

上传到orangePI中,解压运行即可
tar -zxvf ai_box_ubuntu20.04.tar.gzcd ai_box/./AiBox

jetson Nano
jetson nano是跑python、GPU版本的,不是跑C++的,追求实时性、识别速度和高性能的请私下联系我采购商业python版本,功能比cpp版本更强,所以这里就没有CPU版本的适配demon,见谅!
VOC2YOLO
VOC格式数据是一种标准格式数据,而在yolo中有自己的格式数据,它是txt格式的,每一行表示一个对象的基本信息,所以我们需要将VOC格式的数据转换为YOLO格式数据之后,才能拿到yolo中进行训练,当然,我们可以一开始的时候就标注yolo格式数据,这里我不太推荐,原因如下
  • VOC是通用格式数据,记录信息非常详细,yolo格式不是通用格式数据,信息损失大
  • VOC格式数据兼容性和移植性较好,可以较好的与其他平台对接,如paddle飞桨、阿里天池等
  • 开源工具基本都支持VOC格式标注
    这里我们使用的是labeling标注工具标注,它支持voc和yolo格式数据。

所以,我们在数据标注的时候,首先选择VOC格式,标注完成后自己协议个python脚本实现VOC格式数据到YOLO格式数据转换即可,这里我已经写好了python脚本,各种问题已经考虑好了,你拿过去用就好了
  1. """
  2. 注意:
  3. 1、首先更改VOC格式根目录路径,然后将生成的images和labels目录
  4. 拷贝到训练数据集目录下(名字自定义)即可
  5. 2、修改classes类别名称列表
  6. 3、配置是否进行文件重命名:batch_rename_voc_samples
  7. """
  8. import xml.etree.ElementTree as ET
  9. import os
  10. import uuid
  11. import shutil
  12. import random
  13. from PIL import Image

  14. # voc中的类别名对应yolo的类别下标
  15. # 改成自己的类别名称,注意类别顺序
  16. classes = ["person", "hat", "reflective_clothes", "other_clothes"]

  17. # 转成yolov5-txt格式图片大小
  18. # yolov5长宽必须是32像素整倍
  19. # yolov5默认大小为640x640
  20. # 为了提高精度建议放大1280x1280
  21. # 摄像机分辨率1280x720
  22. glob_resize_img = False
  23. global_img_size = (1280, 1280)

  24. # 是否对原来的样本文件进行重命名
  25. # 如果文件名为非uuid的文件,建议重命名
  26. # 以免与其他数据文件名相同覆盖(不同分类训练样本粘贴的时候)
  27. batch_rename_voc_samples = False

  28. # VOC图片格式目录根路径
  29. # VOC满足其约定的目录结构
  30. # ROOT(dir)
  31. # --Annotations(存放标注的标签文件(目标真值标注数据,xml格式))
  32. # --ImageSets(类别标签其中包含4个文件夹Action|Layout|Main|Segmentation,识别任务必须有Main)
  33. # --JPEGImages(存放需要打标签的图片文件(图像jpg格式))
  34. voc_root_path = 'D:/datasets/per_hat'
  35. # 添加后斜杠
  36. if not voc_root_path.endswith('\\') and not voc_root_path.endswith('/'):
  37.     voc_root_path += '/'

  38. # voc格式标签文件路径
  39. xml_file_path = voc_root_path + 'Annotations/'

  40. # voc格式标注图片目录
  41. # 最好不要用"images"作文件夹名字,
  42. # 后续会对图片进行划分,命名的新文件夹叫"images"
  43. images_file_path = voc_root_path + 'JPEGImages/'

  44. # 数据集划分比例建议:训练集80%,验证集10%,测试集10%(标准的8:1:1)
  45. train_percent = 0.9
  46. val_percent = 0.1
  47. test_percent = 0.0


  48. # 批量重命名图片(uuid名称)
  49. def rename_images(xml_dir, images_dir):
  50.     # 获取xml文件列表
  51.     xml_file_list = os.listdir(xml_dir)
  52.     # 处理所有xml文件
  53.     for index, fn in enumerate(xml_file_list):
  54.         print(f'正在重命名第{index}个文件:{fn}')
  55.         # 新文件的文件名
  56.         new_name = str(uuid.uuid1()).replace('-', '')
  57.         # 老文件的文件名
  58.         old_name = fn[:-4]
  59.         # xml原文件路径
  60.         xml_oldname = xml_dir + fn
  61.         # xml新文件路径
  62.         xml_newname = xml_dir + new_name + '.xml'
  63.         # 重命名新文件名
  64.         os.rename(xml_oldname, xml_newname)
  65.         # 对应jpeg图片
  66.         jpg_oldname = images_dir + old_name + '.jpg'
  67.         # 对应的jpg图片存在
  68.         if os.path.exists(jpg_oldname):
  69.             # jpg新文件路径
  70.             jpg_newname = images_dir + new_name + '.jpg'
  71.             # 删除老的图片
  72.             os.rename(jpg_oldname, jpg_newname)


  73. # voc盒子型=>中点+宽高
  74. def convert(size, box):
  75.     dw = 1. / size[0]
  76.     dh = 1. / size[1]
  77.     x = (box[0] + box[1]) / 2.0
  78.     y = (box[2] + box[3]) / 2.0
  79.     w = box[1] - box[0]
  80.     h = box[3] - box[2]
  81.     x = x * dw
  82.     w = w * dw
  83.     y = y * dh
  84.     h = h * dh
  85.     return x, y, w, h


  86. # 转换标签文件
  87. def convert_annotations(source_file, dest_file):
  88.     print(f'正在转换文件:{source_file}')
  89.     in_file = open(source_file, encoding='UTF-8')
  90.     out_file = open(dest_file, 'w', encoding='UTF-8')
  91.     tree = ET.parse(in_file)
  92.     root = tree.getroot()
  93.     size = root.find('size')
  94.     w = 0
  95.     h = 0
  96.     if size is not None:
  97.         w = int(size.find('width').text)
  98.         h = int(size.find('height').text)
  99.     # 图片尺寸为0处理
  100.     if 0 == w or 0 == h:
  101.         # xxx.jpg
  102.         name = os.path.basename(source_file)
  103.         name = name[:-4]
  104.         # 获取jpg文件
  105.         image_file = images_file_path + name + '.jpg'
  106.         if not os.path.exists(image_file):
  107.             image_file = images_file_path + name + '.png'
  108.         # 只有xml没有图片
  109.         if not os.path.exists(image_file):
  110.             in_file.close()
  111.             out_file.close()
  112.             os.remove(source_file)
  113.             os.remove(dest_file)
  114.             return
  115.         # 获取图片宽高
  116.         img = Image.open(image_file)
  117.         w, h = img.size
  118.         img.close()

  119.     for obj in root.iter('object'):
  120.         # difficult = obj.find('difficult').text
  121.         cls = obj.find('name').text
  122.         # if cls not in classes or int(difficult) == 1:
  123.         #     continue
  124.         if cls not in classes:
  125.             print(f'class {cls} not in config list')
  126.             continue
  127.         # 类别名转为yolov5的类别索引下标
  128.         cls_id = classes.index(cls)
  129.         # 读取物体识别位置
  130.         xmlbox = obj.find('bndbox')
  131.         b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text),
  132.              float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
  133.         bb = convert((w, h), b)
  134.         out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


  135. # *********************************************** #
  136. #  parent folder
  137. #  --data
  138. #  ----images
  139. #       ----train
  140. #       ----val
  141. #       ----test
  142. #  ----labels
  143. #       ----train
  144. #       ----val
  145. #       ----test
  146. # *********************************************** #
  147. # 创建yolov5格式目录
  148. def create_dir():
  149.     if not os.path.exists(voc_root_path + 'images/'):
  150.         os.makedirs(voc_root_path + 'images/')
  151.     if not os.path.exists(voc_root_path + 'labels/'):
  152.         os.makedirs(voc_root_path + 'labels/')

  153.     if not os.path.exists(voc_root_path + 'images/train/'):
  154.         os.makedirs(voc_root_path + 'images/train')
  155.     if not os.path.exists(voc_root_path + 'images/val/'):
  156.         os.makedirs(voc_root_path + 'images/val/')
  157.     if not os.path.exists(voc_root_path + 'images/test/'):
  158.         os.makedirs(voc_root_path + 'images/test/')

  159.     if not os.path.exists(voc_root_path + 'labels/train/'):
  160.         os.makedirs(voc_root_path + 'labels/train/')
  161.     if not os.path.exists(voc_root_path + 'labels/val/'):
  162.         os.makedirs(voc_root_path + 'labels/val/')
  163.     if not os.path.exists(voc_root_path + 'labels/test/'):
  164.         os.makedirs(voc_root_path + 'labels/test/')
  165.     return


  166. # png转jpg
  167. def png_to_jpg_if_png_exists(jpg_image):
  168.     # 文件不存在
  169.     if not os.path.exists(jpg_image):
  170.         # xxx.jpg
  171.         name = os.path.basename(jpg_image)
  172.         name = name[:-4]
  173.         # png文件
  174.         png_image = images_file_path + name + '.png'
  175.         # png文件也不存在
  176.         if not os.path.exists(png_image):
  177.             print(f'file {jpg_image} not exists')
  178.             return
  179.         # 转行png文件为jpg
  180.         img = Image.open(png_image)
  181.         # 转换为JPG格式图片
  182.         img = img.convert("RGB")
  183.         # 保存为新的jpg格式图片
  184.         img.save(jpg_image)
  185.         # 关闭图片
  186.         img.close()
  187.         # 删除原来的png格式图片
  188.         os.remove(png_image)


  189. # 重置图片大小
  190. def resize_source_image(source_path, dest_path):
  191.     img = None
  192.     try:
  193.         # 打开图片
  194.         img = Image.open(source_path)
  195.         # 放大图片
  196.         image = img.resize(global_img_size)
  197.         # 将新图像保存至桌面
  198.         image.save(dest_path)
  199.     except IOError as e:
  200.         print("缩放图像失败:" + e)
  201.     finally:
  202.         # 关闭图像
  203.         if img is not None:
  204.             img.close()
  205.     pass


  206. # 转行所有数据集
  207. def convert_all_data():
  208.     # 创建yolov5格式目录
  209.     create_dir()

  210.     # 原数据集XML文件列表及总数
  211.     total_xml = os.listdir(xml_file_path)
  212.     num_xml = len(total_xml)

  213.     # 计算训练集、验证集、测试集数量
  214.     num_train = int(num_xml * train_percent)
  215.     num_val = int(num_xml * val_percent)
  216.     num_test = num_xml - num_train - num_val
  217.     print(f"训练集数目:{num_train}, 验证集数目:{num_val},测试集数目:{num_test}")

  218.     # 随机训练集
  219.     train = random.sample(total_xml, num_train)
  220.     # 验证测试集[排除训练集数据]
  221.     val_test = [i for i in total_xml if not i in train]
  222.     # 从训练测试集取出验证集
  223.     val = random.sample(val_test, num_val)
  224.     # 测试集[排除训练集及验证集数据]
  225.     test = [i for i in total_xml if not i in train and not i in val]

  226.     # 开始转换训练集标签
  227.     for index, fn in enumerate(train):
  228.         print(f'正在转换第{index}个训练数据集文件:{fn}')
  229.         # 原来文件名
  230.         old_name = fn[:-4]
  231.         new_name = old_name
  232.         # 重命名文件
  233.         if batch_rename_voc_samples:
  234.             new_name = str(uuid.uuid1()).replace('-', '')
  235.         # 转换xml文件
  236.         xml_old_file = xml_file_path + old_name + '.xml'
  237.         xml_new_file = voc_root_path + 'labels/train/' + new_name + '.txt'
  238.         convert_annotations(xml_old_file, xml_new_file)
  239.         # 拷贝jpg文件
  240.         src_image = images_file_path + old_name + '.jpg'
  241.         dst_image = voc_root_path + 'images/train/' + new_name + '.jpg'
  242.         png_to_jpg_if_png_exists(src_image)
  243.         if os.path.exists(src_image):
  244.             if glob_resize_img:
  245.                 resize_source_image(src_image, dst_image)
  246.             else:
  247.                 shutil.copyfile(src_image, dst_image)

  248.     # 开始转换验证集标签
  249.     for index, fn in enumerate(val):
  250.         print(f'正在转换第{index}个验证数据集文件:{fn}')
  251.         # 原来文件名
  252.         old_name = fn[:-4]
  253.         new_name = old_name
  254.         # 重命名文件
  255.         if batch_rename_voc_samples:
  256.             new_name = str(uuid.uuid1()).replace('-', '')
  257.         # 转换xml文件
  258.         xml_old_file = xml_file_path + old_name + '.xml'
  259.         xml_new_file = voc_root_path + 'labels/val/' + new_name + '.txt'
  260.         convert_annotations(xml_old_file, xml_new_file)
  261.         # 拷贝jpg文件
  262.         src_image = images_file_path + old_name + '.jpg'
  263.         dst_image = voc_root_path + 'images/val/' + new_name + '.jpg'
  264.         png_to_jpg_if_png_exists(src_image)
  265.         if os.path.exists(src_image):
  266.             if glob_resize_img:
  267.                 resize_source_image(src_image, dst_image)
  268.             else:
  269.                 shutil.copyfile(src_image, dst_image)

  270.     # 开始转换测试集标签
  271.     for index, fn in enumerate(test):
  272.         print(f'正在转换第{index}个测试数据集文件:{fn}')
  273.         # 原来文件名
  274.         old_name = fn[:-4]
  275.         new_name = old_name
  276.         # 重命名文件
  277.         if batch_rename_voc_samples:
  278.             new_name = str(uuid.uuid1()).replace('-', '')
  279.         # 转换xml文件
  280.         xml_old_file = xml_file_path + old_name + '.xml'
  281.         xml_new_file = voc_root_path + 'labels/test/' + new_name + '.txt'
  282.         convert_annotations(xml_old_file, xml_new_file)
  283.         # 拷贝jpg文件
  284.         src_image = images_file_path + old_name + '.jpg'
  285.         dst_image = voc_root_path + 'images/test/' + new_name + '.jpg'
  286.         png_to_jpg_if_png_exists(src_image)
  287.         if os.path.exists(src_image):
  288.             if glob_resize_img:
  289.                 resize_source_image(src_image, dst_image)
  290.             else:
  291.                 shutil.copyfile(src_image, dst_image)
  292.     pass


  293. # 开始执行转行
  294. convert_all_data()
复制代码
百度爬虫
模型的训练关键在于数据集的准备,如何弄到我们需要的数据集?其实有很多方面,我这里大概找了几个方法,大部分可以通过网上获取,也可以自己写爬虫从百度爬取(后面我也找了很多数据集获取地址,参见《数据集采集》一页。
百度爬虫我也准备好了,只需执行python脚本然后输入你要搜索的关键词、要下载的图片数量即可下载到对应关键词的图片。
  • 爬虫脚本
    1. """
    2. 百度图库图片抓取
    3. """
    4. import uuid

    5. import requests
    6. import re
    7. from urllib import parse
    8. import os


    9. class ImageSpider(object):
    10.     def __init__(self, save_dir):
    11.         self.url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word={}{}'
    12.         self.headers = {'User-Agent': 'Mozilla/4.0'}
    13.         self.word_parse = ''
    14.         self.save_dir = save_dir
    15.         self.image_count = 1000
    16.         self.i = 1

    17.     # 获取图片递归函数
    18.     def getimage(self, url, word):
    19.         # 使用 requests模块得到响应对象
    20.         res = requests.get(url, headers=self.headers)

    21.         # 更改编码格式
    22.         res.encoding = "utf-8"
    23.         # 得到html网页
    24.         html = res.text
    25.         # print(html)
    26.         # 正则解析
    27.         pattern = re.compile('"hoverURL":"(.*?)"', re.S)
    28.         img_link_list = pattern.findall(html)
    29.         # 存储图片的url链接
    30.         print(img_link_list)

    31.         # 创建目录,用于保存图片
    32.         directory = str(self.save_dir + '/{}').format(word)
    33.         # 如果目录不存在则创建新目录
    34.         if not os.path.exists(directory):
    35.             os.makedirs(directory, mode=0o777, exist_ok=True)

    36.         for img_link in img_link_list:
    37.             filename = '{}/{}_{}.jpg'.format(directory, word, str(uuid.uuid1()))
    38.             self.save_image(img_link, filename)
    39.             self.i += 1
    40.             # 每页只能下载60张图片,这里可以直接跳出,或者按需要的数量更改
    41.             if self.i == self.image_count:
    42.                 print(f'下载完成{self.image_count}张图,退出下载')
    43.                 return
    44.             # 也可以改成翻页下载的形式:
    45.             # self.url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word={}{}'
    46.             # 格式化地址:url = self.url.format(word_parse,'&pn=40')  #这里的pn=20*n
    47.             if self.i % 60 == 0:
    48.                 pn = (int)(self.i / 60 * 20)
    49.                 pagepn = '&pn=' + str(pn)
    50.                 urlnew = self.url.format(self.word_parse, pagepn)
    51.                 print(urlnew)
    52.                 self.getimage(urlnew, word)

    53.     # 保存图片
    54.     def save_image(self, img_link, filename):
    55.         try:
    56.             # https:\\/\\/ns-strategy.cdn.bcebos.com\\/ns-strategy\\/upload\\/fc_big_pic\\/part-00384-1388.jpg
    57.             img_link = img_link.replace("\\/", '/')
    58.             html = requests.get(url=img_link, headers=self.headers).content
    59.             with open(filename, 'wb') as f:
    60.                 f.write(html)
    61.             print(f'下载{img_link}到{filename}成功')
    62.         except Exception as e:
    63.             print(f'下载图片{img_link}异常:{e}')

    64.     # 执行函数
    65.     def run(self):
    66.         word = input("您想要搜索下载的图片关键词?")
    67.         self.word_parse = parse.quote(word)
    68.         count = input("抓取图片最大数量?")
    69.         self.image_count = int(count)
    70.         url = self.url.format(self.word_parse, '&pn=0')
    71.         print(url)
    72.         self.getimage(url, word)


    73. if __name__ == '__main__':
    74.     spiderer = ImageSpider('D:/capture')
    75.     spiderer.run()
    复制代码

  • 使用方式
    进入虚拟环境,或者直接打开命令行,将以上脚本保存为baidu_capture.py脚本名称,然后python执行
    1. #进入虚拟环境
    2. conda activate yolov5
    3. #进入脚本所在目录
    4. cd xxx
    5. #执行脚本
    6. python3 baidu_capture.py
    7. 您想要搜索下载的图片关键词?狗
    8. 抓取图片最大数量?10
    9. https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%E7%8B%97&pn=0
    10. ['https://img2.baidu.com/it/u=3710071795,1935934436&fm=253&fmt=auto&app=120&f=JPEG?w=405&h=607', '', 'https://img0.baidu.com/it/u=355540748,4279750747&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=590', 'https://img1.baidu.com/it/u=2800285962,3144843962&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=708', 'https://img0.baidu.com/it/u=2982112298,332524237&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1422', '', 'https://img0.baidu.com/it/u=899072890,1051003349&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=889', '', '', '', '', '', 'https://img0.baidu.com/it/u=3958984912,1183025142&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500', '', 'https://img0.baidu.com/it/u=709389818,15662528&fm=253&fmt=auto&app=120&f=JPEG?w=888&h=500', '', 'https://img0.baidu.com/it/u=4033153792,1132130660&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750', 'https://img0.baidu.com/it/u=1094067482,1954257272&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=500', '', '', '', '', 'https://img1.baidu.com/it/u=3037065633,3920937498&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500', 'https://img1.baidu.com/it/u=243234235,2932914455&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500', '', 'https://img1.baidu.com/it/u=1644105177,300278054&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=500', 'https://img0.baidu.com/it/u=2423716291,609421818&fm=253&fmt=auto&app=138&f=JPEG?w=666&h=500', 'https://img0.baidu.com/it/u=1847314541,347034172&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=500', '', 'https://img0.baidu.com/it/u=254439336,3029519064&fm=253&fmt=auto&app=120&f=JPEG?w=1255&h=800', 'https://img0.baidu.com/it/u=2350579518,1580042609&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889', '', 'https://img1.baidu.com/it/u=2418131841,3031705877&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=753', 'https://img1.baidu.com/it/u=3918682719,279636889&fm=253&fmt=auto&app=120&f=JPEG?w=970&h=618', 'https://img2.baidu.com/it/u=3125212292,1141242674&fm=253&fmt=auto&app=120&f=JPEG?w=567&h=500', 'https://img2.baidu.com/it/u=1440470319,1200016074&fm=253&fmt=auto&app=120&f=JPEG?w=640&h=427', 'https://img1.baidu.com/it/u=2732463704,821520455&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500', 'https://img1.baidu.com/it/u=704275214,396135592&fm=253&fmt=auto&app=138&f=JPEG?w=667&h=500', 'https://img1.baidu.com/it/u=1496080221,654701152&fm=253&fmt=auto&app=138&f=JPEG?w=333&h=500', 'https://img1.baidu.com/it/u=1496132220,1600902313&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=798', '', '', 'https://img0.baidu.com/it/u=402685873,1458512737&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1437', 'https://img0.baidu.com/it/u=2008945784,3169002842&fm=253&fmt=auto&app=120&f=JPEG?w=608&h=342', '', '', 'https://img2.baidu.com/it/u=1153911856,401197048&fm=253&fmt=auto&app=138&f=JPEG?w=720&h=482', 'https://img2.baidu.com/it/u=4239368062,3794634334&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=667', 'https://img2.baidu.com/it/u=2903268539,2008608892&fm=253&fmt=auto&app=138&f=JPEG?w=667&h=500', 'https://img1.baidu.com/it/u=3097786841,280197815&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=500', 'https://img1.baidu.com/it/u=987977502,1862942488&fm=253&fmt=auto&app=138&f=JPEG?w=813&h=500', 'https://img1.baidu.com/it/u=1099947152,3909189908&fm=253&fmt=auto&app=138&f=JPEG?w=560&h=320', 'https://img1.baidu.com/it/u=722657272,1259482305&fm=253&fmt=auto&app=138&f=JPEG?w=418&h=410', 'https://img0.baidu.com/it/u=3762086336,3971104417&fm=253&fmt=auto&app=138&f=JPEG?w=667&h=500', 'https://img0.baidu.com/it/u=850446474,652694488&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500', 'https://img2.baidu.com/it/u=1432520278,742839924&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750', '', 'https://img0.baidu.com/it/u=1832399488,3142588414&fm=253&fmt=auto&app=138&f=JPG?w=348&h=500', 'https://img0.baidu.com/it/u=199133472,3474349226&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=666', 'https://img0.baidu.com/it/u=3768239988,3053430673&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500', 'https:\\/\\/ns-strategy.cdn.bcebos.com\\/ns-strategy\\/upload\\/fc_big_pic\\/part-00461-2994.jpg']
    11. 下载https://img2.baidu.com/it/u=3710071795,1935934436&fm=253&fmt=auto&app=120&f=JPEG?w=405&h=607到D:/capture/狗/狗_00ada4cc-0572-11ef-871d-94e6f745cd96.jpg成功
    12. 下载图片异常:Invalid URL '': No scheme supplied. Perhaps you meant https://?
    13. 下载https://img0.baidu.com/it/u=355540748,4279750747&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=590到D:/capture/狗/狗_011d3801-0572-11ef-a4bc-94e6f745cd96.jpg成功
    14. 下载https://img1.baidu.com/it/u=2800285962,3144843962&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=708到D:/capture/狗/狗_01925dd7-0572-11ef-9ec1-94e6f745cd96.jpg成功
    复制代码

  • 下载完成后,在D:/capture目录就可以看到《狗》文件夹,文件夹内就包含了对应文件

    基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

    基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

千图爬虫
和百度图库图片爬虫一样,我也写了一个关于千图网的一个爬虫,脚本如下
  1. """
  2. 千图网图库图片抓取
  3. 汉字转拼音:pip install pohan -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
  4. """
  5. import uuid
  6. import requests
  7. import re
  8. from urllib import parse
  9. import os
  10. import pohan
  11. from pohan.pinyin.pinyin import Style


  12. # 判断词语是否为中文
  13. def is_chinese(strings):
  14.     for _char in strings:
  15.         if '\u4e00' <= _char <= '\u9fa5':
  16.             return True


  17. class ImageSpider(object):
  18.     def __init__(self, save_dir):
  19.         # 分页从1开始
  20.         self.url = 'https://www.58pic.com/tupian/{}-852-0-{}.html'
  21.         self.headers = {'User-Agent': 'Mozilla/4.0'}
  22.         self.word_parse = ''
  23.         self.save_dir = save_dir
  24.         self.image_count = 1000
  25.         self.i = 1

  26.     # 获取图片递归函数
  27.     def getimage(self, url, word):
  28.         # 使用 requests模块得到响应对象
  29.         res = requests.get(url, headers=self.headers)
  30.         # 更改编码格式
  31.         res.encoding = "utf-8"
  32.         # 得到html网页
  33.         html = res.text
  34.         # print(html)
  35.         # 正则解析
  36.         pattern = re.compile('data-original="(.*?)"', re.S)
  37.         img_link_list = pattern.findall(html)
  38.         # 存储图片的url链接
  39.         print(img_link_list)

  40.         # 创建目录,用于保存图片
  41.         directory = str(self.save_dir + '/{}').format(word)
  42.         # 如果目录不存在则创建新目录
  43.         if not os.path.exists(directory):
  44.             os.makedirs(directory, mode=0o777, exist_ok=True)

  45.         previous_image = ''
  46.         for img_link in img_link_list:
  47.             # 添加请求前缀https
  48.             img_link = "https:" + img_link
  49.             # 忽略图片是图标图等且与上一张图不相同
  50.             if img_link.find("icon.qiantucdn.com/static") == -1 and previous_image != img_link:
  51.                 # 本地文件路径
  52.                 filename = '{}/{}_{}.jpg'.format(directory, word, str(uuid.uuid1()))
  53.                 self.save_image(img_link, filename)
  54.             # 上一张图地址
  55.             previous_image = img_link
  56.             self.i += 1
  57.             # 每页只能下载60张图片,这里可以直接跳出,或者按需要的数量更改
  58.             if self.i == self.image_count:
  59.                 print(f'下载完成{self.image_count}张图,退出下载')
  60.                 return
  61.             # 也可以改成翻页下载的形式
  62.             if self.i % 77 == 0:
  63.                 pn = (int)(self.i / 77) + 1
  64.                 urlnew = self.url.format(self.word_parse, pn)
  65.                 print(f'请求下一页{urlnew}')
  66.                 self.getimage(urlnew, word)

  67.     # 保存图片
  68.     def save_image(self, img_link, filename):
  69.         try:
  70.             # https:\\/\\/ns-strategy.cdn.bcebos.com\\/ns-strategy\\/upload\\/fc_big_pic\\/part-00384-1388.jpg
  71.             img_link = img_link.replace("\\/", '/')
  72.             html = requests.get(url=img_link, headers=self.headers).content
  73.             with open(filename, 'wb') as f:
  74.                 f.write(html)
  75.             print(f'下载{img_link}到{filename}成功')
  76.         except Exception as e:
  77.             print(f'下载图片{img_link}异常:{e}')

  78.     # 执行函数
  79.     def run(self):
  80.         word = input("您想要搜索下载的图片关键词?")
  81.         # 千图网汉字自动转拼音搜索
  82.         pinyin_list = pohan.pinyin.han2pinyin(word, style=Style.NORMAL)
  83.         key_word = ''
  84.         for item in pinyin_list:
  85.             key_word += item[0]
  86.         self.word_parse = parse.quote(key_word)
  87.         count = input("抓取图片最大数量?")
  88.         self.image_count = int(count)
  89.         url = self.url.format(self.word_parse, '1')
  90.         print(url)
  91.         self.getimage(url, word)


  92. if __name__ == '__main__':
  93.     spider = ImageSpider('D:/capture')
  94.     spider.run()
复制代码
千图网图片可能精准一些,当然可能是数据量没有百度图库的大,但是也是一个不错选择,执行过程和百度一样,这里不在赘述。
注意:
千图网之前的爬虫可以爬,现在发现这个脚本不能用了,应该是静态图片访问千图网做了token访问,还需要登录,人没百度大,心机耍的一溜一溜的,真要命,各位大神请贡献你们自己的其他图库的爬虫,在此为大家感谢你!
测试模型
在源码里我提供了如下几个onnx测试模型,各位可以修改自己的代码,然后使用对应模型进行测试,模型路径见源码
AiBox\3rdparty\model
  • cloth.onnx
    安全帽反光衣模型,默认分类:person,hat,reflective_clothes,other_clothes
  • dao.onnx
    持刀检测模型,模型分类:dao
  • fire.onnx
    火焰检测模型,模型分类:fire
  • helmet.onnx
    安全帽模型,模型分类:hat,person

演示效果AI盒子管理端(web)

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...


AI盒子服务端(C++)
(1)ubuntu系统启动

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...
(2)windows系统启动

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...
AI预警云平台(Sass)

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...

基于yolov8框架,使用C++实现的跨平台目标识别系统,支持windows、linux(Ubuntu或centos)跨平台编译及部 ...


开发环境机器准备
ubuntu、centos、windows、VMware Workstation Pro
本次开源部分为c++版跨平台服务端,开发技术使用cmake、boost、sqlite、opencv、oatpp(http)、oatpp-websocket、spdlog(项目中已有),所以必须先安装对应的软件和必要的库,软件和库请移步此处下载:
链接:https://pan.baidu.com/s/1bPi_l4fKvhZOSducrd4eZw?pwd=ghwm 提取码:ghwm

除了必要的软件之外,我们需要准备一台windows开发机和一台linux开发机器(ubuntu或者centos都可以)
环境准备
vs2019、boost、oatpp、oatpp-websocket、opencv、spdlog
本次实际开发环境为vs2019,各位可以使用vs2019或以上都可以,支持跨平台开发调试工具,各个环境和软件安装详细细节如下所示。
提取码下载:
文件名称:提取码下载.txt 
下载次数:0  文件大小:16 Bytes  售价:499金钱 [记录]
下载权限: 不限 [购买VIP]   [充值]   [在线充值]   【VIP会员6折;永久VIP4折】
安全检测,请放心下载





相关帖子

扫码关注微信公众号,及时获取最新资源信息!下载附件优惠VIP会员5折;永久VIP免费
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明:
1、本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
2、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,请勿任何商业目的与商业用途。
3、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4、论坛的所有内容都不保证其准确性,完整性,有效性,由于源码具有复制性,一经售出,概不退换。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
5、用户使用本网站必须遵守适用的法律法规,对于用户违法使用本站非法运营而引起的一切责任,由用户自行承担
6、本站所有资源来自互联网转载,版权归原著所有,用户访问和使用本站的条件是必须接受本站“免责声明”,如果不遵守,请勿访问或使用本网站
7、本站使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,本站不承担任何责任。
8、凡以任何方式登陆本网站或直接、间接使用本网站资料者,视为自愿接受本网站声明的约束。
9、本站以《2013 中华人民共和国计算机软件保护条例》第二章 “软件著作权” 第十七条为原则:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。若有学员需要商用本站资源,请务必联系版权方购买正版授权!
10、本网站如无意中侵犯了某个企业或个人的知识产权,请来信【站长信箱312337667@qq.com】告之,本站将立即删除。
郑重声明:
本站所有资源仅供用户本地电脑学习源代码的内含设计思想和原理,禁止任何其他用途!
本站所有资源、教程来自互联网转载,仅供学习交流,不得商业运营资源,不确保资源完整性,图片和资源仅供参考,不提供任何技术服务。
本站资源仅供本地编辑研究学习参考,禁止未经资源商正版授权参与任何商业行为,违法行为!如需商业请购买各资源商正版授权
本站仅收集资源,提供用户自学研究使用,本站不存在私自接受协助用户架设游戏或资源,非法运营资源行为。
 
在线客服
点击这里给我发消息 点击这里给我发消息 点击这里给我发消息
售前咨询热线
312337667

微信扫一扫,私享最新原创实用干货

QQ|免责声明|小黑屋|依星资源网 ( 鲁ICP备2021043233号-3 )|网站地图

GMT+8, 2024-12-23 00:02

Powered by Net188.com X3.4

邮箱:312337667@qq.com 客服QQ:312337667(工作时间:9:00~21:00)

快速回复 返回顶部 返回列表