opcv videowriter, i don't know why it does'nt work - opencv

I've just written a first program for videocaptur and videowriter. I copied the source from the wiki and changed the only video file name, but it made error.
Here is the source from the wiki.
The opencv is 2.1 and the compiler is visual c++ 2008 express.
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main(int, char**)
{
VideoCapture capture(1); // open the default camera
if( !capture.isOpened() ) {
printf("Camera failed to open!\n");
return -1;
}
Mat frame;
capture >> frame; // get first frame for size
// record video
VideoWriter record("RobotVideo.avi", CV_FOURCC('D','I','V','X'), 30, frame.size(), true);
if( !record.isOpened() ) {
printf("VideoWriter failed to open!\n");
return -1;
}
namedWindow("video",1);
for(;;)
{
// get a new frame from camera
capture >> frame;
// show frame on screen
imshow("video", frame);
// add frame to recorded video
record << frame;
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
// the recorded video will be closed automatically in the VideoWriter destructor
return 0;
}
With the source, I changed 2 parts. One is for VideoCapture. (I don't have tunercard or camera.) The source is
VideoCapture capture(1); // open the default camera
and changed to
VideoCapture capture("C:/Users/Public/Videos/Sample Videos/WildlifeTest.wmv");
And the other is for VideoWriter:
// record video
VideoWriter record("RobotVideo.avi", CV_FOURCC('D','I','V','X'), 30, frame.size(), true);
and changed to
VideoWriter record("C:/Users/Public/Videos/Sample Videos/WildlifeRec.wmv",
CV_FOURCC('W','M','V','1'), 30,frame.size(), true);
and the part of error is:
// add frame to recorded video
record << frame;
Please show me what is my mistake!
P.S.
when I delete the line record << frame;, it works well. I think the error caused at the line.
And I found that even if without change, the wiki source program make same error.

The first error that i see is the file paths. You have to give them like this : C:\\Users\\....

please make sure you opencv_ffmpegXXX.dll work right

Related

OpenCV VideoCapture with H264 CODEC

I am using new logitech camera c920 for my project to do object recognition .
My camera can support H264 codec and can display H264 HD output.
But How I can set CODEC type as H264 in my below code to get out put as H264 DECODED STREAM
by using OpenCV instruction .
I am capturing video by using below logic : ref:this link
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("display", frame);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
By setting the fourCC property, you should be telling VideoCapture that your source is h.264. All the docs for openCV say that you will get decoded BGR data out though.
cap.set(CV_CAP_PROP_FOURCC, CV_FOURCC('H', '2', '6', '4'));

OpenCV VideoCapture reading issue

This will probably be a dumb question, but i really can't figure it out.
First of all: sorry for the vague title, i'm not really sure about how to describe my problem in a couple of words.
I'm using OpenCV 2.4.3 in MS Visual Studio, C++. I'm using the VideoCapture interface for capturing frames from my laptop webcam.
What my program should do is:
Loop on different poses of the user, for each pose:
wait that the user is in position (a getchar() waits for an input that says "i'm in position" by simply hitting enter)
read the current frame
extract a region of intrest from that frame
save the image in the ROI and then label it
Here is the code:
int main() {
Mat img, face_img, img_start;
Rect *face;
VideoCapture cam(0);
ofstream fout("dataset/dataset.txt");
if(!fout) {
cout<<"Cannot open dataset file! Aborting"<<endl;
return 1;
}
int count = 0; // Number of the (last + 1) image in the dataset
// Orientations are: 0°, +/- 30°, +/- 60°, +/-90°
// Distances are just two, for now
// So it is 7x2 images
cam.read(img_start);
IplImage image = img_start;
face = face_detector(image);
if(!face) {
cout<<"No face detected..? Aborting."<<endl;
return 2;
}
// Double ROI dimensions
face->x = face->x-face->width / 2;
face->y = face->y-face->height / 2;
face->width *= 2;
face->height *=2;
for(unsigned i=0;i<14;++i) {
// Wait for the user to get in position
getchar();
// Get the face ROI
cam.read(img);
face_img = Mat(img, *face);
// Save it
stringstream sstm;
string fname;
sstm << "dataset/image" << (count+i) << ".jpeg";
fname = sstm.str();
imwrite(fname,face_img);
//do some other things..
What i expect from it:
i stand in front of the camera when the program starts and it gets the ROI rectangle using the face_detector() function
when i'm ready, say in pose0, i hit enter and a picture is taken
from that picture a subimage is extracted and it is saved as image0.jpeg
loop this 7 times
What it does:
i stand in front of the camera when the program starts, nothing special here
i hit enter
the ROI is extracted not from the picture taken in that moment, but from the first one
At first, i used img in every cam.capture(), then i changed the first one in cam.capture(img_start) but that didn't help.
The second iteration of my code saves the image that should have been saved in the 1st, the 3rd iteration the one that should have been saved in the 2nd and so on.
I'm probably missing someting important from the VideoCapture, but i really can't figure it out, so here i am.
Thanks for any help, i really appreciate it.
The problem with your implementation is that the camera is not running freely and capturing images in real time. When you start up the camera, the videocapture buffer is filled up while waiting for you to read in the frames. Once the buffer is full, it doesn't drop old frames for new ones until you read and free up space in it.
The solution would be to have a separate capture thread, in addition to your "process" thread. The capture thread keeps reading in frames from the buffer whenever a new frame comes in and stores it in a "recent frame" image object. When the process thread needs the most recent frame (i.e. when you hit Enter), it locks a mutex for thread safety, copies the most recent frame into another object and frees the mutex so that the capture thread continues reading in new frames.
#include <iostream>
#include <stdio.h>
#include <thread>
#include <mutex>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void camCapture(VideoCapture cap, Mat* frame, bool* Capture){
while (*Capture==true) {
cap >> *frame;
}
cout << "camCapture finished\n";
return;
}
int main() {
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat *frame, SFI, Input;
frame = new Mat;
bool *Capture = new bool;
*Capture = true;
//your capture thread has started
thread captureThread(camCapture, cap, frame, Capture);
mtx.lock();
imshow(*frame,current_frame);
mtx.unlock();
//Terminate the thread
mtx.lock();
*Capture = false;
mtx.unlock();
captureThread.join();
return 0;
}
This is the code that I wrote from the above advice. I hope someone can get help from this.
When you are capturing the image continuously, no captured frame will be stored in the opencv buffer, such that there will be no lag in streaming.
If you take screenshot/capture image with some time gap inbetween, the captured image will be first stored in the opencv buffer, after that the image is retrieved from the buffer.
When the buffer is full, when you are calling captureObject >> matObject, the last frame from the image is returned, not the current frame in the capturecard/webcam.
So only you are seeing a lag in your code. This issue can be resolved by taking screenshot based on the frames per second (fps) value of the webcam and time taken to capture the screenshot.
The time taken to read frame from buffer is very less, Measure the time taken to take the screenshot. If it is lesser than the fps we can assume that is read from buffer else it means it is captured from webcam.
Sample Code:
For capturing a recent screenshot from webcam.
#include <opencv2/opencv.hpp>
#include <time.h>
#include <thread>
#include <chrono>
using namespace std;
using namespace cv;
int main()
{
struct timespec start, end;
VideoCapture cap(-1); // first available webcam
Mat screenshot;
double diff = 1000;
double fps = ((double)cap.get(CV_CAP_PROP_FPS))/1000;
while (true)
{
clock_gettime(CLOCK_MONOTONIC, &start);
//camera.grab();
cap.grab();// can also use cin >> screenshot;
clock_gettime(CLOCK_MONOTONIC, &end);
diff = (end.tv_sec - start.tv_sec)*1e9;
diff = (diff + (end.tv_nsec - start.tv_nsec))*1e-9;
std::cout << "\n diff time " << diff << '\n';
if(diff > fps)
{
break;
}
}
cap >> screenshot; // gets recent frame, can also use cap.retrieve(screenshot);
// process(screenshot)
cap.release();
screenshot.release();
return 0;
}

Why is the speed of AVI video increasing when reading it using OpenCV?

I am trying to read an AVI file using openCV. After getting the capture, the problem comes when I give a condition to the while loop which governs the extent to which queryFrame will be done.
There are total 1251 frames in the video.
When I use while (counter <= number_of_frames), the video runs fine and,
when I use while (cvQueryFrame(capture)), the video runs fine till 200-250th frame, then suddenly it starts running faster and finishes by 625th frame. I printed the FPS, it remains same all the time.
Why is this happening ??
Please help!
try the following...
C style reading..
#include <opencv2/video/video.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main()
{
CvCapture *video;
video = cvCreateFileCapture("ADDRESS TO THE FILE");
IplImage *frame;
while(true)
{
frame = cvQueryFrame(video);
if(frame->imageData==NULL)
{
std::cout<<"END OF VIDEO"<<std::endl;
break;
}
cvShowImage("VIDEO",frame);
cvWiatKey(25);//SINCE MOST OF THE VIDEOS RUN AT 25 FPS
}
return 0;
}
C++ STYLE....
int main()
{
VideoCapture video("ADDRESS OF VIDEO");
Mat frame;
while(true)
{
video >> frame;
if(frame.data==NULL)
{
std::cout<<"END OF VIDEO FILE"<<std::endl;
break;
}
imshow("VIDEO",frame);
waitKey(25);
}
return 0;
}
try this...and check if it gives an uniform rate of play...

Camera remains active after VideoCapture destructor is called

I've run this sample code:
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0);
if(!cap.isOpened()) return -1;
Mat frame, edges;
namedWindow("edges",1);
for(;;)
{
cap >> frame;
cvtColor(frame, edges, CV_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow("edges", edges);
if(waitKey(30) >= 0) break;
}
return 0;
}
It works fine, but after the application closes, the camera remains active. I know this because the flash led stays on until I kill the HPMediaSmartWebcam.exe process.
How do I close the camera after I've finished using VideoCapture?
According to the docs...here the camera will be deinitializd automatically in the class destructor...the destructor calls a virtual function cv::VideoCapture.release()...run the camera for a fixed number of frames and then see whether the LED of the webcam goes off or not..
int frames = 0;
while(frames!=1000)
{
//do frame capture from webcam and image processing...
++frames;
}

OpenCV can't find my USB webcam

I am trying to create an OpenCV application on my MacBook with built-in iSight camera. I grabbed some very simple code off the internet and ran it with no trouble. OpenCV automatically discovered the built-in webcam and ran properly but I can't get it to work with my USB webcam.
#include <stdio.h>
#include <opencv.hpp>
int main( int argc, char **argv )
{
CvCapture *capture = 0;
IplImage *frame = 0;
int key = 0;
/* initialize camera */
capture = cvCaptureFromCAM(0);
/* always check */
if ( !capture ) {
fprintf( stderr, "Cannot open initialize webcam!\n" );
return 1;
}
/* create a window for the video */
cvNamedWindow( "Test", CV_WINDOW_AUTOSIZE );
while( key != 'q' ) {
/* get a frame */
frame = cvQueryFrame( capture );
/* always check */
if( !frame ) break;
/* display current frame */
cvShowImage( "Test", frame );
/* exit if user press 'q' */
key = cvWaitKey( 1 );
}
/* free memory */
cvDestroyWindow( "Test" );
cvReleaseCapture( &capture );
return 0;
}
I compiled this with:
g++ webcam.c -o webcam -I/opt/local/include/opencv2 -I/opt/local/include -L/opt/local/lib -lopencv_core -lopencv_highgui
According to the documentation, by changing the line capture = cvCaptureFromCAM(0); to
capture = cvCaptureFromCAM(1); I should be able to access the other webcam that I have plugged in but running the program gives me the error message: Warning: Max Camera Num is 0; Using camera 0
What steps can I take to get OpenCV to recognize that I have another camera connected to my USB drive?
This is based on windows experience, but I believe the main issue to be the same. (To get input from a logitech USB-camera on my laptop.)
As far as I recall; OpenCV does not support multiple cameras, and thereby not the choice of camera.
I am guessing that you can easily run your build-in camera with the code you've shown.
My solution to a similar problem was deactivating the build-in camera. Giving the USB camera the only "availavle" slot for your cvCaptureFromCAM(0) function.
I hope this can solve your problem, even though the solution is a little 'clunky'.

Resources