IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 使用OpenCV进行视频背景估计 -> 正文阅读

[人工智能]使用OpenCV进行视频背景估计

简 介: 本文给出了一个估计视频背景 的简便可靠的算法,对于固定镜头下的视频,包含有少量移动物体,可以通过中值滤波的方式来获得图像的背景图像。再借助于帧间差可以获得图像中移动物体的掩膜,进一步进行物体检测、跟踪和识别。

关键词 背景建模帧间差

简 介
目 录
Contents
时间中值滤波
中值背景估计
利用中值进
行背景估计
背景估计代码
帧间差
总 结

本文根据 Simple Background Estimation in Videos using OpenCV (C++/Python) 中的内容整理而得。

?

§00 ??介

??在很多计算机视觉应用场合,你所能支配的计算机算力不够用的。这种情况下,我们需要使用有效简单的图像处理技术。

??针对于固定相机,且镜头中存在移动物体的场景中对背景进行估计应用中,本文将会讨论相关的技术。这种应用场景实际并不少见。举例来说,对于很多交通监控摄像头都是固定不同的。

注意,本文中的代码在OpenCV 4.4中进行测试的。

0.1 时间中值滤波

??为了便于理解本文后面算法,我们先考虑一个 1D 的简单问题。

??假定我们需要估计一个每隔10ms的物理量(比如房间内的温度)。比如,房间温度是70华氏度。

▲ 图1.1  房间温度测量曲线

▲ 图1.1 房间温度测量曲线

??在上面图表中,我们显示了两个温度计测量曲线一个温度计是好的,另外一个有点毛病。

??左边曲线显示了来自于好的温度计测量曲线,其中包含了定义水平的高斯噪声。为了得到更加准确的温度值,我们可以把几秒钟之内的数值求平均。既然高速噪声具有正和负的取值,所以简单的平均计算便可以消除噪声的影响。实际上,这个特例中平均值为70.01华氏度。

??存在故障的温度计,则不然,它在大多数情况下输出的数值和好的温度计是相同的。但有时候抽风,输出完全错误的数值。

??实际上,如果我们仍然采用取平均的算法,坏的温度计输出数值为71.07华氏度,显然温度值估计偏高了。

??这种情况下还能够获得温度的精确估计吗?

??答案是:可以的。如果数据存在“野值”,也就是完全错误的数值,使用数据的中值可以对需要估计的数值产生更加可靠稳定的估计。

??所谓的中值就是对所有数据按照升序,或者降序进行排列的时候的中间取值。

??上述坏的温度计数据如果使用中值滤波所得到的温度为70.05华氏度,比71.07的平均数值要好。

??中值计算的唯一确定就是比起平均算法所需要的算力更多。

?

§01 值背景估计


1.1 利用中值进行背景估计

??现在我们回到对于静止相机所拍摄的视频背景估计的问题上来。我们可以假设在大多数情况下每个像素都看到相同地点的北京,这是因为相机是固定的。偶然情况下,汽车或者其他移动物体经过前面挡住了背景。

??对于视频序列,我们可以随机选择一些视频帧(比如25帧,大约1秒钟)。换而言之,对于每个图像中的像素我们都有了25次的估计值。由于图像中每个像素没有被移动物体或者车辆遮挡的时间超过50%,所以25帧图像中所有像素中值就是对于背景的最好估计。

??对于图像中每个像素都使用中值进行估计,便可以得到一个中值图像,它代表了场景的背景。

1.2 背景估计代码

??下面让我们看看实际的代码。

  • Python
import numpy as np
import cv2
from skimage import data, filters

# Open Video
cap = cv2.VideoCapture('video.mp4')

# Randomly select 25 frames
frameIds = cap.get(cv2.CAP_PROP_FRAME_COUNT) * np.random.uniform(size=25)

# Store selected frames in an array
frames = []
for fid in frameIds:
    cap.set(cv2.CAP_PROP_POS_FRAMES, fid)
    ret, frame = cap.read()
    frames.append(frame)

# Calculate the median along the time axis
medianFrame = np.median(frames, axis=0).astype(dtype=np.uint8)    

# Display median frame
cv2.imshow('frame', medianFrame)
cv2.waitKey(0)
  • C++
#include <opencv2/opencv.hpp>
#include <iostream>
#include <random>

using namespace std;
using namespace cv;

??下面我们需要创建几个函数来计算中值图像帧。

int computeMedian(vector<int> elements) 
{
  nth_element(elements.begin(), elements.begin()+elements.size()/2, elements.end());

  //sort(elements.begin(),elements.end());
  return elements[elements.size()/2];
}

cv::Mat compute_median(std::vector<cv::Mat> vec) 
{
  // Note: Expects the image to be CV_8UC3
  cv::Mat medianImg(vec[0].rows, vec[0].cols, CV_8UC3, cv::Scalar(0, 0, 0));

  for(int row=0; row<vec[0].rows; row++) 
  {
    for(int col=0; col<vec[0].cols; col++) 
    {
      std::vector<int> elements_B;
      std::vector<int> elements_G;
      std::vector<int> elements_R;

      for(int imgNumber=0; imgNumber<vec.size(); imgNumber++) 
      {
        int B = vec[imgNumber].at<cv::Vec3b>(row, col)[0];
        int G = vec[imgNumber].at<cv::Vec3b>(row, col)[1];
        int R = vec[imgNumber].at<cv::Vec3b>(row, col)[2];

        elements_B.push_back(B);
        elements_G.push_back(G);
        elements_R.push_back(R);
      }

      medianImg.at<cv::Vec3b>(row, col)[0]= computeMedian(elements_B);
      medianImg.at<cv::Vec3b>(row, col)[1]= computeMedian(elements_G);
      medianImg.at<cv::Vec3b>(row, col)[2]= computeMedian(elements_R);
    }
  }
  return medianImg;
}
int main(int argc, char const *argv[])
{
  std::string video_file;
  // Read video file
  if(argc > 1)
  {
    video_file = argv[1];
  } else 
  {
    video_file = "video.mp4";
  }

  VideoCapture cap(video_file);
  if(!cap.isOpened())
    cerr << "Error opening video file\n";

  // Randomly select 25 frames
  default_random_engine generator;
  uniform_int_distribution<int>distribution(0, 
  cap.get(CAP_PROP_FRAME_COUNT));

  vector<Mat> frames;
  Mat frame;

  for(int i=0; i<25; i++) 
  {
    int fid = distribution(generator);
    cap.set(CAP_PROP_POS_FRAMES, fid);
    Mat frame;
    cap >> frame;
    if(frame.empty())
      continue;
    frames.push_back(frame);
  }
  // Calculate the median along the time axis
  Mat medianFrame = compute_median(frames);

  // Display median frame
  imshow("frame", medianFrame);
  waitKey(0);
}

??正如你所看到的,我们随机选择了25帧图片, 计算每个像素在25帧中的中值,这个中值帧就是对于背景的很好的估计。这是因为每个像素至少在50%的时间中是背景图像。

??下面显示了背景结果。

▲ 图1.1  通过计算式25帧每个像素对应的中值组成了对于背景的估计

▲ 图1.1 通过计算式25帧每个像素对应的中值组成了对于背景的估计

?

§02 间差


??明显,下一个问题就是我们是否可以对每一帧获得一个移动物体的掩膜(mask)。

??可以通过以下步骤来完成:
??1. 将背景帧转换成灰度图;
??2. 对于视频中的所有帧, 转换成对应的灰度图;
??3. 计算机当前帧的灰度图与背景帧之间的差异的绝对值;
??4. 通过阈值判断、噪声去除、二值化最终获得输出结果。

??下面是对应的程序代码:

  • Python
# Reset frame number to 0
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

# Convert background to grayscale
grayMedianFrame = cv2.cvtColor(medianFrame, cv2.COLOR_BGR2GRAY)

# Loop over all frames
ret = True
while(ret):

  # Read frame
  ret, frame = cap.read()
  # Convert current frame to grayscale
  frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  # Calculate absolute difference of current frame and 
  # the median frame
  dframe = cv2.absdiff(frame, grayMedianFrame)
  # Treshold to binarize
  th, dframe = cv2.threshold(dframe, 30, 255, cv2.THRESH_BINARY)
  # Display image
  cv2.imshow('frame', dframe)
  cv2.waitKey(20)

# Release video object
cap.release()

# Destroy all windows
cv2.destroyAllWindows()
  • C++
//  Reset frame number to 0
cap.set(CAP_PROP_POS_FRAMES, 0);

// Convert background to grayscale
Mat grayMedianFrame;
cvtColor(medianFrame, grayMedianFrame, COLOR_BGR2GRAY);

// Loop over all frames
while(1) 
{
  // Read frame
  cap >> frame;

  if (frame.empty())
    break;

  // Convert current frame to grayscale
  cvtColor(frame, frame, COLOR_BGR2GRAY);

  // Calculate absolute difference of current frame and the median frame
  Mat dframe;
  absdiff(frame, grayMedianFrame, dframe);

  // Threshold to binarize
  threshold(dframe, dframe, 30, 255, THRESH_BINARY);

  // Display Image
  imshow("frame", dframe);
  waitKey(20);
}

  cap.release();
  return 0;
}

?

??结 ※


??文给出了一个估计视频背景 的简便可靠的算法,对于固定镜头下的视频,包含有少量移动物体,可以通过中值滤波的方式来获得图像的背景图像。再借助于帧间差可以获得图像中移动物体的掩膜,进一步进行物体检测、跟踪和识别。

??对于图像中移动物体比较多,频繁,可以中值滤波无法准确获得背景。则可以采用:


■ 相关文献链接:

● 相关图表链接:

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:12:38  更:2022-02-03 01:13:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 20:31:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码