I am trying to write a program that captures video from a webcam using this code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat frame;
VideoCapture cap(1);
char key;
String outputName = "output.avi";
VideoWriter outputVideo;
Size size = Size(cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT));
outputVideo.open(outputName, CV_FOURCC('D', 'I', 'V', 'X'), cap.get(CV_CAP_PROP_FPS), size, true);
if (!outputVideo.isOpened())
{
cout << "Could not open the output video for write: " << outputName << endl;
return -1;
}
cout << "size " << size.width << " x " << size.height << endl;
namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
cap.set(CV_CAP_PROP_EXPOSURE, -8);
while (true){
bool success = cap.read(frame);
if (!success){
cout << "Cannot read frame from file" << endl;
return -2;
}
outputVideo.write(frame);
imshow("Display window", frame);
key = waitKey(1);
if (key == ' '){
cout << "Video ended due to key stroke" << endl;
return 1;
}
}
return 0;
}
The program doesn't seem to be able to open outputVideo since it always returns -1. I thought that I might not have the codec divx installed, but I have installed it from k-lite codec pack and divx and it still does not work.
Could anybody please tell me how to install codecs such that opencv recognizes them?
I am using OpenCV 2.4.10 on Windows 7 with Visual studio 2013.
Related
My name is Toan. Currently, I'm using OpenCV-C++ to write video *.mp4 type. I can write video .avi type but It's take a lot of storage. About 1Mb/1s with 640x480 resolution and 15 FPS. I'm using iMX6UL-EVK board(Linux).
I built without error but no output .mp4 file. And in python code (OpenCV-Python), this board can write .mp4 video with "mp4v".
I tried with "mp4v", "xvid", "divx", "h264", "x264" but not working. So what can I do now? Or may you show me others type of video which not take much of storage ?
This is my code:
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
cout << "Built with OpenCV " << CV_VERSION << endl;
Mat image;
Mat src;
VideoCapture capture;
capture.open(2);
capture >> src;
bool isColor = (src.type() == CV_8UC3);
VideoWriter writer;
int codec = VideoWriter::fourcc('M', 'P', '4', 'V');
double fps = 15.0;
string filename = "live.mp4";
Size sizeFrame(640,480);
writer.open(filename, codec, fps, sizeFrame, isColor);
cout << "Started writing video... " << endl;
for (int i = 0 ; i < 60 ; i ++)
{
capture >> image;
Mat xframe;
resize(image,xframe,sizeFrame);
writer.write(xframe);
// imshow("Sample", image);
// char c = (char)waitKey(1);
// if(c == 27) break;
}
cout << "Write complete !" << endl;
capture.release();
writer.release();
return 0;
}
Thank you so much,
Toan
VideoWriter::fourcc('a', 'v', 'c', '1')
work fine for me to write mp4 file.
I am trying to open a video and write it to a location:
#include <opencv2/opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
using namespace cv;
using namespace std;
int main()
{
string videoName = "KorExp3.avi";
VideoCapture video(videoName);
Mat frame;
video >> frame;
VideoWriter w("D:/w.avi", CV_FOURCC('M', 'P', '4', '2'), 30, frame.size(), true);
while (true) {
video >> frame;
imshow("frame", frame);
w << frame;
}
w.release();
waitKey(0);
return 0;
}
In debug mode, while hovering the mouse on video it says:
Information not available, no symbols loaded for opencv_world340d.dll
I have copied this dll file and the video file to the same location of .exe, but still same thing happens. I also tried the absolute path to the video string videoName = "D:\\KorExp3.avi"; but didn't work.
How can I capture a video and write it to a location using openCV?
Do you generate (compile) OpenCV with debug symbols??
This is a sample (and simple) code to record a video file using OpenCV...
I am using Qt (5.5.1 and upper) on Linux, but this is doesn't matter...
It will work in every OS...
void MainWindow::on_Rec_Click()
{
QString szNome = QString("%1/%2-%3-M.mp4").arg(szPath).arg(szCamIndex).arg(obAgora.toString("yyyyMMddHHmmss"));
qDebug() << szNome;
char szCPath[2048];
strcpy(szCPath, szNome.toStdString().c_str());
qDebug() << "Path: " << szCPath;
MakePath(szCPath, inIndice+1); // If the path does not exist...
SaveEventToDB(szNome, inIndice+1, obAgora, 0); // Register event in DB
qDebug() << m_Capture[inIndice - 1] << " / " << inIndice;
cv::Size S = cv::Size((int) m_Capture[inIndice]->get(CV_CAP_PROP_FRAME_WIDTH), // Acquire input size
(int) m_Capture[inIndice]->get(CV_CAP_PROP_FRAME_HEIGHT));
qDebug() << S.width << " / " << S.height;
int ex = cv::VideoWriter::fourcc('M','P','4','2');
qDebug() << ex;
double dlFrameRate = m_Capture[inIndice]->get(CV_CAP_PROP_FPS);
qDebug() << dlFrameRate;
m_Output = new cv::VideoWriter(szNome.toStdString(), ex, dlFrameRate, S, true);
qDebug() << "Object cv::VideoWriter created.";
m_OutputFile = szNome;
m_inTimerID = startTimer(1000 / dlFrameRate);
}
void MainWindow::timerEvent(QTimerEvent *event)
{
if(m_inActualView != 0) {
cv::Mat image;
*m_Capture[m_inActualView] >> image;
if(m_Output) {
if(m_Output->isOpened()) {
*m_Output << image;
}
}
cv::flip( image,image, 0);
// Show the image
m_Ui->openCVViewer->showImage( image );
}
}
I put the directory of the video instead of moving the video to the project location andthe error was solved:
string videoName = "D:\\KorExp3.avi";
while (true) {
video >> frame;
...
I want to crop a certain area of my raw video before extracting the frames. I don't want to use external cropping video software because I need the video to be raw for processing. Is it possible to crop a certain area before extraction ? I read about ROI for images, is it possible for video too ?
Here's my extraction code that's already working :
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
#include <sstream>
using namespace cv;
using namespace std;
int c = 0;
string int2str(int &);
int main(int argc, char **argv) {
string s;
VideoCapture cap("test_video.mov");
if (!cap.isOpened())
{
cout << "Cannot open the video file" << endl;
return -1;
}
double fps = cap.get(CV_CAP_PROP_FPS);
cout << "Frame per seconds : " << fps << endl;
namedWindow("MyVideo", CV_WINDOW_NORMAL);
resizeWindow("MyVideo", 600, 600);
while (1)
{
Mat frame;
Mat Gray_frame;
bool bSuccess = cap.read(frame);
if (!bSuccess)
{
cout << "Cannot read the frame from video file" << endl;
break;
}
s = int2str(c);
//cout<<("%d\n",frame )<<endl;
c++;
imshow("MyVideo", frame);
imwrite("frame" + s + ".jpg", frame);
if (waitKey(30) == 27)
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
string int2str(int &i) {
string s;
stringstream ss(s);
ss << i;
return ss.str();
}
Still need to crop the video, any advice ?
I'm following a tutorial to extract video frames. I've read this question, it doesn't work, also queationfrom Open CV Answer, but the solution is for capturing current frame. I have a 120fps video and want to extract all of them. Here's my code
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
#include <sstream>
using namespace cv;
using namespace std;
int c = 0;
string int2str(int &);
int main(int argc, char **argv) {
string s;
VideoCapture cap("test.mp4"); // video
if (!cap.isOpened())
{
cout << "Cannot open the video file" << endl;
return -1;
}
double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
cout << "Frame per seconds : " << fps << endl;
namedWindow("MyVideo", CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
while (1)
{
Mat frame;
Mat Gray_frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess)
{
cout << "Cannot read the frame from video file" << endl;
break;
}
s = int2str(c);
//cout<<("%d\n",frame )<<endl;
c++;
imshow("MyVideo", frame); //show the frame in "MyVideo" window
imwrite("ig" + s + ".jpg", frame);
if (waitKey(30) == 27) //esc key
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
//int to string function
string int2str(int &i) {
string s;
stringstream ss(s);
ss << i;
return ss.str();
}
My problem is, I have a minute video at 120fps. I expected to be able to extract 120 frames. But the extraction went wrong, the video last for 1 minute but I got more than 200 frames stored in my folder. Did I do something wrong in my code ?
I am working with GigaE Camera and it is a grayscale image and I want to record the videos. So I have tried initially with webcam and below is my code:
#include "opencv2\highgui\highgui.hpp"
#include "iostream"
#include "opencv2/opencv.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "opencv2/videoio/videoio.hpp"
#include<string>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture cap(0);
VideoWriter writer;
if (!cap.isOpened())
{
cout << "not opened" << endl;
return -1;
}
char* windowName = "Webcam Feed";
namedWindow(windowName, CV_WINDOW_AUTOSIZE);
string filename = "D:\videos\myVideo12.avi";
int fcc = CV_FOURCC('M', 'J', 'P', 'J');
int fps = 30;
Size frameSize(cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT));
bool isColor = false;
writer = VideoWriter(filename, fcc, fps, frameSize, isColor);
if (!writer.isOpened())
{
cout << "Error not opened" << endl;
getchar();
return -1;
}
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame);
if (!bSuccess)
{
cout << "ERROR READING FRAME FROM CAMERA FEED" << endl;
break;
}
cvtColor(frame, frame, CV_BGR2GRAY);
writer.write(frame);
imshow(windowName, frame);
return 0;
}
There is no video created and I don't get any error too. But it works fine with OpenCV-2.4.10.
Most likely, the video is not written because of the codec. OpenCV tends to stay silent in case of encoding (and many other) problems. Try setting fcc to -1 to choose from a list of available codecs.
Solved! The error is in the giving the filename path where I used '\' instead of '/'. The codecs are MPEG or DIV3 for grayscale images.