I am using opencv to capture a video directly from webcam and saving it to a avi file. I have used the following code:
#include "StdAfx.h"
using namespace std;
using namespace cv;
int _tmain()
{
VideoCapture src;
src.open(1);
if(!src.isOpened())
{
cout<<"could not open camera\n";
return -1;
}
else
{
cout<<"camera opened\n";
}
int ex=static_cast<int>(src.get(CV_CAP_PROP_FOURCC));
Size s(Size((int)src.get(CV_CAP_PROP_FRAME_WIDTH),(int)src.get((CV_CAP_PROP_FRAME_HEIGHT))));
VideoWriter out;
out.open("out.avi",ex,20,s);
while(1)
{
Mat im;
src>>im;
imshow("vid",im);
out<<im;
char c;
c=cvWaitKey(50);
if(c==27)
break;
}
system("pause");
}
all the headers are included in stdafx.h.
But actually I am getting a avi file of size 0bite. How to fix this thing? I need to record the webcam video without displaying.
Note: I'm new in openCV and I am using Visual Studio 2010
to run the application without display the webcam just delete
imshow("vid",im);
and out.avi size is 0 because you open it when the application is running (when you open the video stream and write on it ) , to open the video which you recorded , just close the application to end the write on the video and then open it .
Actually there is no logical error in your program. The only problem is the FOUR_CC Codec you are using to write the video.
When I ran your code, I faced the exact problem as yours. When I added the error checking to the out.open() function, I found the problem.
Most probably, the FOUR_CC codec of the camera is not supported by the avi container.
As you are using Windows, a good option is to use CV_FOURCC_PROMPT in the 2nd argument of out.open.
This will open a pop up list box containing different FOUR_CC codecs available. If you don't know which one to choose, just select Full Frames (Uncompressed). It is the most compatible option but will increase the size of the output video file.
The final code should look like this:
if(!out.open("out.avi",CV_FOURCC_PROMPT,20,s))
{
cout<<"Writer Not Opened"<<endl;
return -1;
}
Related
I have installed OpenCV on Windows 10 and using C++ in Visual Studio.
Now I'm trying to make a program that makes several photos then saves them.
Problem:
I made a copy of project on USB flash (go to another PC) and when I try to start it from .exe file, I get this error:
How can start it without installing 1Gb of FULL OpenCV libraries?
I tried to start from release version.
My C++ source:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <windows.h> // For Sleep
using namespace cv;
using namespace std;
int main(int, char**)
{
VideoCapture cap(0);
// Get the frame
Mat save_img; cap >> save_img;
if (save_img.empty())
{
std::cerr << "Something is wrong with the webcam, could not get frame." << std::endl;
}
// Save the frame into a file
imwrite("test.jpg", save_img); // A JPG FILE IS BEING SAVED
return 0;
}
My settings:
P.S. I want to make light program for making photo on Windows. And how to make real portable programs.
I'm doing a project with OpenCV. I am trying to run a simple code:
#include<opencv2/core.hpp>
#include<opencv2/videoio.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
cv::Mat img2 = cv::imread("test.jpg", 1);
if (!img2.data) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
cv::waitKey(5000);
return -1;
}
else {
cout << "Working" << endl;
cv::waitKey(5000);
}
return 0;
}
My project is a lot more bigger then this, however something simple like this isn't working for me. I have tried many things such as full path names // and \\, even tried an IplImage and convert it into Mat still no luck.
I have tried many different file types as well. If it helps I have coded it to stop the application after hitting any button, that does not work as it isn't taking any input from my keyboard.
How can I determine what is wrong?
I had this exact issue including the part about it only working in release mode. I found out I was using the release libraries for both release and debug. Because I had followed the tutorial on the OpenCV website for visual studio (incorrectly albeit), I changed the .lib folder to the correct d.lib and that fixed it.
I am trying to build an application, which get data from webcam or external device, saves Video Frames into text file, then read frames from created text file.
I don't know whether it is a good idea to save to text file, I'm open suggestions.
So far I've done to saving to a text file.
My problem is reading from text file. Basically I read text line by line, but I don't know how to convert this text into Mat object.
So far my code is:
ifstream read_storage(new_vid_frm_path);
if(!read_storage.is_open()) {
perror("\n\n\n\t\t\t(-)FAIL : Can't Open SavedVideoFrames.txt\n\n\n\t\t\t");
return -1;
}
VideoWriter *vid = new VideoWriter(new_vid_frm_path,CV_FOURCC('P', 'I', 'M', '1'),30,Size(vc.get(CV_CAP_PROP_FRAME_WIDTH),vc.get(CV_CAP_PROP_FRAME_HEIGHT)));
Mat line;
vector<Mat> vid_frms;
while ( getline (read_storage,line) ) {
cout << line << '\n';
}
read_storage.close();
if(vid_frms.size() == 0){
printf("\n\n\n\t\t\t(-)FAIL: Error In Frame\n\n\n\t\t\t");
return -1;
}
for(size_t i = 0; i<vid_frms.size(); i++)
(*vid).write(vid_frms[i]);
printf("\n\n\n\t\t\t(+)SUCCESS: Video Processing Complete \n\n\n\t\t\t ");
Do you have ay suggestions how can I cast or convert this line string to Mat obejct?
while ( getline (read_storage,line) ) {
cout << line << '\n';
}
Thanks.
By the way, I looked at this solution, but I couldn't understand.
Convert a string of bytes to cv::mat
I couldn't find the byte type in c++ and I think there might be a direct conversion between String to Mat object.
You can save anything (just about) in OpenCV to a .xml or .yml text file and then read it back in using the OpenCV XML/YAML FileStorage methods.
I highly recomend this over using native C++ methods for file stuff.
It's specifically designed to handle all this legwork for you.
I'm currently using OpenCV 2.3.1 with Visual Studio 2008. I'm trying to read the frames from a Hauppauge Usb Live-2 using VideoCapture, but I'm ran into a strange issue. Below is the relevant part of my code:
VideoCapture vc(0);
if (!vc.isOpened()) return -1;
Mat frame;
namedWindow("Camera");
bool success;
while (true)
{
success = vc.read(frame);
if (!success) continue;
imshow("Camera", frame);
if (waitkey(30) == 27) break;
}
Initially, when running my code in debug mode, the window displaying the captured frames shows only a solid gray image. Attempting to debug my program, I placed breakpoint a breakpoint at the start of my code and stepped through each line. At imshow, however, the window started displaying the grabbed frames properly, showing what was captured by my camera. Subsequently, I realized that so long as I enter a breakpoint between opening my device and displaying it on the window, the frames will start showing up properly.
Does anyone have any idea how entering a breakpoint may affect the execution of a program in debug mode (in this case allowing the VideoCapture object to start reading the frames properly)?
Note: Running the executable gave no problems either, so I'm posting this question out of curiosity.
I believe your code is trying to display the image (which is empty) before your camera gets ready. Try to slow down for one or two seconds, by first include files like:
#include <chrono>
#include <thread>
Then before your while statement, add this line:
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
If you are using C++ with lower version than 11, then the sleep_for method might be different. Take a reference here.
The camera has an initialisation period so you need to check for empty frames.
Now there are two options, you could do what #Derman has said and put in a wait but how do you know how long you need to wait for?
Or you can check for empty frames and only show the window if they are not empty
VideoCapture vc(0);
if ( !vc.isOpened() ) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}
Mat frame;
namedWindow("Camera");
bool success;
while (true)
{
vc.read(frame);
if(frame.empty()){
std::cerr<<"frame is empty"<<std::endl;
break;
}
imshow("Camera", frame);
if (waitkey(30) == 27) break;
}
I don't see any reason why this code shouldn't start showing the frames once they are avaliable from the camera
I am trying to write a video in OpenCV in Windows and am meeting various issues when choosing codecs. I'm not sure if it is something in my code or I do not have the codecs necessary. The code is:
int main(int argc, char ** argv){
VideoCapture inputVideo("LFW.mp4");
Mat inputFrame, outputFrame;
VideoWriter outputVideo;
if (!inputVideo.isOpened()){
std::cout << "!!! Input video could not be opened" << std::endl;
return 1;
}
int ex = static_cast<int>(inputVideo.get(CV_CAP_PROP_FOURCC));
const string name = "Output.mp4";
Size size = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), (int) inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT));
outputVideo.open(name, CV_FOURCC('M','P','4','2'), inputVideo.get(CV_CAP_PROP_FPS), size, true);
if (!outputVideo.isOpened()){
std::cout << "!!! Output video could not be opened" << std::endl;
return 2;
}
return 0;
}
The code keeps exiting with code 2, therefore the videoWriter object is not happy with its configuration.
I have a problem with many codecs on windows. I have installed ffmpeg correctly, but still there is a problem with many video format.
Try this one CV_FOURCC('W', 'M', 'V', '2')
VideoWriter video("Result.wmv", CV_FOURCC('W', 'M', 'V', '2'), 30, SizeOfFrame, true);
WMV is awful format but works perfect for me. I am working with Visual Studio 2015 and my own build of Opencv 3.0.0.
In Opencv 3.0.0, I can strongly recommend include also
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "opencv2/videoio/videoio.hpp"
There is anoter recommandation. Check size of input video and size of VideoWriter. CV_CAP_PROP_FRAME_WIDTH and CV_CAP_PROP_FRAME_HEIGHT in some cases return wrong values. Check both sizes before video.write(Mat)
You can check your video writer by this loop.
Set your writer sizes as dummy constant.
Size SizeOfFrame = cv::Size( 800, 600);
VideoWriter video("Result.wmv", CV_FOURCC('W', 'M', 'V', '2'), 30, SizeOfFrame, true);
In video loop resize retrieved video to same size as writer. If this fail your installation is probably wrong.
for (;;)
{
bool Is = cap.grab();
if (Is == false) {
cout << "cannot grab video frame" << endl;
}
else {
cap.retrieve(LoadedImage, CV_CAP_OPENNI_BGR_IMAGE);
resize(LoadedImage, LoadedImage, Size(800, 600));
video.write(LoadedImage);
}
}
My Tutorial here
It is not uncommon that people have codec issues when working with VideoCapture and VideoWriter. (Another less common issue is that OpenCV has been compiled without an encoder (like using WITH_FFMPEG=NO or WITH_VFW=NO when compiling OpenCV) )
I would try the following things dissect the problem (ordered by the level of hassle involved :) ):
Try running the same program but passing -1instead of CV_FOURCC('M','P','4','2') as the second argument to outputVideo.open(). You will then get a pop-up asking you to select codec and can then see which ones OpenCV finds.
If that doesn't help you - use a debugger to step into outputVideo.open(). You might turn out to arrive at an empty function (#ifdefed away due to some preprocessor macro). Unfortunately you will have to have a debug-compiled OpenCV with pdb-files to do this properly.