前景背景分离
#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;
}
输出结果: