关注我,并留言,不定期送各种c++资料
代码全部在下面,就一个文件,随便添加一个空项目后就可以将下面代码替换到工程中。具体操作步骤没时间过多的写,可以看注释。代码运行没有问题,我用的是opencv344和vs2017。需要源代码和资料的请在这里下载,在我的工程里面环境已经配置好https://download.csdn.net/download/qq_41476542/12305236
代码如下:
#include
#include
#include
using namespace std;//命名空间std
using namespace cv;//命名空间cvv b
string int2str(const int &int_temp)//数据流之间的转换
{
stringstream stream;//通过流来实现字符串和数字的转换
string string_temp;//有不限长度的优点
stream << int_temp; //将int输入流,向左移4位
string_temp = stream.str(); //此处也可以用 stream>>string_temp//从stream中抽取前面插入的int值
return string_temp;
} int main(int argc, const char** argv)
{
VideoCapture cap;//打开摄像头对象
bool update_bg_model = true;
cap.open(0);
// cap.open("http://113.57.246.23:8080/shot.jpg");
cap.open("C:\\Users\\Administrator\\Desktop\\acvis09-5950.avi");
//cap.open("D:\\qq\\demo\\vtest.avi");
if (!cap.isOpened())
{
printf("can not open camera or video file\n");
return -1;
}
namedWindow("image", WINDOW_AUTOSIZE);
namedWindow("foreground mask", WINDOW_AUTOSIZE);//保持原图大小
namedWindow("foreground image", WINDOW_AUTOSIZE);//
namedWindow("mean background image", WINDOW_AUTOSIZE);//原图大小
Ptr bg_model = createBackgroundSubtractorMOG2();//(100, 3, 0.3, 5);建立背景模型
Mat img, fgmask, fgimg;//定义矩阵
int i = 0;
for (;;)//死循环
{
i++;
cap >> img;//由capture类输出图像
if (img.empty())
break;
img = img(Rect(40, 0, 300, img.rows));
if (fgimg.empty())
fgimg.create(img.size(), img.type());
//更新模型
bg_model->apply(img, fgmask, update_bg_model ? -1 : 0);//背景模型的跟新
medianBlur(fgmask, fgmask, 13);//有效抑制噪声的中值滤波函数,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值。输入图像输出图像尺寸大小,必须是大于1的奇数,如3、5、7……
threshold(fgmask, fgmask, 150, 255, THRESH_BINARY);//# 阈值化,将非纯白色(244~255)的所有像素设为0
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));// # 为了使效果更好,进行一次膨胀
/*erode(fgmask, fgmask, element, Point(0, 0), 3);
dilate(fgmask, fgmask, element, Point(0, 0), 3);*/
Mat srcGrayImage = fgmask.clone();
vector> vContours;
vector vHierarchy;
// # 检测轮廓
findContours(srcGrayImage, vContours, vHierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE, Point(0, 0));
int count = 0;
RNG rng(12345);//构造方法设定一个具体值,表示下面代码每次生成的结果都是一样的
for (int i = 0; i < vContours.size(); i++)
{
double area = contourArea(vContours[i], false);
//RotatedRect该类表示平面上的旋转矩形,该类对象有三个重要属性:
//矩形中心点(质心),边长(长和宽),旋转角度。三种构造函数和三种成员操作函数
RotatedRect smallRect = minAreaRect(vContours[i]);
/* RotatedRect该类表示平面上的旋转矩形,有三个属性:
矩形中心点(质心)
边长(长和宽)
旋转角度
*/
Point2f smallRect_center = smallRect.center;
float smallRect_width = smallRect.size.width;
float smallRect_height = smallRect.size.height;
float smallRect_angle = 0;
smallRect = RotatedRect(smallRect_center, Size2f(smallRect_height, smallRect_width), smallRect_angle);
//若使用Point2f,这里就使用flow1_at_point.x形式存取像素值
Point2f P[4];
//points()函数用于求矩形的4个顶点,
smallRect.points(P);
if (area>600 && area < 3000)
{
count++;
for (int j = 0; j <= 3; j++)
{
//划线,绘制在img上
line(img, P[j], P[(j + 1) % 4], Scalar(255, 0, 0), 2);
}
}
if (area>3000&& area < 5000)
{
count += 2;
for (int j = 0; j <= 3; j++)
{
line(img, P[j], P[(j + 1) % 4], Scalar(255, 0, 0), 2);
}
}
}
//任意值
//数数的颜色
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
//写字参数1:, Mat& img,待写字的图片,我们写在img图上
/*参数2:,const string& text,待写入的字,我们下面写入Hello
参数3:, Point org, 第一个字符左下角坐标,我们设定在图片的Point(50, 60)坐标。表示x = 50, y = 60。
参数4:,int fontFace,字体类型,FONT_HERSHEY_SIMPLEX ,FONT_HERSHEY_PLAIN ,FONT_HERSHEY_DUPLEX 等等等。
参数5:,double fontScale,字体大小,我们设置为2号
参数6:,Scalar color,字体颜色,颜色用Scalar()表示,不懂得去百度。
参数7:, int thickness,字体粗细,我们下面代码使用的是4号
参数8:, int lineType,线型,我们使用默认值8.*/
putText(img, int2str(count), Point(220, 40), FONT_HERSHEY_TRIPLEX, 1, color, 2);
//设定所有的值为0.
得到前景
fgimg = Scalar::all(0);
img.copyTo(fgimg, fgmask);
Mat bgimg;
得到背景
bg_model->getBackgroundImage(bgimg);//?
imshow("image", img);
/*string windows_name = "Video/image_" + int2str(i);
string windows_name_ext = windows_name + ".jpg";
imwrite(windows_name_ext, img);*/
imshow("foreground mask", fgmask);
imshow("foreground image", fgimg);
//是否图像读入
if (!bgimg.empty())
imshow("mean background image", bgimg);
char k = (char)waitKey(1);
if (k == 27) break;
if (k == ' ')
{
update_bg_model = !update_bg_model;
if (update_bg_model)
printf("\t>背景更新(Background update)已打开\n");
else
printf("\t>背景更新(Background update)已关闭\n");
}
}
return 0;
}