OpenCV:前景背景分离

前景背景分离

#include <spdlog/spdlog.h>

#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>

namespace zhjr {
namespace utils {
/**
 * @brief 前景背景分割
 * @param video_file 视频文件
 * @param method knn、mog2
 * @return
 */
bool segmFGBG(const std::string& video_file, std::string method = "knn") {
  SPDLOG_LOGGER_INFO(spdlog::default_logger(), "开始前景背景分割");

  cv::VideoCapture cap(video_file);
  if (!cap.isOpened()) {
    SPDLOG_LOGGER_ERROR(spdlog::default_logger(), "打开视频失败:{}",
                        video_file);
    return false;
  }
  SPDLOG_LOGGER_INFO(spdlog::default_logger(), "打开视频成功:{}", video_file);

  cv::UMat frame, fgmask, fgimg;

  cv::Ptr<cv::BackgroundSubtractorKNN> knn =
      cv::createBackgroundSubtractorKNN();
  cv::Ptr<cv::BackgroundSubtractorMOG2> mog2 =
      cv::createBackgroundSubtractorMOG2();

  while (true) {
    cap >> frame;
    if (frame.empty()) {
      break;
    }

    int64 start = cv::getTickCount();

    if (method == "knn") {
      SPDLOG_LOGGER_INFO(spdlog::default_logger(), "前景背景分割:KNN");
      knn->apply(frame, fgmask);
    } else if (method == "mog2") {
      SPDLOG_LOGGER_INFO(spdlog::default_logger(), "前景背景分割:MOG2");
      mog2->apply(frame, fgmask);
    }

    double fps = cv::getTickFrequency() / (cv::getTickCount() - start);
    SPDLOG_LOGGER_INFO(spdlog::default_logger(), "FPS: {}", fps);

    fgimg.create(frame.size(), frame.type());
    fgimg.setTo(cv::Scalar::all(0));
    frame.copyTo(fgimg, fgmask);

    cv::imshow("frame", frame);
    cv::imshow("fgmask", fgmask);
    cv::imshow("fgimg", fgimg);
    cv::waitKey(28);
  }

  cv::destroyAllWindows();

  SPDLOG_LOGGER_INFO(spdlog::default_logger(), "完成前景背景分割");

  return true;
}
}  // namespace utils
}  // namespace zhjr

int main(int argc, char* argv[]) {
  zhjr::utils::segmFGBG("../data/vtest.avi", "mog2");

  return EXIT_SUCCESS;
}

输出结果:
在这里插入图片描述

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
k-means算法是一种常用的无监督学习算法,用于将数据集划分为K个不同的簇。在彩色图像前景背景分割中,可以使用k-means算法将图像中的像素点分为前景背景两个簇。 以下是一个基于Matlab的k-means彩色图像前景背景分割的简单代码示例: ```matlab % 读取彩色图像 image = imread('image.jpg'); % 转换图像为Lab颜色空间 lab_image = rgb2lab(image); % 从Lab颜色空间中提取a和b通道 ab_channels = lab_image(:, :, 2:3); % 扁平化ab通道,仅保留两个通道的像素信息 ab_channels = reshape(ab_channels, [], 2); % 颜色通道标准化 ab_channels = double(ab_channels) / 255; % 使用k-means算法将像素点分为两个簇,即前景背景 % 这里我们取K=2 k = 2; [cluster_idx, ~] = kmeans(ab_channels, k); % 将像素点重新组织为原始图像的大小 segmented_image = reshape(cluster_idx, size(lab_image, 1), size(lab_image, 2)); % 显示分割结果 figure; subplot(1, 2, 1); imshow(image); title('原始图像'); subplot(1, 2, 2); imagesc(segmented_image); title('分割结果'); colormap jet; % 显示分割结果的前景背景 foreground = segmented_image == 2; background = segmented_image == 1; figure; subplot(1, 3, 1); imshow(image); title('原始图像'); subplot(1, 3, 2); imshow(foreground); title('前景'); subplot(1, 3, 3); imshow(background); title('背景'); ``` 这段代码首先读取彩色图像,并将其转换为Lab颜色空间。然后,将a和b通道从Lab图像中提取出来,并将其扁平化为一个Nx2的矩阵。然后,利用k-means算法将这些像素点分为两个簇,即前景背景。最后,将分割结果重新组织为原始图像的大小,并将其显示出来。同时,将分割结果中的前景背景提取出来,并显示在单独的图像中。 这只是一个简单的示例,实际应用中可能需要对图像进行预处理、调整算法参数以及进行后处理等步骤,以提高分割的准确性和鲁棒性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值