/*
基于高斯混合建模(MOG2)+光流法,实现车辆测速
*/
#include <iostream>
#include <sstream>
#include <string.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/video/video.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/video/tracking.hpp>
#include <cmath>
#include <vector>
#include <typeinfo>
#include <opencv2/video/background_segm.hpp>
#include <time.h>
using namespace std;
using namespace cv;
/*计算车速*/
double get_speed(cv::Mat& frame, int index, vector<Point>& contour, Point2f center, float radius, vector<Point2f> prevContourCenters, double fps)
{
int meters = 30;
int maxSpeed = 100;
if (center.x > 5 && center.x < 480){
for (size_t i = 0; i < prevContourCenters.size(); i++)
{
//if (prevContourCenters[i].x < center.x){
if (prevContourCenters[i].y < center.y)
{
//double diff = center.x - prevContourCenters[i].x;
double diff = center.y - prevContourCenters[i].y;
cv::Point x, y;
int fontFace = 3;
double fontScale = 0.5;
int thickness = 1.8;
Point textOrg(center.x - 20, center.y - radius - 5);
String str2 = " km/h";
double speed = diff*fps / 300 * meters*3.6;
if (speed > 100)
speed = 101;
std::stringstream strSpeed;
strSpeed << speed;
if (speed > maxSpeed){
//在图像上显示车速,保存超速车辆图片
cv::putText(frame, strSpeed.str()+str2, textOrg, fontFace, fontScale, Scalar(0, 255, 0), thickness, 5);
imwrite("image.jpg", frame);
}
else {
cout << "Speed =" << strSpeed.str() + str2 << endl;
cv::putText(frame, strSpeed.str() + str2, textOrg, fontFace, fontScale, Scalar(0, 255, 0), thickness, 5);
}
return speed;
}
}
}
}
int main(int argc, char *argv[])
{
//车辆数量
int count;
//车辆轮廓面积、宽高比
double area, ar;
//当前处理帧,未处理前的图像
Mat frame;
//高斯混合模型分割出的前景
Mat fore;
//当前处理帧(双边滤波后图像)
Mat img;
//当前帧的上一帧图像
Mat prevImg;
//灰度图像
Mat gray;
//灰度图像转换成CV_8UC1类型
Mat temp;
//保存车辆ROI图像
Mat vehicle_ROI;
//获取到视频的第一帧原始图像
Mat img_temp;
//打开视频文件
VideoCapture cap("test.mp4");
if (!cap.isOpened())
{
cout << "打开视频文件失败" << endl;
return -1;
}
//创建高斯混合模型,用于检测视频中的移动目标(车辆)
Ptr<BackgroundSubtractorMOG2> bg = createBackgroundSubtractorMOG2(500, 25, false);
vector<vector<Point> > contours;
vector<Point2f> prevContoursCenters;
vector<Point2f> tempContoursCenters;
vector<Rect> cars;
//获取第一帧
cap >> img_temp;
//RGB转灰度化
cvtColor(img_temp, gray, CV_BGR2GRAY);
//转换成CV_8UC1类型
gray.convertTo(temp, CV_8U);
//双边滤波,可以滤除图像数据中的噪声
bilateralFilter(temp, prevImg, 5, 20, 20);
//开始和结束时间,用于计时
time_t start, end;
// 帧率,表示帧数/秒
double fps;
// 当前帧数
int counter = 0;
// 从开始到当前时间的秒数,用浮点数表示
double sec;
//开始计时
time(&start);
while (true)
{
count = 0;
cap >> frame;
if (frame.empty())
break;
//imshow("Frame", frame);
//waitKey(2);
//灰度化
cvtColor(frame, gray, CV_BGR2GRAY);
//转换为CV_8UC1类型
gray.convertTo(temp, CV_8U);
//双边滤波
bilateralFilter(temp, img, 5, 20, 20);
//计算前景mask
bg->apply(img, fore);
//腐蚀图片
erode(fore, fore, Mat());
//膨胀、扩大图片
dilate(fore, fore, Mat());
//查找轮廓
findContours(fore, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Point2f> center(contours.size());
vector<float> radius(contours.size());
tempContoursCenters.clear();
time(&end);
//计算当前帧率
++counter;
//开始到结束经历的时间
sec = difftime(end, start);
//帧率=帧数/时间
fps = counter / sec;
for (size_t i = 0; i < contours.size(); i++)
{
//对轮廓进行多边形拟合
approxPolyDP(Mat(contours[i]), contours_poly[i], 10, true);
//最小外接矩形
boundRect[i] = boundingRect(Mat(contours_poly[i]));
//保存车辆ROI图像
vehicle_ROI = img(boundRect[i]);
//计算车辆轮廓面积
area = contourArea(contours[i], false);
//宽高比
ar = vehicle_ROI.cols / vehicle_ROI.rows;
//面积过滤,将符合阈值范围内的车辆轮廓绘制出来并计算出车速值
if (area > 450.0 && ar > 0.8)
{
//最小外接圆,求出圆心坐标和半径
minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]);
//绘制矩形
rectangle(frame, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 1, 8, 0);
tempContoursCenters.push_back(center[i]);
//计算出车速值
get_speed(frame, i, contours[i], center[i], radius[i], prevContoursCenters, fps);
count = count + 1;
}
}
stringstream ss;
ss << count;
//显示内容
string s = ss.str();
//字体类型
int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
double fontScale = 1; //字体大小
int thickness = 3; //字体粗细
cv::Point textOrg(10, 110);
cv::putText(frame, s, textOrg, fontFace, fontScale, Scalar(255, 255, 255), thickness, 5);
int win_size = 10;
int maxCorners = 200;
double qualityLevel = 0.5;
double minDistance = 1;
int blockSize = 3;
double k = 0.04;
vector<Point2f> img_corners;
img_corners.reserve(maxCorners);
vector<Point2f> prevImg_corners;
prevImg_corners.reserve(maxCorners);
//角点检测,获得像素精度角点坐标
goodFeaturesToTrack(img, img_corners, maxCorners, qualityLevel, minDistance, Mat(), blockSize, true);
//获得亚像素精度角点坐标
cornerSubPix(img, img_corners, Size(win_size, win_size), Size(-1, -1),
TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03));
vector<uchar> features_found;
features_found.reserve(maxCorners);
vector<float> feature_errors;
feature_errors.reserve(maxCorners);
//Lukas-Kanade光流,用于车辆跟踪
calcOpticalFlowPyrLK(img, prevImg, img_corners, prevImg_corners, features_found, feature_errors,
Size(win_size, win_size), 3,
cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.3), 0, k);
// for( int i=0; i < features_found.size(); i++ ){
// Point2f p0( ceil( img_corners[i].x ), ceil( img_corners[i].y ) );
// Point2f p1( ceil( prevImg_corners[i].x ), ceil( prevImg_corners[i].y ) );
// line( frame, p0, p1, CV_RGB(255,0,0), 5 );
// }
prevImg = img;
prevContoursCenters.clear();
prevContoursCenters = tempContoursCenters;
//显示结果
namedWindow("Frame");
imshow("Frame", frame);
if (waitKey(1) >= 0)
break;
}
//销毁所有窗口
destroyAllWindows();
system("PAUSE");
}

诗眼天涯
- 粉丝: 31
- 资源: 15
最新资源
- 之前面试别的做底层开发的候选人时候,问的一些面试问题,相对比较基本的一些
- ssm390基于java_ssm+jsp的进销存管理系统设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm280基于java_ssm+vue的本科生导师指导平台设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm388基于java_ssm+vue的校内互助交易平台设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm389基于java_ssm+vue的校园活动资讯网设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm279基于java_ssm+jsp的酒店客房管理系统设计实现(代码+数据库+毕业论文+答辩PPT+开题报告+演示录像+运行教学+软件部署).zip
- ssm278基于java_ssm+vue的web在线教学质量评价系统的设计实现(代码+数据库+毕业论文+开题报告+演示录像+运行教学+软件部署).zip
- ssm391基于java_ssm+jsp的网络财务网站设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm282基于java_ssm+vue的学生学情预警系统设计实现(代码+数据库+毕业论文+开题报告+演示录像+运行教学+软件部署).zip
- ssm393基于java_ssm+vue的基于html5济南旅游网站设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm281基于java_ssm+vue的电脑测评系统设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm283基于java_ssm+jsp的高校宿舍管理系统设计实现(代码+数据库+毕业论文+答辩PPT+演示录像+运行教学+软件部署).zip
- ssm392基于java_ssm+jsp的思途旅游管理系统设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- Cocos Creator 2D游戏开发入门基础教程
- ssm286基于java_ssm+vue的电脑公司财务管理系统设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
- ssm395基于java_ssm+vue的基于BS论文管理系统设计实现(代码+数据库+毕业论文+演示录像+运行教学+软件部署).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


