C++ OpenCV Video Processing
Video processing refers to processing and analyzing each frame of a video sequence.
OpenCV provides powerful tools for processing video data, including video reading, frame processing, video saving, and real-time video processing.
Application Scenarios of Video Processing
Video Surveillance:
Use background subtraction to detect moving objects.
Use optical flow to analyze object motion trajectories.
Video Analysis:
Extract key frames from videos.
Analyze object behavior in videos.
Real-time Processing:
Real-time video filters (e.g., edge detection, blur, etc.).
Real-time object detection and tracking.
Reading and Displaying Videos
Reading Video Files (VideoCapture)
In OpenCV,VideoCapturethe class is used to read video frames from video files or cameras.
To read a video file, first create aVideoCaptureobject, and specify the path to the video file.
Example
using namespace cv;
int main() {
// Create a VideoCapture object and open the video file
VideoCapture cap("example.mp4");
// Check whether the video was opened successfully
if (!cap.isOpened()) {
std::cerr << "Error: Could not open video file." << std::endl;
return -1;
}
// The video reading and display code will be introduced below
return 0;
}
Displaying Video Frames
After reading the video file, you can read the video frame by frame in a loop, and use theimshowfunction to display each frame.
Example
while (true) {
// Read the next frame
cap >> frame;
// If the frame is empty, the video has ended
if (frame.empty()) {
break;
}
// Display the current frame
imshow("Video", frame);
// Wait 30 milliseconds, press ESC to exit
if (waitKey(30) == 27) {
break;
}
}
// Release the VideoCapture object
cap.release();
// Close all windows
destroyAllWindows();
Saving Videos (VideoWriter)
If you want to save the processed video to a file, you can use theVideoWriterclass. First, you need to specify the output file name, encoding format, frame rate, and frame size.
Example
double fps = cap.get(CAP_PROP_FPS);
Size frameSize(cap.get(CAP_PROP_FRAME_WIDTH), cap.get(CAP_PROP_FRAME_HEIGHT));
// Create a VideoWriter object
VideoWriter writer("output.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, frameSize);
while (true) {
cap >> frame;
if (frame.empty()) {
break;
}
// Write frames to the output video file
writer.write(frame);
imshow("Video", frame);
if (waitKey(30) == 27) {
break;
}
}
// Release the VideoCapture and VideoWriter objects
cap.release();
writer.release();
destroyAllWindows();
Video Frame Processing
Processing Video Frame by Frame
In video processing, it is usually necessary to perform specific processing operations on each frame. For example, you can convert each frame to grayscale, perform edge detection, and so on.
Example
cap >> frame;
if (frame.empty()) {
break;
}
// Convert the frame to a grayscale image
Mat grayFrame;
cvtColor(frame, grayFrame, COLOR_BGR2GRAY);
// Display the grayscale frame
imshow("Gray Video", grayFrame);
if (waitKey(30) == 27) {
break;
}
}
Real-time Processing of Video Frames
When processing video frames in real time, it is usually necessary to apply some real-time processing algorithms to each frame. For example, detect moving objects in the video in real time.
Example
cap >> prevFrame;
cvtColor(prevFrame, prevFrame, COLOR_BGR2GRAY);
while (true) {
cap >> nextFrame;
if (nextFrame.empty()) {
break;
}
cvtColor(nextFrame, nextFrame, COLOR_BGR2GRAY);
// Calculate the difference between frames
absdiff(prevFrame, nextFrame, diffFrame);
// Display the difference frame
imshow("Motion Detection", diffFrame);
// Update the previous frame
prevFrame = nextFrame.clone();
if (waitKey(30) == 27) {
break;
}
}
Real-time Camera Processing
Opening the Camera
Using theVideoCaptureclass, you can not only read video files, but also open the camera for real-time video stream processing. To open the camera, simply set theVideoCaptureparameter to 0 (which indicates the default camera).
Example
if (!cap.isOpened()) {
std::cerr << "Error: Could not open camera." << std::endl;
return -1;
}
Processing Real-time Video Streams
After opening the camera, you can process the real-time video stream frame by frame just like processing a video file. For example, you can apply an edge detection algorithm to the real-time video stream.
Example
cap >> frame;
if (frame.empty()) {
break;
}
// Apply Canny edge detection
Mat edges;
Canny(frame, edges, 100, 200);
// Display the edge detection result
imshow("Edges", edges);
if (waitKey(30) == 27) {
break;
}
}
cap.release();
destroyAllWindows();
Advanced Video Processing Techniques
Video Background Subtraction
Background subtraction is used to extract foreground objects from a video.
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
// Open a video file or camera
VideoCapture cap("video.mp4");
if (!cap.isOpened()) {
cout << "Error: Unable to open video file or camera!" << endl;
return -1;
}
// Create a background subtractor
Ptr<BackgroundSubtractor> bgSubtractor = createBackgroundSubtractorMOG2();
// Process video frames
Mat frame, fgMask;
while (true) {
cap >> frame;
if (frame.empty()) break;
// Apply background subtraction
bgSubtractor->apply(frame, fgMask);
// Display the result
imshow("Frame", frame);
imshow("Foreground Mask", fgMask);
// Press ESC to exit
if (waitKey(30) == 27) break;
}
// Release resources
cap.release();
destroyAllWindows();
return 0;
}
Optical Flow Computation
Optical flow is used to calculate the motion of objects in video frames.
Sparse optical flow (Lucas-Kanade method):
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
// Open a video file or camera
VideoCapture cap("video.mp4");
if (!cap.isOpened()) {
cout << "Error: Unable to open video file or camera!" << endl;
return -1;
}
// Read the first frame
Mat oldFrame, oldGray;
cap >> oldFrame;
cvtColor(oldFrame, oldGray, COLOR_BGR2GRAY);
// Select feature points
vector<Point2f> oldPoints;
goodFeaturesToTrack(oldGray, oldPoints, 100, 0.3, 7);
// Process video frames
Mat frame, gray;
while (true) {
cap >> frame;
if (frame.empty()) break;
// Convert to grayscale image
cvtColor(frame, gray, COLOR_BGR2GRAY);
// Compute optical flow
vector<Point2f> newPoints;
vector<uchar> status;
vector<float> err;
calcOpticalFlowPyrLK(oldGray, gray, oldPoints, newPoints, status, err);
// Draw optical flow trajectories
for (size_t i = 0; i < oldPoints.size(); i++) {
if (status[i]) {
line(frame, oldPoints[i], newPoints[i], Scalar(0, 255, 0), 2);
circle(frame, newPoints[i], 3, Scalar(0, 0, 255), -1);
}
}
// Update frames and feature points
oldGray = gray.clone();
oldPoints = newPoints;
// Display the result
imshow("Optical Flow", frame);
// Press ESC to exit
if (waitKey(30) == 27) break;
}
// Release resources
cap.release();
destroyAllWindows();
return 0;
}