OpenCV (处理视频序列)
Eva.Q Lv9

Video ~ ~

读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main(){
VideoCapture capture("bike.avi");
if(!capture.isOpen()) return 1;

double rate = capture.get(CV_CAP_PROP_FPS);

bool stop(false);
Mat frame;
namedWindow("Extracted Frame");

int delay = 1000/rate;

while(!stop){

if(!capture.read(frame)) break;

imshow("Extracted Frame", frame);

if(waitKey(delay) > 0) stop = true;
}

capture.release();
return 0;
}

详细见 https://evaqwq.github.io/2021/07/28/OPENCV1-1/

处理视频帧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "videoprocessor.h"

void draw(const cv::Mat& img, cv::Mat& out) {

img.copyTo(out);
cv::circle(out, cv::Point(100,100),5,cv::Scalar(255,0,0),2);
}

// processing function
void canny(cv::Mat& img, cv::Mat& out) {

// Convert to gray
if (img.channels()==3)
cv::cvtColor(img,out,cv::COLOR_BGR2GRAY);
// Compute Canny edges
cv::Canny(out,out,100,200);
// Invert the image
cv::threshold(out,out,128,255,cv::THRESH_BINARY_INV);
}

int main()
{
// Open the video file
cv::VideoCapture capture("bike.avi");
// cv::VideoCapture capture("http://www.laganiere.name/bike.avi");
// check if video successfully opened
if (!capture.isOpened())
return 1;

// Get the frame rate
double rate= capture.get(cv::CAP_PROP_FPS);
std::cout << "Frame rate: " << rate << "fps" << std::endl;

bool stop(false);
cv::Mat frame; // current video frame
cv::namedWindow("Extracted Frame");

// Delay between each frame
// corresponds to video frame rate
int delay= 1000/rate;
long long i=0;
std::string b="bike";
std::string ext=".bmp";
// for all frames in video
while (!stop) {

// read next frame if any
if (!capture.read(frame))
break;

cv::imshow("Extracted Frame",frame);

std::string name(b);
std::ostringstream ss; ss << std::setfill('0') << std::setw(3) << i; name+= ss.str(); i++;
name+=ext;

std::cout << name <<std::endl;

cv::Mat test;
// cv::resize(frame, test, cv::Size(), 0.2,0.2);
// cv::imwrite(name, frame);
// cv::imwrite(name, test);

// introduce a delay
// or press key to stop
if (cv::waitKey(delay)>=0)
stop= true;
}

// Close the video file
capture.release();

cv::waitKey();

// Now using the VideoProcessor class

// Create instance
VideoProcessor processor;

// Open video file
processor.setInput("bike.avi");

// Declare a window to display the video
processor.displayInput("Input Video");
processor.displayOutput("Output Video");

// Play the video at the original frame rate
processor.setDelay(1000./processor.getFrameRate());

// Set the frame processor callback function
processor.setFrameProcessor(canny);

// output a video
processor.setOutput("bikeCanny.avi",-1,15);

// stop the process at this frame
processor.stopAtFrameNo(51);

// Start the process
processor.run();

cv::waitKey();

return 0;
}

VideoProcessor.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// The frame processor interface
class FrameProcessor {

public:
// processing method
virtual void process(cv:: Mat &input, cv:: Mat &output)= 0;
};

class VideoProcessor {

private:

// the OpenCV video capture object
cv::VideoCapture capture;
// the callback function to be called
// for the processing of each frame
void (*process)(cv::Mat&, cv::Mat&);
// the pointer to the class implementing
// the FrameProcessor interface
FrameProcessor *frameProcessor;
// a bool to determine if the
// process callback will be called
bool callIt;
// Input display window name
std::string windowNameInput;
// Output display window name
std::string windowNameOutput;
// delay between each frame processing
int delay;
// number of processed frames
long fnumber;
// stop at this frame number
long frameToStop;
// to stop the processing
bool stop;

// vector of image filename to be used as input
std::vector<std::string> images;
// image vector iterator
std::vector<std::string>::const_iterator itImg;

// the OpenCV video writer object
cv::VideoWriter writer;
// output filename
std::string outputFile;

// current index for output images
int currentIndex;
// number of digits in output image filename
int digits;
// extension of output images
std::string extension;

// to get the next frame
// could be: video file; camera; vector of images
bool readNextFrame(cv::Mat& frame);

// to write the output frame
// could be: video file or images
void writeNextFrame(cv::Mat& frame);

public:

// Constructor setting the default values
VideoProcessor() : callIt(false), delay(-1),
fnumber(0), stop(false), digits(0), frameToStop(-1),
process(0), frameProcessor(0) {}

// set the name of the video file
bool setInput(std::string filename)

// set the camera ID
bool setInput(int id)

// set the vector of input images
bool setInput(const std::vector<std::string>& imgs)

// set the output video file
// by default the same parameters than input video will be used
bool setOutput(const std::string &filename, int codec=0, double framerate=0.0, bool isColor=true);

// set the output as a series of image files
// extension must be ".jpg", ".bmp" ...
bool setOutput(const std::string &filename, // filename prefix
const std::string &ext, // image file extension
int numberOfDigits=3, // number of digits
int startIndex=0) // start index


// set the callback function that will be called for each frame
void setFrameProcessor(void (*frameProcessingCallback)(cv::Mat&, cv::Mat&));

// set the instance of the class that implements the FrameProcessor interface
void setFrameProcessor(FrameProcessor* frameProcessorPtr);

// stop streaming at this frame number
void stopAtFrameNo(long frame);

// process callback to be called
void callProcess();

// do not call process callback
void dontCallProcess();

// to display the input frames
void displayInput(std::string wn);

// to display the processed frames
void displayOutput(std::string wn);

// do not display the processed frames
void dontDisplay();

// set a delay between each frame
// 0 means wait at each frame
// negative means no delay
void setDelay(int d);

// a count is kept of the processed frames
long getNumberOfProcessedFrames();

// return the size of the video frame
cv::Size getFrameSize();

// return the frame number of the next frame
long getFrameNumber();

// return the position in ms
double getPositionMS();

// return the frame rate
double getFrameRate();

// return the number of frames in video
long getTotalFrameCount();

// get the codec of input video
int getCodec(char codec[4]);

// go to this frame number
bool setFrameNumber(long pos);

// go to this position
bool setPositionMS(double pos);

// go to this position expressed in fraction of total film length
bool setRelativePosition(double pos);

// Stop the processing
void stopIt();

// Is the process stopped?
bool isStopped();

// Is a capture device opened?
bool isOpened();

// to grab (and process) the frames of the sequence
void run();
};

提取前景物

BGFGSegmentor.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class BGFGSegmentor : public FrameProcessor {

cv::Mat gray; // current gray-level image
cv::Mat background; // accumulated background
cv::Mat backImage; // current background image
cv::Mat foreground; // foreground image
double learningRate; // learning rate in background accumulation
int threshold; // threshold for foreground extraction

public:

BGFGSegmentor() : threshold(10), learningRate(0.01) {}

// Set the threshold used to declare a foreground
void setThreshold(int t) {

threshold= t;
}

// Set the learning rate
void setLearningRate(double r) {

learningRate= r;
}

// processing method
void process(cv:: Mat &frame, cv:: Mat &output) {

// convert to gray-level image
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);

// initialize background to 1st frame
if (background.empty())
gray.convertTo(background, CV_32F);

// convert background to 8U
background.convertTo(backImage,CV_8U);

// compute difference between current image and background
cv::absdiff(backImage,gray,foreground);

// apply threshold to foreground image
cv::threshold(foreground,output,threshold,255,cv::THRESH_BINARY_INV);

// accumulate background
cv::accumulateWeighted(gray, background,
// alpha*gray + (1-alpha)*background
learningRate, // alpha
output); // mask
}
};

#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
int main()
{
// Open the video file
cv::VideoCapture capture("bike.avi");
// check if video successfully opened
if (!capture.isOpened())
return 0;

// current video frame
cv::Mat frame;
// foreground binary image
cv::Mat foreground;
// background image
cv::Mat background;

cv::namedWindow("Extracted Foreground");

// The Mixture of Gaussian object
// used with all default parameters
cv::Ptr<cv::BackgroundSubtractor> ptrMOG = cv::bgsegm::createBackgroundSubtractorMOG();

bool stop(false);
// for all frames in video
while (!stop) {

// read next frame if any
if (!capture.read(frame))
break;

// update the background
// and return the foreground
ptrMOG->apply(frame,foreground,0.01);

// Complement the image
cv::threshold(foreground,foreground,128,255,cv::THRESH_BINARY_INV);

// show foreground and background
cv::imshow("Extracted Foreground",foreground);

// introduce a delay
// or press key to stop
if (cv::waitKey(10)>=0)
stop= true;
}

cv::waitKey();

// Create video procesor instance
VideoProcessor processor;

// Create background/foreground segmentor
BGFGSegmentor segmentor;
segmentor.setThreshold(25);

// Open video file
processor.setInput("bike.avi");

// set frame processor
processor.setFrameProcessor(&segmentor);

// Declare a window to display the video
processor.displayOutput("Extracted Foreground");

// Play the video at the original frame rate
processor.setDelay(1000./processor.getFrameRate());

// Start the process
processor.run();

cv::waitKey();
}

将得到一些二值前景图像

  • Post title:OpenCV (处理视频序列)
  • Post author:Eva.Q
  • Create time:2021-08-04 14:06:10
  • Post link:https://qyy/2021/08/04/OPENCV/OPENCV1-7/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.