#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <sstream>
#include <iomanip>
using namespace std;
using namespace cv;
class FrameProcessor{
public:
virtual void process(Mat &input, Mat &ouput) = 0;
};
class BGFGSegmentor : public FrameProcessor{
Mat gray;//当前帧灰度图
Mat background;//背景图,格式为32位浮点
Mat backImage;//CV_8U格式背景图
Mat foreground;//前景图
double learningRate;//学习率
int threshold;//阈值,滤去扰动
public:
BGFGSegmentor() :threshold(30), learningRate(0.6){}
//帧处理函数
void process(Mat &frame, Mat &output){
//转化为灰度图
cvtColor(frame, gray, CV_BGR2GRAY);
if (background.empty())
//第一帧
gray.convertTo(background, CV_32F);
//背景转为CV_8U格式以便求取和当前帧差的绝对值
background.convertTo(backImage, CV_8U);
//求当前帧与背景的差别
absdiff(backImage, gray, foreground);
//过滤掉前景中与背景差别不大的扰动点
cv::threshold(foreground, output, threshold, 255, THRESH_BINARY_INV);
//更新背景,output作为掩码
accumulateWeighted(gray, background, learningRate, output);
}
};
class VideoProcessor{
private:
VideoCapture caputure;
//写视频流对象
VideoWriter writer;
//输出文件名
string Outputfile;
int currentIndex;
int digits;
string extension;
FrameProcessor *frameprocessor;
//图像处理函数指针
void(*process)(Mat &, Mat &);
bool callIt;
string WindowNameInput;
string WindowNameOutput;
//延时
int delay;
long fnumber;
//第frameToStop停止
long frameToStop;
//暂停标志
bool stop;
//图像序列作为输入视频流
vector<string> images;
//迭代器
public:
VideoProcessor() : callIt(true), delay(0), fnumber(0), stop(false), digits(0), frameToStop(-1){}
//设置图像处理函数
void setFrameProcessor(void(*process)(Mat &, Mat &)){
frameprocessor = 0;
this->process = process;
CallProcess();
}
//打开视频
bool setInput(string filename){
fnumber = 0;
//若已打开,释放重新打开
caputure.release();
return caputure.open(filename);
}
//设置输入视频播放窗口
void displayInput(string wn){
WindowNameInput = wn;
namedWindow(WindowNameInput);
}
//设置输出视频播放窗口
void displayOutput(string wn){
WindowNameOutput = wn;
namedWindow(WindowNameOutput);
}
//销毁窗口
void dontDisplay(){
destroyWindow(WindowNameInput);
destroyWindow(WindowNameOutput);
WindowNameInput.clear();
WindowNameOutput.clear();
}
//启动
void run(){
Mat frame;
Mat output;
if (!isOpened())
return;
stop = false;
while (!isStopped()){
//读取下一帧
if (!readNextFrame(frame))
break;
if (WindowNameInput.length() != 0)
imshow(WindowNameInput, frame);
//处理该帧
if (callIt){
if (process)
process(frame, output);
else if (frameprocessor)
frameprocessor->process(frame, output);
}
else{
output = frame;
}
if (Outputfile.length()){
cvtColor(output, output, CV_GRAY2BGR);
writeNextFrame(output);
}
if (WindowNameOutput.length() != 0)
imshow(WindowNameOutput, output);
//按键暂停,继续按键继续
if (delay >= 0 && waitKey(delay) >= 0)
waitKey(0);
//到达指定暂停键,退出
if (frameToStop >= 0 && getFrameNumber() == frameToStop)
stopIt();
}
}
//暂停键置位
void stopIt(){
stop = true;
}
//查询暂停标志位
bool isStopped(){
return stop;
}
//返回视频打开标志
bool isOpened(){
return caputure.isOpened() || !images.empty();
}
//设置延时
void setDelay(int d){
delay = d;
}
//读取下一帧
bool readNextFrame(Mat &frame){
if (images.size() == 0)
return caputure.read(frame);
else{
if (itImg != images.end()){
frame = imread(*itImg);
itImg++;
return frame.data ? 1 : 0;
}
else
return false;
}
}
void CallProcess(){
callIt = true;
}
void dontCallProcess(){
callIt = false;
}
//设置停止帧
void stopAtFrameNo(long frame){
frameToStop = frame;
}
// 获得当前帧的位置
long getFrameNumber(){
long fnumber = static_cast<long>(caputure.get((CV_CAP_PROP_POS_FRAMES)));
return fnumber;
}
//获得帧大小
Size getFrameSize() {
if (images.size() == 0) {
// 从视频流获得帧大小
int w = static_cast<int>(caputure.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(caputure.get(CV_CAP_PROP_FRAME_HEIGHT));
return Size(w, h);
}
else {
//从图像获得帧大小
cv::Mat tmp = cv::imread(images[0]);
return (tmp.data) ? (tmp.size()) : (Size(0, 0));
}
}
//获取帧率
double getFrameRate(){
return caputure.get(CV_CAP_PROP_FPS);
}
vector<string>::const_iterator itImg;
bool setInput(const vector<string> &imgs){
fnumber = 0;
caputure.release();
images = imgs;
itImg = images.begin();
return true;
}
void setFrameProcessor(FrameProcessor *frameprocessor){
process = 0;
this->frameprocessor = frameprocessor;
CallProcess();
}
//获得编码类型
int getCodec(char codec[4]) {
if (images.size() != 0)
return -1;
union { // 数据结构4-char
int value;
char code[4];
} returned;
//获得编码值
returned.value = static_cast<int>(
caputure.get(CV_CAP_PROP_FOURCC));
// get the 4 characters
codec[0] = returned.code[0];
codec[1] = returned.code[1];
codec[2] = returned.code[2];
codec[3] = returned.code[3];
return returned.value;
}
bool setOutput(const string &filename, int codec = 0, double framerate = 0.0, bool isColor = true){
//设置文件名
Outputfile = filename;
//清空扩展名
extension.clear();
//设置帧率
if (framerate == 0.0){
framerate = getFrameRate();
}
//获取输入原视频的编码方式
char c[4];
if (codec == 0){
codec = getCodec(c);
}
return writer.open(Outputfile,
codec,
framerate,
getFrameSize(),
isColor);
}
//输出视频帧到图片fileme+currentIndex.ext,如filename001.jpg
bool setOutput(const string &filename,//路径
const string &ext,//扩展名
int numberOfDigits = 3,//数字位数
int startIndex = 0){//起始索引
if (numberOfDigits<0)
return false;
Outputfile = filename;
extension = ext;
digits = numberOfDigits;
currentIndex = startIndex;
return true;
}
//写下一帧
void writeNextFrame(Mat &frame){
//如果扩展名不为空,写到图片文件中
if (extension.length()){
stringstream ss;
ss << Outputfile << setfill('0') << setw(digits) << currentIndex++ << extension;
imwrite(ss.str(), frame);
}
//反之,写到视频文件中
else{
writer.write(frame);
}
}
};
//帧处理函数:canny边缘检测
void canny(cv::Mat& img, cv::Mat& out) {
//灰度变换
if (img.channels() == 3)
cvtColor(img, out, CV_BGR2GRAY);
// canny算子求边缘
Canny(out, out, 100, 200);
//颜色反转,看起来更舒服些
threshold(out, out, 128, 255, cv::THRESH_BINARY_INV);
}
int main(int argc, char *argv[])
{
VideoProcessor processor;
// FeatureTracker tracker;
BGFGSegmentor tracker;
//打开输入视频
processor.setInput("bike.avi");
processor.displayInput("Current Frame");
processor.displayOutput("Output Frame");
//设置每一帧的延时
processor.setDelay(1000. / processor.getFrameRate());
//设置帧处理函数,可以任意
processor.setFrameProcessor(&tracker);
// processor.setOutput ("./bikeout.avi");
// processor.setOutput ("bikeout",".jpg");
processor.run();
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
收起资源包目录
moving_target_tracking.rar (22个子文件)
track
track.sln 961B
track.sdf 12.94MB
track.v12.suo 18KB
Debug
track.ilk 598KB
track.exe 110KB
track.pdb 1.75MB
track
track.vcxproj.filters 945B
video.avi 423KB
track.vcxproj 4KB
bike.avi 436KB
main.cpp 7KB
Debug
vc120.pdb 1.34MB
track.log 2KB
main.obj 405KB
vc120.idb 587KB
track.tlog
CL.write.1.tlog 316B
CL.read.1.tlog 18KB
cl.command.1.tlog 568B
link.write.1.tlog 294B
link.command.1.tlog 3KB
link.read.1.tlog 8KB
track.lastbuildstate 151B
共 22 条
- 1
weixin_42653672
- 粉丝: 93
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0