【opencv3】透视变换后帧差法检测运动物体C++

简介: 【opencv3】透视变换后帧差法检测运动物体C++

实现目标


在透视变换的基础上,利用帧差法检测运动物体,并用矩形框出。


程序


#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>  
using namespace cv;
using namespace std;
Mat MoveDetect(Mat temp, Mat frame);
void onMouse(int event, int x, int y, int flags, void *utsc);
Point2f srcTri[4], dstTri[4];
int clickTimes = 0;
Mat imageWarp;
Mat frame;
int main()
{
  VideoCapture video("H:\\test.mp4");
  if (!video.isOpened())
  return -1;
  video.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
  video.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
  while (1)
  {
  int frameCount = video.get(CV_CAP_PROP_FRAME_COUNT);//获取帧数  
  double FPS = video.get(CV_CAP_PROP_FPS);//获取FPS  
  Mat temp;//存储前一帧图像  
  Mat result;//存储结果图像  
  for (int i = 0; i < frameCount; i++)
  {
    video.read(frame);
    if (frame.empty())//异常检测  
    {
    cout << "frame is empty!" << endl;
    break;
    }
    if (i == 0)//如果为第一帧(temp为空)  
    {
    result = MoveDetect(frame, frame);
    }
    else//若不是第一帧(temp有值)  
    {
    result = MoveDetect(temp, frame);
    }
    temp = frame.clone();
    imshow("result", result);
    setMouseCallback("Source Image", onMouse);
    imshow("Source Image", frame);
  }
  }
  return 0;
}
void onMouse(int event, int x, int y, int flags, void *utsc)
{
  if (event == CV_EVENT_LBUTTONUP)//响应鼠标左键抬起事件
  {
  circle(frame, Point(x, y), 2.5, Scalar(0, 0, 255), 2.5);//标记选中点
  imshow("Source Image", frame);
  srcTri[clickTimes].x = x;
  srcTri[clickTimes].y = y;
  cout << "x: " << x << "  y: " << y << endl;
  clickTimes++;
  }
  if (clickTimes == 4)
  {
  //注意点的顺序:左上,右上,左下,右下
  dstTri[0].x = 0;
  dstTri[0].y = 0;
  dstTri[1].x = frame.rows - 1;
  dstTri[1].y = 0;
  dstTri[2].x = 0;
  dstTri[2].y = frame.cols - 161;
  dstTri[3].x = frame.rows - 1;
  dstTri[3].y = frame.cols - 161;
  Mat transform = Mat::zeros(3, 3, CV_32FC1);//透视变换矩阵
  transform = getPerspectiveTransform(srcTri, dstTri);//获取透视变换矩阵  
  warpPerspective(frame, imageWarp, transform, Size(frame.rows, frame.cols - 160));//透视变换
  imshow("After WarpPerspecttive", imageWarp);
  }
}
Mat MoveDetect(Mat temp, Mat frame)
{
  Mat result = frame.clone();
  //1.将background和frame转为灰度图  
  Mat gray1, gray2;
  cvtColor(temp, gray1, CV_BGR2GRAY);
  cvtColor(frame, gray2, CV_BGR2GRAY);
  //2.将background和frame做差  
  Mat diff;
  absdiff(gray1, gray2, diff);
  // imshow("2_diff", diff);
  //3.对差值图diff_thresh进行阈值化处理  
  Mat diff_thresh;
  threshold(diff, diff_thresh, 50, 255, CV_THRESH_BINARY);
  // imshow("3_diff_thresh", diff_thresh);
  //4.腐蚀  
  Mat kernel_erode = getStructuringElement(MORPH_RECT, Size(3, 3));
  Mat kernel_dilate = getStructuringElement(MORPH_RECT, Size(5, 5));
  erode(diff_thresh, diff_thresh, kernel_erode);
  // imshow("4_erode", diff_thresh);
  //5.膨胀  
  dilate(diff_thresh, diff_thresh, kernel_dilate);
  // imshow("5_dilate", diff_thresh);
  //6.查找轮廓并绘制轮廓  
  vector<vector<Point> > contours;
  findContours(diff_thresh, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
  // drawContours(result, contours, -1, Scalar(0, 0, 255), 2);//在result上绘制轮廓      
  //7.查找正外接矩形  
  vector<Rect> boundRect(contours.size());
  for (int i = 0; i < contours.size(); i++)
  {
  boundRect[i] = boundingRect(contours[i]);
  if (contours[i].size() > 500)//过滤掉较小的矩形
    rectangle(result, boundRect[i], Scalar(0, 255, 0), 2);//在result上绘制正外接矩形  
  }
  return result;
}
相关文章
|
2月前
|
并行计算 算法 数据可视化
基于OpenCV C++实现的光流法目标检测
基于OpenCV C++实现的光流法目标检测
|
5月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
151 0
|
机器学习/深度学习 监控 算法
基于计算机视觉(opencv)的运动计数(运动辅助)系统-源码+注释+报告
基于计算机视觉(opencv)的运动计数(运动辅助)系统-源码+注释+报告
384 3
|
计算机视觉
Opencv学习笔记(八):如何通过cv2读取视频和摄像头来进行人脸检测(jetson nano)
如何使用OpenCV库通过cv2模块读取视频和摄像头进行人脸检测,并提供了相应的代码示例。
434 1
|
11月前
|
XML 机器学习/深度学习 人工智能
使用 OpenCV 和 Python 轻松实现人脸检测
本文介绍如何使用OpenCV和Python实现人脸检测。首先,确保安装了OpenCV库并加载预训练的Haar特征模型。接着,通过读取图像或视频帧,将其转换为灰度图并使用`detectMultiScale`方法进行人脸检测。检测到的人脸用矩形框标出并显示。优化方法包括调整参数、多尺度检测及使用更先进模型。人脸检测是计算机视觉的基础技术,具有广泛应用前景。
483 10
|
11月前
|
存储 程序员 编译器
什么是内存泄漏?C++中如何检测和解决?
大家好,我是V哥。内存泄露是编程中的常见问题,可能导致程序崩溃。特别是在金三银四跳槽季,面试官常问此问题。本文将探讨内存泄露的定义、危害、检测方法及解决策略,帮助你掌握这一关键知识点。通过学习如何正确管理内存、使用智能指针和RAII原则,避免内存泄露,提升代码健壮性。同时,了解常见的内存泄露场景,如忘记释放内存、异常处理不当等,确保在面试中不被秒杀。最后,预祝大家新的一年工作顺利,涨薪多多!关注威哥爱编程,一起成为更好的程序员。
493 0
|
机器学习/深度学习 计算机视觉
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
本文介绍了如何使用OpenCV进行特定区域的目标检测,包括人脸检测实例,展示了两种实现方法和相应的代码。
374 1
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
2391 3
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
185 11
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
140 3