閱讀370 返回首頁    go 阿裏雲 go 技術社區[雲棲]


取出視頻中有移動物體的幀

實用小程序:


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


最後更新:2017-04-03 05:40:03

  上一篇:go 
  下一篇:go android ndk之hello world