取出视频中有移动物体的帧

简介:

实用小程序:


//opencv2.0风格

//本程序有几个可调值
//1.背景更新 学习率 learningRate
//2.去掉小面积阈值 area_threshold

#include "cv.h"
#include "highgui.h"
#include <stdlib.h>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>

#include <iostream>
#include <string>
#include <cstdio>

using namespace std;
using namespace cv;

char input_name[50];
char outFolder[50];
char countChar[10000];
char tmp[50];


int main()
{
	//可调参数
	//char* input_name = "007.avi";
	double fScale = 0.5;      //缩放倍数
	double learningRate=0.5;    // 控制背景累积学习的速率
	double area_threshold = 30;  //区域面积大小阈值
	int nThreshold=30; //二值化阈值


	Mat frame_ori;		//每一帧原图像,绝不处理
	Mat frame;		//每一帧图像处理
	Mat gray;		//frame转成的灰度图
	Mat frame_copy_8U;	//copy过来的8U图像
	Mat frame_copy;
	Mat img1;		//差分输出
	Mat outBinary; //二值图输出

	//输入
	cout<<"please input the src video :"<<endl;
	cin>>input_name;
	cout<<"please input the output folder :"<<endl;
	cin>>outFolder;

	//从视频读入
	VideoCapture capture(input_name);

	int count=0;
	if(capture.isOpened()/*capture*/)	//读取文件开关
	{
		//对每一帧做处理

		for(;;)
		{

			//单帧处理

			capture >> frame_ori;
			if(!frame_ori.empty())//如果捕捉到了
			{
				cout<<"\n\n***************New Start********************"<<endl;


				//将原图像缩放
				//resize(frame_ori,frame,Size(frame_ori.cols * fScale,frame_ori.rows * fScale),0,0,CV_INTER_LINEAR);
				frame=frame_ori;

				//frame->gray 单通道灰度图
				cvtColor(frame, gray, CV_BGR2GRAY);

				//进行处理
				if (frame_copy.empty())
				{
					//记录第一帧 gray->frame_copy
					gray.convertTo(frame_copy, CV_32F);
				}

				frame_copy.convertTo(frame_copy_8U, CV_8U);
				//差分
				absdiff(frame_copy_8U, gray, img1);


				//二值化
				threshold(img1, outBinary, nThreshold, 255, THRESH_BINARY);

				accumulateWeighted(gray, frame_copy,learningRate,outBinary);


				//加一个中值滤波,会减少不少误差
				cv::medianBlur(outBinary, outBinary,3);


				//轮廓检测
				vector<vector<Point>> _contours;//储存所有轮廓
				vector<Vec4i>hierarchy;

				Mat imageROI;;
				cv::findContours( outBinary, _contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

				int contoursSize=0;
				for(size_t i = 0; i< _contours.size(); ++i)
				{
					//遍历所有轮廓

					//计算轮廓面积
					double contArea =  fabs(contourArea(_contours[i]));

					//去除较小面积的轮廓
					if( contArea < area_threshold)
						continue;

					//获得外接矩形
					Rect r0 = boundingRect(Mat(_contours[i]));

					//实时画出每个矩形
					rectangle(outBinary,r0,cvScalar(255,255,255),1,8,0);

					contoursSize++;
				}

				cout<<"轮廓数 == "<<contoursSize<<endl;
				if(contoursSize!=0)
				{
					strcpy(countChar,outFolder);
					strcat(countChar,"\\");
					//cout<<countChar<<endl;
					//cout<<"有了有了!!!!!!!!"<<endl;
					count++;
					itoa(count,tmp,10);
					strcat(tmp,".jpg");
					strcat(countChar,tmp);
					//cout<<countChar<<endl;
					imwrite(countChar,frame_ori);
				}
				

				imshow("src", frame);
				imshow("outBinary", outBinary);
			}

			else
			{ 
				printf(" --(!) No captured frame -- Break!");
				break;
			}

			//10ms中按任意键进入此if块
			if( cvWaitKey( 10 ) >= 0 )
				break;
		}
	}

	return 0;
}


相关文章
|
7天前
|
传感器
CAN 帧有哪些类型
CAN帧主要有五种类型:数据帧,用于传输数据;远程帧,用于请求数据;错误帧,表示检测到错误;过载帧,表示接收器需要延时;帧间隔,用于分隔不同的帧。
|
7天前
|
编解码 算法
为什么受损的视频数据通常显示为绿色?为什么很多30帧/秒的视频实际都是29.976帧/秒?
视频编码采用YUV格式因其亮度与色度分离,利于压缩且兼容黑白显示;受损视频常显绿色因YUV转RGB时Y、U、V为0导致;30帧/秒视频实为29.976帧/秒源于NTSC标准适应彩色电视需求;H.264等标准中H无特定含义,H.264又名MPEG-4 AVC,是ITU-T与ISO/IEC MPEG合作成果。
|
12天前
|
编解码 缓存 算法
视频帧里的I帧、P帧、B帧是什么?
I帧、P帧、B帧是视频编码中的基本概念。I帧是帧内编码帧,无需参考其他帧即可解码;P帧是前向预测编码帧,基于前一帧解码;B帧是双向预测编码帧,基于前后帧解码。IDR帧是一种特殊的I帧,用于即时解码刷新,防止错误传播。GOP(Group of Pictures)是一组连续的画面,第一个帧为I帧,gop_size设置越大,画质越好,但解码延迟增加。OpenGOP允许GOP间的帧依赖,而ClosedGOP则不允许。DTS(解码时间戳)和PTS(显示时间戳)分别用于解码和显示时间控制。
|
6月前
|
网络协议
计算机网络四种帧介绍,广播帧、未知帧、同网帧、异网帧
计算机网络四种帧介绍,广播帧、未知帧、同网帧、异网帧
|
机器学习/深度学习 传感器 算法
【视频处理】通过调用图像来重建新影片及计算颜色通道的平均灰度值,并检测帧与前一帧之间的差异(Matlab代码实现)
【视频处理】通过调用图像来重建新影片及计算颜色通道的平均灰度值,并检测帧与前一帧之间的差异(Matlab代码实现)
随机乱序图像
随机乱序图像
97 0
随机乱序图像
|
机器学习/深度学习 并行计算 算法
MMFlow :帧与帧之间的追光者
光流(Optical Flow),字面理解为“光的流动”,更准确的说法为:时变图像上的二维运动场,是视频数据的重要视觉线索,在动作识别、视频理解、视频分割、目标跟踪以及全景拼接等领域,都有广泛应用。
617 0
MMFlow :帧与帧之间的追光者
为什么电影24帧就够了,游戏60帧还要提高?
这个问题亦困扰了吾很久。后来找了一篇文章,感觉自己看明白了。在此总结一下。
126 0
|
计算机视觉 Linux 传感器
Kinect2.0-空间长度测量
1. 鼠标左键按下选择起点,拖动鼠标,左键放开,确定终点。 实现效果1 实现效果2 2. 在linux下使用libfreenect2开源多平台驱动来获取kinect2.0的传感器信息,得到深度信息,并通过libfreenect2提供的getPointXYZ函数,来得到相机坐标系中某一点的空间坐标。
1713 0