Opencv视频特定区域人数统计(在人物重叠时效果不佳)

#include <opencv\highgui.h>
#include<opencv\cxcore.h>
#include<opencv2\core.hpp>
#include<iostream>
#include <vector> 
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <sstream>
#include "opencv2/opencv.hpp"  
#include "opencv2/video/background_segm.hpp"  
#include <iostream>    
#include <string>     
#include <opencv2/opencv.hpp>    


using namespace cv;
using namespace std;
using namespace cv::ml;
bool drawing_box = false;
static Scalar randomColor(RNG& rng);
bool gotBox = false;
Rect box;
Point downPoint;
vector<Rect> found, found_filtered;
Mat removeLight(Mat imge, Mat pattern, int method);
Mat calculateLightPattern(Mat img);
void mouseRectHandler(int event, int x, int y, int flags, void *param);




int main(int argc, char** argv)
{
Mat img;
Mat frame, mask, output;
int time = 0;
vector<vector<Point>> contours;
vector<Rect> people;
VideoCapture cap;
//cap.open("G:\\Youku Files\\transcode\\test02.avi");
cap.open("E:\\opencv-for-window\\opencv\\sources\\samples\\data\\test03.avi");
Ptr<BackgroundSubtractorMOG2> bgsubtractor = createBackgroundSubtractorMOG2();
bgsubtractor->setVarThreshold(20);
//定义HOG对象,采用默认参数,或者按照下面的格式自己设置
//HOGDescriptor defaultHog;
//(cv::Size(64, 128), cv::Size(16, 16), cv::Size(8, 8), 
//cv::Size(8, 8),9, 1, -1, 
//cv::HOGDescriptor::L2Hys, 0.2, true, 
//cv::HOGDescriptor::DEFAULT_NLEVELS);


//设置SVM分类器,用默认分类器
// defaultHog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());


//对图像进行多尺度行人检测,返回结果为矩形框
namedWindow("video", 1);
setMouseCallback("video", mouseRectHandler, NULL);
for (;;)
{
//读取视频的第一帧    
cap >> img;
if (!img.data)
break;
rectangle(img, box, Scalar(255, 255, 0), 2);//画出感兴趣区域  
imshow("video", img);
if (gotBox)
break;
if (waitKey(50) == 'q')//---------很重要    
break;
}
//remove callback    
setMouseCallback("video", NULL, NULL);
for (;;)
{
int peopleNumber = 0;
//读取视频   
cap >> img;
//判断是否有当前帧  
if (!img.data)
break;
//画出感兴趣区域  
rectangle(img, box, Scalar(0, 255, 0), 2);

Mat roi;
img(box).copyTo(roi);
bgsubtractor->apply(roi, mask, 0.01);
medianBlur(mask, mask, 3);
pyrDown(mask, mask);
dilate(mask,mask,0.1);
pyrUp(mask,mask);
findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
vector<vector<Point>>::const_iterator itContours = contours.begin();
/* for (; itContours != contours.end(); ++itContours) {
cout << "Size: " << itContours->size() << endl;//每个轮廓包含的点数
cout << "-----一帧" << endl;
}*/
Mat put = Mat::zeros(mask.rows, mask.cols, CV_8UC3);
RNG rng(0xFFFFFFFF);
for (int i = 0; i < contours.size(); i++){
drawContours(put, contours, i, randomColor(rng));
imshow("Result", put);
}
Mat cimage = Mat::zeros(mask.size(), CV_8UC3);


for (size_t i = 0; i < contours.size(); i++)
{
//轮廓的边缘点个数  
size_t count = contours[i].size();
//Fitzgibbon的椭圆拟合方法,要求至少6个点  
if (count < 40)
continue;


Mat pointsf;
//将轮廓中的点转换为以Mat形式存储的2维点集(x,y)  
Mat(contours[i]).convertTo(pointsf, CV_32F);


//最小二次拟合(Fitzgibbon的方法)  
//box包含了椭圆的5个参数:(x,y,w,h,theta)  
RotatedRect box = fitEllipse(pointsf);


//把那些长轴与短轴之比很多的那些椭圆剔除。  
if (MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height) * 8)
continue;
//绘制轮廓  
drawContours(cimage, contours, (int)i, Scalar::all(255), 1, 8);
// cout << contours.size << "--contours" << endl;
//绘制椭圆  
ellipse(cimage, box, Scalar(0, 0, 255), 1, CV_AA);

double mj = box.size.width*box.size.height*0.5;
if (mj > 800) {
peopleNumber++;


}


Point2f vtx[4];


box.points(vtx);
for (int j = 0; j < 4; j++) {
line(cimage, vtx[j], vtx[(j + 1) % 4], Scalar(0, 255, 0), 1, CV_AA);
}


}
stringstream ss;
ss << "n:" << peopleNumber;

Point pt(10, 20);
Scalar color = CV_RGB(255, 0, 0);
putText(img, ss.str(), pt, CV_FONT_HERSHEY_DUPLEX, 0.7f, color);
imshow("video2", roi);
imshow("video", img);
cout << "-------------------------------" << peopleNumber<< endl;
imshow("mask", cimage);

peopleNumber = 0;


if (waitKey(33) == 'q')
break;
}






img.release();
cap.release();
return 0;
}
Mat removeLight(Mat imge, Mat pattern, int method) {
Mat aux;
if (method == 1) {
Mat img32, pattern32;
imge.convertTo(img32, CV_32F);
pattern.convertTo(pattern32, CV_32F);
aux = 1 - (img32 / pattern32);
aux = aux * 255;
aux.convertTo(aux, CV_8U);
}
else {
aux = pattern - imge;
}
return aux;
}








Mat calculateLightPattern(Mat img) {
Mat pattern;
blur(img, pattern, Size(img.cols / 3, img.cols / 3));
return pattern;
}
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng;
return Scalar(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
}
void ConnectedComponents(Mat img) {
Mat lables;
int num_objects = connectedComponents(img, lables);
}




void mouseRectHandler(int event, int x, int y, int flags, void *param)
{
switch (event)
{
case CV_EVENT_MOUSEMOVE:
if (drawing_box)
{
//鼠标的移动到downPoint的右下角  
if (x >= downPoint.x && y >= downPoint.y)
{
box.x = downPoint.x;
box.y = downPoint.y;
box.width = x - downPoint.x;
box.height = y - downPoint.y;
}
//鼠标的移动到downPoint的右上角  
if (x >= downPoint.x && y <= downPoint.y)
{
box.x = downPoint.x;
box.y = y;
box.width = x - downPoint.x;
box.height = downPoint.y - y;
}
//鼠标的移动到downPoint的左上角  
if (x <= downPoint.x && y <= downPoint.y)
{
box.x = x;
box.y = y;
box.width = downPoint.x - x;
box.height = downPoint.y - y;
}
//鼠标的移动到downPoint的左下角  
if (x <= downPoint.x && y >= downPoint.y)
{
box.x = x;
box.y = downPoint.y;
box.width = downPoint.x - x;
box.height = y - downPoint.y;
}
}
break;


case CV_EVENT_LBUTTONDOWN:
//按下鼠标,代表可以可以开始画矩形  
drawing_box = true;
//记录起点  
downPoint = Point(x, y);
break;


case CV_EVENT_LBUTTONUP:


//松开鼠标,代表结束画矩形  
drawing_box = false;
gotBox = true;
break;
default:
break;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值