370
技術社區[雲棲]
取出視頻中有移動物體的幀
實用小程序:
//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