#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;
}
}
#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;
}
}