mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge pull request #25349 from gursimarsingh:videocapture_samples_cpp
combined videocapture and videowriter samples for cleanup
This commit is contained in:
@@ -710,9 +710,12 @@ namespace internal { class VideoCapturePrivateAccessor; }
|
||||
|
||||
The class provides C++ API for capturing video from cameras or for reading video files and image sequences.
|
||||
|
||||
Here is how the class can be used:
|
||||
@include samples/cpp/snippets/videocapture_basic.cpp
|
||||
|
||||
@note
|
||||
- (C++) A basic sample on using the %VideoCapture interface can be found at
|
||||
`OPENCV_SOURCE_CODE/samples/cpp/videocapture_starter.cpp`
|
||||
`OPENCV_SOURCE_CODE/samples/cpp/videocapture_combined.cpp`
|
||||
- (Python) A basic sample on using the %VideoCapture interface can be found at
|
||||
`OPENCV_SOURCE_CODE/samples/python/video.py`
|
||||
- (Python) A multi threaded video processing sample can be found at
|
||||
@@ -979,8 +982,8 @@ class IVideoWriter;
|
||||
Check @ref tutorial_video_write "the corresponding tutorial" for more details
|
||||
*/
|
||||
|
||||
/** @example samples/cpp/videowriter_basic.cpp
|
||||
An example using VideoWriter class
|
||||
/** @example samples/cpp/videowriter.cpp
|
||||
An example using VideoCapture and VideoWriter class
|
||||
*/
|
||||
|
||||
/** @brief Video writer class.
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp> // cv::Canny()
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using std::cout; using std::cerr; using std::endl;
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
Mat frame;
|
||||
cout << "Opening camera..." << endl;
|
||||
VideoCapture capture(0); // open the first camera
|
||||
if (!capture.isOpened())
|
||||
{
|
||||
cerr << "ERROR: Can't initialize camera capture" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
cout << "Frame width: " << capture.get(CAP_PROP_FRAME_WIDTH) << endl;
|
||||
cout << " height: " << capture.get(CAP_PROP_FRAME_HEIGHT) << endl;
|
||||
cout << "Capturing FPS: " << capture.get(CAP_PROP_FPS) << endl;
|
||||
|
||||
cout << endl << "Press 'ESC' to quit, 'space' to toggle frame processing" << endl;
|
||||
cout << endl << "Start grabbing..." << endl;
|
||||
|
||||
size_t nFrames = 0;
|
||||
bool enableProcessing = false;
|
||||
int64 t0 = cv::getTickCount();
|
||||
int64 processingTime = 0;
|
||||
for (;;)
|
||||
{
|
||||
capture >> frame; // read the next frame from camera
|
||||
if (frame.empty())
|
||||
{
|
||||
cerr << "ERROR: Can't grab camera frame." << endl;
|
||||
break;
|
||||
}
|
||||
nFrames++;
|
||||
if (nFrames % 10 == 0)
|
||||
{
|
||||
const int N = 10;
|
||||
int64 t1 = cv::getTickCount();
|
||||
cout << "Frames captured: " << cv::format("%5lld", (long long int)nFrames)
|
||||
<< " Average FPS: " << cv::format("%9.1f", (double)getTickFrequency() * N / (t1 - t0))
|
||||
<< " Average time per frame: " << cv::format("%9.2f ms", (double)(t1 - t0) * 1000.0f / (N * getTickFrequency()))
|
||||
<< " Average processing time: " << cv::format("%9.2f ms", (double)(processingTime) * 1000.0f / (N * getTickFrequency()))
|
||||
<< std::endl;
|
||||
t0 = t1;
|
||||
processingTime = 0;
|
||||
}
|
||||
if (!enableProcessing)
|
||||
{
|
||||
imshow("Frame", frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
int64 tp0 = cv::getTickCount();
|
||||
Mat processed;
|
||||
cv::Canny(frame, processed, 400, 1000, 5);
|
||||
processingTime += cv::getTickCount() - tp0;
|
||||
imshow("Frame", processed);
|
||||
}
|
||||
int key = waitKey(1);
|
||||
if (key == 27/*ESC*/)
|
||||
break;
|
||||
if (key == 32/*SPACE*/)
|
||||
{
|
||||
enableProcessing = !enableProcessing;
|
||||
cout << "Enable frame processing ('space' key): " << enableProcessing << endl;
|
||||
}
|
||||
}
|
||||
std::cout << "Number of captured frames: " << nFrames << endl;
|
||||
return nFrames > 0 ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This sample demonstrates how to read and display frames from a video file, a camera device or an image sequence.
|
||||
* The sample also demonstrates extracting audio buffers from a video file.
|
||||
|
||||
* Capturing video and audio simultaneously from camera device is not supported by OpenCV.
|
||||
*/
|
||||
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
string keys =
|
||||
"{input i | 0 | Path to input image or video file. Skip this argument to capture frames from a camera.}"
|
||||
"{help h | | print usage}";
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
parser.about("This sample demonstrates how to read and display frames from a video file, a camera device or an image sequence \n"
|
||||
"Usage:\n --input/-i=<video file, image sequence in format like ../data/left%02d.jpg or camera index>\n"
|
||||
"q,Q,esc -- quit\n"
|
||||
"You can also pass the path to an image sequence and OpenCV will treat the sequence just like a video\n"
|
||||
"example: --input=right%02d.jpg\n");
|
||||
|
||||
// Check for 'help' argument to display usage information
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
string file = parser.get<string>("input");
|
||||
|
||||
Mat videoFrame;
|
||||
Mat audioFrame;
|
||||
vector<vector<Mat>> audioData;
|
||||
VideoCapture cap;
|
||||
|
||||
if (isdigit(file[0])) {
|
||||
// No input file, capture video from default camera
|
||||
int idx = file[0] - '0';
|
||||
cap.open(idx, CAP_ANY);
|
||||
if (!cap.isOpened()) {
|
||||
cerr << "ERROR! Unable to open camera" << endl;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// Open input video file
|
||||
cap.open(file, CAP_ANY);
|
||||
if (!cap.isOpened()) {
|
||||
cerr << "ERROR! Unable to open file: " + file << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
cout << "Frame width: " << cap.get(CAP_PROP_FRAME_WIDTH) << endl;
|
||||
cout << " height: " << cap.get(CAP_PROP_FRAME_HEIGHT) << endl;
|
||||
cout << "Capturing FPS: " << cap.get(CAP_PROP_FPS) << endl;
|
||||
|
||||
int numberOfFrames = 0;
|
||||
|
||||
// Main loop for capturing and displaying frames
|
||||
for (;;)
|
||||
{
|
||||
if (!cap.grab()) {
|
||||
cerr << "End of input stream" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
bool videoFrameRetrieved = cap.retrieve(videoFrame);
|
||||
if (videoFrameRetrieved) {
|
||||
numberOfFrames++;
|
||||
imshow("Video | q or esc to quit", videoFrame);
|
||||
if (waitKey(30) >= 0)
|
||||
break;
|
||||
cout << "Video frame retrieved successfully. Frame count: " << numberOfFrames << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Output the count of captured samples and frames
|
||||
cout << "Number of video frames: " << numberOfFrames << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help(char** argv)
|
||||
{
|
||||
cout << "\nThis sample shows you how to read a sequence of images using the VideoCapture interface.\n"
|
||||
<< "Usage: " << argv[0] << " <image_mask> (example mask: example_%02d.jpg)\n"
|
||||
<< "Image mask defines the name variation for the input images that have to be read as a sequence. \n"
|
||||
<< "Using the mask example_%02d.jpg will read in images labeled as 'example_00.jpg', 'example_01.jpg', etc."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
help(argv);
|
||||
cv::CommandLineParser parser(argc, argv, "{@image| ../data/left%02d.jpg |}");
|
||||
string first_file = parser.get<string>("@image");
|
||||
|
||||
if(first_file.empty())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
VideoCapture sequence(first_file);
|
||||
|
||||
if (!sequence.isOpened())
|
||||
{
|
||||
cerr << "Failed to open the image sequence!\n" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Mat image;
|
||||
namedWindow("Image sequence | press ESC to close", 1);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// Read in image from sequence
|
||||
sequence >> image;
|
||||
|
||||
// If no image was retrieved -> end of sequence
|
||||
if(image.empty())
|
||||
{
|
||||
cout << "End of Sequence" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
imshow("Image sequence | press ESC to close", image);
|
||||
|
||||
if(waitKey(500) == 27)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* @file videocapture_starter.cpp
|
||||
* @brief A starter sample for using OpenCV VideoCapture with capture devices, video files or image sequences
|
||||
* easy as CV_PI right?
|
||||
*
|
||||
* Created on: Nov 23, 2010
|
||||
* Author: Ethan Rublee
|
||||
*
|
||||
* Modified on: April 17, 2013
|
||||
* Author: Kevin Hughes
|
||||
*/
|
||||
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
//hide the local functions in an anon namespace
|
||||
namespace {
|
||||
void help(char** av) {
|
||||
cout << "The program captures frames from a video file, image sequence (01.jpg, 02.jpg ... 10.jpg) or camera connected to your computer." << endl
|
||||
<< "Usage:\n" << av[0] << " <video file, image sequence or device number>" << endl
|
||||
<< "q,Q,esc -- quit" << endl
|
||||
<< "space -- save frame" << endl << endl
|
||||
<< "\tTo capture from a camera pass the device number. To find the device number, try ls /dev/video*" << endl
|
||||
<< "\texample: " << av[0] << " 0" << endl
|
||||
<< "\tYou may also pass a video file instead of a device number" << endl
|
||||
<< "\texample: " << av[0] << " video.avi" << endl
|
||||
<< "\tYou can also pass the path to an image sequence and OpenCV will treat the sequence just like a video." << endl
|
||||
<< "\texample: " << av[0] << " right%%02d.jpg" << endl;
|
||||
}
|
||||
|
||||
int process(VideoCapture& capture) {
|
||||
int n = 0;
|
||||
char filename[200];
|
||||
string window_name = "video | q or esc to quit";
|
||||
cout << "press space to save a picture. q or esc to quit" << endl;
|
||||
namedWindow(window_name, WINDOW_KEEPRATIO); //resizable window;
|
||||
Mat frame;
|
||||
|
||||
for (;;) {
|
||||
capture >> frame;
|
||||
if (frame.empty())
|
||||
break;
|
||||
|
||||
imshow(window_name, frame);
|
||||
char key = (char)waitKey(30); //delay N millis, usually long enough to display and capture input
|
||||
|
||||
switch (key) {
|
||||
case 'q':
|
||||
case 'Q':
|
||||
case 27: //escape key
|
||||
return 0;
|
||||
case ' ': //Save an image
|
||||
snprintf(filename,sizeof(filename),"filename%.3d.jpg",n++);
|
||||
imwrite(filename,frame);
|
||||
cout << "Saved " << filename << endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int ac, char** av) {
|
||||
cv::CommandLineParser parser(ac, av, "{help h||}{@input||}");
|
||||
if (parser.has("help"))
|
||||
{
|
||||
help(av);
|
||||
return 0;
|
||||
}
|
||||
std::string arg = parser.get<std::string>("@input");
|
||||
if (arg.empty()) {
|
||||
help(av);
|
||||
return 1;
|
||||
}
|
||||
VideoCapture capture(arg); //try to open string, this will attempt to open it as a video file or image sequence
|
||||
if (!capture.isOpened()) //if this fails, try to open as a video camera, through the use of an integer param
|
||||
capture.open(atoi(arg.c_str()));
|
||||
if (!capture.isOpened()) {
|
||||
cerr << "Failed to open the video device, video file or image sequence!\n" << endl;
|
||||
help(av);
|
||||
return 1;
|
||||
}
|
||||
return process(capture);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
@file videowriter.cpp
|
||||
@brief A sample for VideoWriter and VideoCapture with options to specify video codec, fps and resolution
|
||||
@date April 05, 2024
|
||||
*/
|
||||
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
inline map<string, int> fourccByCodec() {
|
||||
map<string, int> res;
|
||||
res["h264"] = VideoWriter::fourcc('H', '2', '6', '4');
|
||||
res["h265"] = VideoWriter::fourcc('H', 'E', 'V', 'C');
|
||||
res["mpeg2"] = VideoWriter::fourcc('M', 'P', 'E', 'G');
|
||||
res["mpeg4"] = VideoWriter::fourcc('M', 'P', '4', '2');
|
||||
res["mjpeg"] = VideoWriter::fourcc('M', 'J', 'P', 'G');
|
||||
res["vp8"] = VideoWriter::fourcc('V', 'P', '8', '0');
|
||||
return res;
|
||||
}
|
||||
|
||||
// Function to parse resolution string "WxH"
|
||||
static Size parseResolution(const string& resolution) {
|
||||
stringstream ss(resolution);
|
||||
int width, height;
|
||||
char delimiter;
|
||||
|
||||
ss >> width >> delimiter >> height;
|
||||
|
||||
if (ss.fail() || delimiter != 'x') {
|
||||
throw runtime_error("Invalid resolution format. Please provide in WxH format.");
|
||||
}
|
||||
|
||||
return Size(width, height);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
const String keys =
|
||||
"{help h usage ? | | Print help message }"
|
||||
"{fps |30 | fix frame per second for encoding (supported: fps > 0) }"
|
||||
"{codec |mjpeg | Supported codecs depend on OpenCV Configuration. Try one of 'h264', 'h265', 'mpeg2', 'mpeg4', 'mjpeg', 'vp8' }"
|
||||
"{resolution |1280x720 | Video resolution in WxH format, (e.g., '1920x1080') }"
|
||||
"{output_filepath | output.avi | Path to the output video file}";
|
||||
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("Video Capture and Write with codec and resolution options");
|
||||
|
||||
if (parser.has("help")) {
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
double fps = parser.get<double>("fps");
|
||||
string codecStr = parser.get<string>("codec");
|
||||
string resolutionStr = parser.get<string>("resolution");
|
||||
string outputFilepath = parser.get<string>("output_filepath");
|
||||
|
||||
auto codecMap = fourccByCodec();
|
||||
|
||||
if (codecMap.find(codecStr) == codecMap.end()) {
|
||||
cerr << "Invalid codec" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int codec = codecMap[codecStr];
|
||||
Size resolution = parseResolution(resolutionStr);
|
||||
|
||||
// Video Capture
|
||||
VideoCapture cap(0);
|
||||
if (!cap.isOpened()) {
|
||||
cerr << "ERROR! Unable to open camera\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
cout << "Selected FPS: " << fps << endl;
|
||||
cout << "Selected Codec: " << codecStr << endl;
|
||||
cout << "Selected Resolution: " << resolutionStr << " (" << resolution.width << "x" << resolution.height << ")" << endl;
|
||||
|
||||
// Set up VideoWriter
|
||||
VideoWriter writer(outputFilepath, codec, fps, resolution, true); // Assuming color video
|
||||
if (!writer.isOpened()) {
|
||||
cerr << "Could not open the output video file for write\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
cout << "Writing video file: " << outputFilepath << endl
|
||||
<< "Press any key to terminate" << endl;
|
||||
|
||||
Mat frame, resizedFrame;
|
||||
for (;;) {
|
||||
// Capture frame
|
||||
if (!cap.read(frame) || frame.empty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Resize frame to desired resolution
|
||||
resize(frame, resizedFrame, resolution);
|
||||
|
||||
// Write resized frame to video
|
||||
writer.write(resizedFrame);
|
||||
|
||||
// Show live
|
||||
imshow("Live", resizedFrame);
|
||||
if (waitKey(5) >= 0) break;
|
||||
}
|
||||
|
||||
// VideoWriter and VideoCapture are automatically closed by their destructors
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
@file videowriter_basic.cpp
|
||||
@brief A very basic sample for using VideoWriter and VideoCapture
|
||||
@author PkLab.net
|
||||
@date Aug 24, 2016
|
||||
*/
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
Mat src;
|
||||
// use default camera as video source
|
||||
VideoCapture cap(0);
|
||||
// check if we succeeded
|
||||
if (!cap.isOpened()) {
|
||||
cerr << "ERROR! Unable to open camera\n";
|
||||
return -1;
|
||||
}
|
||||
// get one frame from camera to know frame size and type
|
||||
cap >> src;
|
||||
// check if we succeeded
|
||||
if (src.empty()) {
|
||||
cerr << "ERROR! blank frame grabbed\n";
|
||||
return -1;
|
||||
}
|
||||
bool isColor = (src.type() == CV_8UC3);
|
||||
|
||||
//--- INITIALIZE VIDEOWRITER
|
||||
VideoWriter writer;
|
||||
int codec = VideoWriter::fourcc('M', 'J', 'P', 'G'); // select desired codec (must be available at runtime)
|
||||
double fps = 25.0; // framerate of the created video stream
|
||||
string filename = "./live.avi"; // name of the output video file
|
||||
writer.open(filename, codec, fps, src.size(), isColor);
|
||||
// check if we succeeded
|
||||
if (!writer.isOpened()) {
|
||||
cerr << "Could not open the output video file for write\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--- GRAB AND WRITE LOOP
|
||||
cout << "Writing videofile: " << filename << endl
|
||||
<< "Press any key to terminate" << endl;
|
||||
for (;;)
|
||||
{
|
||||
// check if we succeeded
|
||||
if (!cap.read(src)) {
|
||||
cerr << "ERROR! blank frame grabbed\n";
|
||||
break;
|
||||
}
|
||||
// encode the frame into the videofile stream
|
||||
writer.write(src);
|
||||
// show live and wait for a key with timeout long enough to show images
|
||||
imshow("Live", src);
|
||||
if (waitKey(5) >= 0)
|
||||
break;
|
||||
}
|
||||
// the videofile will be closed and released automatically in VideoWriter destructor
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user