Fast SAM与YOLOV8检测模型一起使用实现实例分割以及指定物体分割(有代码)

这篇具有很好参考价值的文章主要介绍了Fast SAM与YOLOV8检测模型一起使用实现实例分割以及指定物体分割(有代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Fast SAM与YOLOV8检测模型一起使用
VX 搜索”晓理紫“ 关注并回复yolov8+fastsam获取核心代码
晓理紫

1 使用场景

实例分割数据集的获取要比检测数据的获取更加困难,在已有检测模型不想从新标注分割数据进行训练但是又想获取相关物体的mask信息以便从像素级别对物体进行操作,这时就可以把检测模型与FastSAM模型配合进行时候实现分割的效果。

2 检测加分割效果

2.1 检测+分割

Fast SAM与YOLOV8检测模型一起使用实现实例分割以及指定物体分割(有代码),机器学习,YOLO

2.2 分割指定物体(分割交通灯,汽车,公交车)

Fast SAM与YOLOV8检测模型一起使用实现实例分割以及指定物体分割(有代码),机器学习,YOLO

3 部署使用

3.1 检测模型

这里使用的检测模型使用YOLOV8,使用TensorRT对YOLOV8进行部署

  • 部署条件

安装YOLOv8环境,可按照git进行配置

需要配置TensorRt相关环境,需要有显卡,安装驱动,CUDA以及TensorRT

需要把原始权重模型转为trt模型

2.2 trt模型转换

trt模型转换有多种方式,本文采用的是先把pt模型转成onnx模型参考,再把onnx通过trtexec工具进行转换。转换命令如下:

yolo mode=export model=yolov8s.pt  format=onnx dynamic=False
trtexec --onnx=yolov8.onnx --saveEngine=yolov8.engine 

注意: trtexec -h查看帮助,转fp16或者int8等参数
部署核心代码

模型转换完成以后,剩下的就是部署推理。部署推理里面最为重要也是最难搞的是数据解析部分。其中模型加载是很标准的流程,当然我这里不一定是标准的。

  • 加载模型并初始化核心代码
  cudaSetDevice(DEVICE);
  INPUT_W = input_w;
  INPUT_H = input_h;
  in_size = 1 * 3 * INPUT_W * INPUT_H;
  w = INPUT_W;
  h = INPUT_H;
  std::ifstream file(engine_file_path, std::ios::binary);
  assert(file.good());
  file.seekg(0, std::ios::end);
  auto size = file.tellg();
  std::ostringstream fmt;

  file.seekg(0, std::ios::beg);
  char *trtModelStream = new char[size];
  assert(trtModelStream);
  file.read(trtModelStream, size);
  file.close();
  initLibNvInferPlugins(&this->gLogger, "");
  this->runtime = nvinfer1::createInferRuntime(this->gLogger);
  assert(this->runtime != nullptr);

  this->engine = this->runtime->deserializeCudaEngine(trtModelStream, size);
  assert(this->engine != nullptr);

  this->context = this->engine->createExecutionContext();

  assert(this->context != nullptr);
  cudaStreamCreate(&this->stream);
  const nvinfer1::Dims input_dims =
      this->engine->getBindingDimensions(this->engine->getBindingIndex(INPUT));
  this->in_size = get_size_by_dims(input_dims);
  CHECK(cudaMalloc(&this->buffs[0], this->in_size * sizeof(float)));

  this->context->setBindingDimensions(0, input_dims);
  const int32_t num_dets_idx = this->engine->getBindingIndex(NUM_DETS);
  const nvinfer1::Dims num_dets_dims =
      this->context->getBindingDimensions(num_dets_idx);
  this->out_sizes[num_dets_idx - NUM_INPUT].first =
      get_size_by_dims(num_dets_dims);
  this->out_sizes[num_dets_idx - NUM_INPUT].second =
      DataTypeToSize(this->engine->getBindingDataType(num_dets_idx));

  const int32_t bboxes_idx = this->engine->getBindingIndex(BBOXES);
  const nvinfer1::Dims bboxes_dims =
      this->context->getBindingDimensions(bboxes_idx);

  this->out_sizes[bboxes_idx - NUM_INPUT].first = get_size_by_dims(bboxes_dims);
  this->out_sizes[bboxes_idx - NUM_INPUT].second =
      DataTypeToSize(this->engine->getBindingDataType(bboxes_idx));

  const int32_t scores_idx = this->engine->getBindingIndex(SCORES);
  const nvinfer1::Dims scores_dims =
      this->context->getBindingDimensions(scores_idx);
  this->out_sizes[scores_idx - NUM_INPUT].first = get_size_by_dims(scores_dims);
  this->out_sizes[scores_idx - NUM_INPUT].second =
      DataTypeToSize(this->engine->getBindingDataType(scores_idx));

  const int32_t labels_idx = this->engine->getBindingIndex(LABELS);
  const nvinfer1::Dims labels_dims =
      this->context->getBindingDimensions(labels_idx);
  this->out_sizes[labels_idx - NUM_INPUT].first = get_size_by_dims(labels_dims);
  this->out_sizes[labels_idx - NUM_INPUT].second =
      DataTypeToSize(this->engine->getBindingDataType(labels_idx));

  for (int i = 0; i < NUM_OUTPUT; i++) {
    const int osize = this->out_sizes[i].first * out_sizes[i].second;
    CHECK(cudaHostAlloc(&this->outputs[i], osize, 0));
    CHECK(cudaMalloc(&this->buffs[NUM_INPUT + i], osize));
  }
  if (warmup) {
    for (int i = 0; i < 10; i++) {
      size_t isize = this->in_size * sizeof(float);
      auto *tmp = new float[isize];

      CHECK(cudaMemcpyAsync(this->buffs[0], tmp, isize, cudaMemcpyHostToDevice,
                            this->stream));
      this->xiaoliziinfer();
    }
  }

模型加载以后,就可以送入数据进行推理

  • 送入数据并推理
  float height = (float)image.rows;
  float width = (float)image.cols;

  float r = std::min(INPUT_H / height, INPUT_W / width);

  int padw = (int)std::round(width * r);
  int padh = (int)std::round(height * r);

  if ((int)width != padw || (int)height != padh) {
    cv::resize(image, tmp, cv::Size(padw, padh));
  } else {
    tmp = image.clone();
  }

  float _dw = INPUT_W - padw;
  float _dh = INPUT_H - padh;

  _dw /= 2.0f;
  _dh /= 2.0f;
  int top = int(std::round(_dh - 0.1f));
  int bottom = int(std::round(_dh + 0.1f));
  int left = int(std::round(_dw - 0.1f));
  int right = int(std::round(_dw + 0.1f));
  cv::copyMakeBorder(tmp, tmp, top, bottom, left, right, cv::BORDER_CONSTANT,
                     PAD_COLOR);
  cv::dnn::blobFromImage(tmp, tmp, 1 / 255.f, cv::Size(), cv::Scalar(0, 0, 0),
                         true, false, CV_32F);
  CHECK(cudaMemcpyAsync(this->buffs[0], tmp.ptr<float>(),
                        this->in_size * sizeof(float), cudaMemcpyHostToDevice,
                        this->stream));
  this->context->enqueueV2(buffs.data(), this->stream, nullptr);
  for (int i = 0; i < NUM_OUTPUT; i++) {
    const int osize = this->out_sizes[i].first * out_sizes[i].second;
    CHECK(cudaMemcpyAsync(this->outputs[i], this->buffs[NUM_INPUT + i], osize,
                          cudaMemcpyDeviceToHost, this->stream));
  }
  cudaStreamSynchronize(this->stream);
                        

推理以后就可以获取数据并进行解析

  • 数据获取并进行解析
  int *num_dets = static_cast<int *>(this->outputs[0]);
  auto *boxes = static_cast<float *>(this->outputs[1]);
  auto *scores = static_cast<float *>(this->outputs[2]);
  int *labels = static_cast<int *>(this->outputs[3]);
  for (int i = 0; i < num_dets[0]; i++) {
    float *ptr = boxes + i * 4;
    Object obj;
    float x0 = *ptr++ - this->dw;
    float y0 = *ptr++ - this->dh;
    float x1 = *ptr++ - this->dw;
    float y1 = *ptr++ - this->dh;

    x0 = clamp(x0 * this->ratio, 0.f, this->w);
    y0 = clamp(y0 * this->ratio, 0.f, this->h);
    x1 = clamp(x1 * this->ratio, 0.f, this->w);
    y1 = clamp(y1 * this->ratio, 0.f, this->h);
    if (!filterClass.empty() &&
        std::find(filterClass.begin(), filterClass.end(), int(*(labels + i))) ==
            filterClass.end())
      continue;
    if (x0 < 0 || y0 < 0 || x1 > this->w || y1 > this->h || (x1 - x0) <= 0 ||
        (y1 - y0) <= 0)
      continue;
    obj.rect.x = x0;
    obj.rect.y = y0;
    obj.rect.width = x1 - x0;
    obj.rect.height = y1 - y0;
    obj.prob = *(scores + i);
    obj.label = *(labels + i);
    obj.pixelBox.push_back(std::vector<float>{x0, y0});
    obj.pixelBox.push_back(std::vector<float>{x1, y1});
    obj.pixelBoxCent = std::vector<float>{(x0 + x1) / 2, (y0 + y1) / 2};
    obj.className = CLASS_NAMES[int(obj.label)];
    const std::vector<float> box = {x0, y0, x1, y1};
    cv::Mat maskmat;
  • 获取对应物体mask(前提已经使用FastSAM进行推理)
  float boxarea = (box[2] - box[0]) * (box[3] - box[1]);
  std::tuple<float, float, float, float> mapkey;
  float maxIoU = FLT_MIN;
  for (auto mapdata : boxMaskMat) {
    cv::Mat maskmat = mapdata.second;
    if (maskmat.rows == 0 || maskmat.cols == 0)
      continue;
    float orig_masks_area = cv::sum(maskmat)[0];
    cv::Rect roi(box[0], box[1], box[2] - box[0], box[3] - box[1]);
    cv::Mat temmask = maskmat(roi);
    float masks_area = cv::sum(temmask)[0];
    float union_arrea = boxarea + orig_masks_area - masks_area;
    float IoUs = masks_area / union_arrea;
    if (IoUs > maxIoU) {
      maxIoU = IoUs;
      mapkey = mapdata.first;
    }
  }
  mask = boxMaskMat[mapkey].clone();

  • 对物体进行过滤

这里对物体进行过滤,主要采取的方式是在检测模块获取物体信息时对物体标签进行过滤。

3.2 FastSAM分割模型

FastSAM分割模型的部署可以参考这篇。

3.3效果视频

效果视频

3 核心代码

VX 搜索”晓理紫“ 关注并回复yolov8+fastsam获取核心代码

晓理紫记录学习!文章来源地址https://www.toymoban.com/news/detail-648043.html

到了这里,关于Fast SAM与YOLOV8检测模型一起使用实现实例分割以及指定物体分割(有代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于YOLOV8模型的西红柿目标检测系统(PyTorch+Pyside6+YOLOv8模型)

    摘要:基于YOLOV8模型的西红柿目标检测系统可用于日常生活中检测与定位西红柿目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据集,使用Pysdie6库来搭

    2024年02月11日
    浏览(47)
  • 基于YOLOv8模型的深海鱼目标检测系统(PyTorch+Pyside6+YOLOv8模型)

    摘要:基于YOLOv8模型和BDD数据集的自动驾驶目标检测系统可用于日常生活与海洋中检测与定位深海鱼目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据

    2024年02月07日
    浏览(43)
  • YOLOv8初体验:检测、跟踪、模型部署

    YOLOv8 有两种安装方式,一种是直接用 pip 命令安装: 另外一种是通过源码安装: 安装完成后就可以通过 yolo 命令在命令行进行使用了。 使用 YOLOv8 进行目标检测,可以使用下面的命令: 如果模型权重不存在,程序会自动从GitHub中下载。如果对命令行的参数不了解,可以参考

    2024年02月03日
    浏览(38)
  • 基于YOLOv8模型的五类动物目标检测系统(PyTorch+Pyside6+YOLOv8模型)

    摘要:基于YOLOv8模型的五类动物目标检测系统可用于日常生活中检测与定位动物目标(狼、鹿、猪、兔和浣熊),利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训

    2024年02月12日
    浏览(43)
  • 基于YOLOV8模型的农作机器和行人目标检测系统(PyTorch+Pyside6+YOLOv8模型)

    摘要:基于YOLOV8模型的农作机器和行人目标检测系统可用于日常生活中检测与定位农作机和行人目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据集,

    2024年02月10日
    浏览(57)
  • 从0开始yolov8模型目标检测训练

    首先有大环境,即已经准备好了python、nvidia驱动、cuda、cudnn等。 2.1 创建虚拟环境 2.2 激活虚拟环境 注意:激活虚拟环境的时候,需要清楚自己创建的虚拟环境(yolov8)是在root权限下,还是在user权限下,否则,当使用source activate yolov8激活环境的时候,可能一直会提示Could n

    2024年02月12日
    浏览(43)
  • 【目标检测】YOLOV8实战入门(五)模型预测

    predict 模式用于在新图像或视频上使用经过训练的 YOLOv8 模型进行预测,在此模式下,模型从 checkpoint 文件加载,用户可以提供图像或视频来执行推理。模型预测输入图像或视频中对象的类别和位置。 YOLOv8 预测模式可以为各种任务生成预测,在使用流模式时返回结果对象列表

    2024年02月06日
    浏览(61)
  • 目标检测再升级!YOLOv8模型训练和部署

    YOLOv8 是 Ultralytics 开发的 YOLO(You Only Look Once)物体检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的SOTA模型,它建立在先前YOLO成功基础上,并引入了新功能和改进,以进一步提升性能和灵活性。它可以在大型数据集上进行训练,并且能够在各种硬件平台上运行

    2024年01月20日
    浏览(48)
  • 基于YOLOv8模型和DarkFace数据集的黑夜人脸检测系统(PyTorch+Pyside6+YOLOv8模型)

    摘要:基于YOLOv8模型和DarkFace数据集的黑夜人脸检测系统可用于日常生活中检测与定位黑夜下的人脸,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据集,

    2024年02月11日
    浏览(41)
  • 基于YOLOV8模型和CCPD数据集的车牌目标检测系统(PyTorch+Pyside6+YOLOv8模型)

    摘要:基于YOLOV8模型和CCPD数据集的车牌目标检测系统可用于日常生活中检测与定位车牌目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据集,使用Py

    2024年02月10日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包