1
0
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:
Gursimar Singh
2024-10-28 12:27:54 +05:30
committed by GitHub
parent 331d327760
commit f217656916
8 changed files with 212 additions and 299 deletions
+6 -3
View File
@@ -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.
-76
View File
@@ -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;
}
+88
View File
@@ -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;
}
-93
View File
@@ -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);
}
+118
View File
@@ -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;
}
-67
View File
@@ -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;
}