【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)的运动计数(运动辅助)系统-源码+注释+报告
基于计算机视觉(opencv)的运动计数(运动辅助)系统-源码+注释+报告
62 3
|
2月前
|
计算机视觉
Opencv学习笔记(八):如何通过cv2读取视频和摄像头来进行人脸检测(jetson nano)
如何使用OpenCV库通过cv2模块读取视频和摄像头进行人脸检测,并提供了相应的代码示例。
127 1
|
2月前
|
机器学习/深度学习 计算机视觉
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
本文介绍了如何使用OpenCV进行特定区域的目标检测,包括人脸检测实例,展示了两种实现方法和相应的代码。
84 1
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
|
2月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
546 3
|
3月前
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
69 11
|
2月前
|
算法 计算机视觉 Python
圆形检测算法-基于颜色和形状(opencv)
该代码实现了一个圆检测算法,用于识别视频中的红色、白色和蓝色圆形。通过将图像从RGB转换为HSV颜色空间,并设置对应颜色的阈值范围,提取出目标颜色的区域。接着对这些区域进行轮廓提取和面积筛选,使用霍夫圆变换检测圆形,并在原图上绘制检测结果。
95 0
|
3月前
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
33 3
|
5月前
|
机器学习/深度学习 传感器 算法
OpenCV4工业缺陷检测的六种方法
OpenCV4工业缺陷检测的六种方法
|
6月前
|
计算机视觉
opencv之形态变换
opencv之形态变换
|
6月前
|
存储 编解码 算法
【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
111 0