I have implemented a openCV program which can capture frames from video file and process it and create a new file. That is doing for single in file . Now I want for multiple files . then I have an idea about POSIX thread pthread library . Is that is a good or bad idea . Actually when I implement pthreads in opencv program I got some errors like following :
OpenCV Error: Assertion failed (_src.sameSize(_dst) && dcn == scn) in
accumulate, file
/home/satinder/opencv_installation/OpenCV/opencv/modules/imgproc/src/accum.cpp,
line 915
what():
/home/satinder/opencv_installation/OpenCV/opencv/modules/imgproc/src/accum.cpp:915:
error: (-215) _src.sameSize(_dst) && dcn == scn in function accumulate
Aborted (core dumped)
corrupted double-linked list: 0x00007fcd048f73d0 ***
Aborted (core dumped)
seg fault also some time .
Is there any possible way how I can implement multi-threading or equivalent my goal make a program which can get more that one input files for same processing.
FOllowing is my code snapshot :
#include "opencv2/highgui/highgui.hpp"
#include <sys/types.h>
#include <pthread.h>
#include <iostream>
using namespace cv;
using namespace std;
void * VideoCap(void *);
void * VideoCap(void *arg)
{
VideoCapture cap((char *)arg); // open the video file for reading
if ( !cap.isOpened() ) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
exit(1);
}
//cap.set(CV_CAP_PROP_POS_MSEC, 300); //start the video at 300ms
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;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video file" << endl;
break;
}
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
}
int main(int argc, char* argv[])
{
int ret ;
pthread_t th[2];
ret = pthread_create(&th[0] , NULL , VideoCap , (void *)"cctv3.mp4");
if(0 == ret)
{
cout << "Thread 1 is created successfull" << endl;
}
ret = pthread_create(&th[1] , NULL , VideoCap , (void *)"cctv10.mp4");
if(0 == ret)
{
cout << "Thread 2 is created successfull" << endl;
}
pthread_join(th[0] , NULL);
pthread_join(th[1] , NULL);
return 0;
}
There are some problems with your code
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
You are creating two threads, so the windows should have different identifiers.
namedWindow((char *)arg, CV_WINDOW_AUTOSIZE);
...
imshow((char *)arg, frame);
Since this question was posted with linux tag, I'm guessing that gtk is relevant. After inserting the directives
#include <gdk/gdk.h>
#include <gtk/gtkmain.h>
at the beginning of the file and then in the main()
pthread_t th[2];
gtk_disable_setlocale();
gtk_init(&argc, &argv);
gdk_threads_init();
New linker / compiler flags are probably needed,
g++ -O -Wall test.cpp -lopencv_highgui -lopencv_core `pkg-config --libs --cflags gdk-2.0 gtk+-2.0`
After these changes there was still an occasional crash, so I added gdk_threads_enter() and gdk_threads_leave(); calls to test if they would help:
gdk_threads_enter();
namedWindow ((char *) arg, CV_WINDOW_AUTOSIZE);
gdk_threads_leave();
Since the crashing was not reproducible, it is hard to tell if those lines have any effect.
Related
I am using OpenCV 2.4.8 and Visual Studio 2013 to run the following simple VideoCapture program. The program is intended to capture the video from the webcam and display it.
However, the program works fine only for the FIRST TIME (after signing in windows), and doesn't work second time.
The problem I get on debugging is :
After executing this line - "bool bSuccess = cap.read(frame);" frame variable is still NULL.
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
char key;
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
if(!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
cout << "Frame size : " << dWidth << " x " << dHeight << endl;
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
Mat frame;
while(1)
{
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video file" << endl;
break;
}
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if(waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
This happen because the camera is not correctly closed after first instance of program. You should try to close the console by esc button and not by clicking X.
Could you try and read more than a single frame before breaking the loop? This may be similar to this problem, where a corrupted first frame / slow camera set up was the only problem.
Unable to read frames from VideoCapture from secondary webcam with OpenCV
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
if (!cap.isOpened()) // if not success, exit program
{
cout << "ERROR: Cannot open the video file" << endl;
return -1;
}
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
cout << "Frame Size = " << dWidth << "x" << dHeight << endl;
Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
VideoWriter oVideoWriter ("D:/MyVideo.avi", CV_FOURCC('P','I','M','1'), 20, frameSize, true); //initialize the VideoWriter object
if ( !oVideoWriter.isOpened() ) //if not initialize the VideoWriter successfully, exit the program
{
cout << "ERROR: Failed to write the video" << endl;
return -1;
}
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "ERROR: Cannot read a frame from video file" << endl;
break;
}
oVideoWriter.write(frame); //writer the frame into the file
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if (waitKey(10) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
I am developing this project using Visual Studio 2012 express and opencv_2.4.9 and windows 7 x64.
But, this code is not working.
Just write out this message "ERROR: Failed to write the video".
Use try, catch to see if you can get a more detailed error message.
One thing I remember when writing videos is that you need to verify you have the codecs installed and in the correct directory or added as a PATH environment variable.
opencv_ffmpeg.dll was the issue for me, and making sure it was in the correct directory and being renamed to opencv_ffmpeg249.dll
Using the code below, I am trying to create an app in C++ with OpenCV + Raspicam. This app should stream video in real time from the RasPi camera model connected to my Pi to an Xwindow.
I get the following error on compile:
videofeed.cpp: In function ‘int main(int, char**)’:
videofeed.cpp:36:37: error: ‘cv::imread’ is not a member of ‘raspicam::RaspiCam_Cv’
How do I remedy this?
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/videoio.hpp"
#include <iostream>
#include </home/pi/raspicam-0.1.3/src/raspicam_cv.h>
using namespace std;
int main ( int argc,char **argv ) {
raspicam::RaspiCam_Cv Camera;
cv::Mat image;
int nCount=100;
//set camera params
Camera.set( CV_CAP_PROP_FORMAT, CV_8UC1 );
//Open camera
cout<<"Opening Camera..."<<endl;
if (!Camera.open())// if not success, exit program
{
cout << "Cannot open the video cam" << endl;
return -1;
}
double dWidth = Camera.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames o$
double dHeight = Camera.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frame$
cout << "Frame size : " << dWidth << " x " << dHeight << endl;
cv::namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
while (1)
{
cv::Mat frame;
bool bSuccess = Camera.cv::imread(frame); // get a new frame from camera
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
cv::imshow("MyVideo", frame); //show the frame in "MyVideo" window
if (cv::waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' ke$
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////
bool bSuccess = Camera.cv::imread(frame); is an error,there is no imreadfunciton in raspicam::RaspiCam_Cv.If you want grub a frame,you can use function grub and than retrieve .
For example:
Mat img;
camera.grab();
camera.retrieve(img);
You can see the declaration:
/**
* Grabs the next frame from video file or capturing device.
*/
bool grab();
/**
*Decodes and returns the grabbed video frame.
*/
void retrieve ( cv::Mat& image );
Also ,you can get example in:https://github.com/cedricve/raspicam
I tried the following code for capturing a video from my webcam:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main()
{
VideoCapture cap(0); // open the video camera no. 0
if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video cam" << endl;
return -1;
}
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
cout << "Frame size : " << dWidth << " x " << dHeight << endl;
namedWindow("MyVideo", CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
namedWindow("Changed", CV_WINDOW_AUTOSIZE);
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
Mat imgH = frame + Scalar(75, 75, 75);
imshow("MyVideo", frame); //show the frame in "MyVideo" window
imshow("Changed", imgH);
if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
Now here's my problem:
After debugging that program for the first time everything works as expected. But when debugging for a second time (after changing some lines in the code) it cannot read from the camera.
Does anyone have a hint for me how to solve that problem?
Thanks!
The code you posted seems to be working absolutely fine in my case, and the output is as intended.
However please make sure that your webcam is switched on before you run the program, this is important.
Since i have a YouCam client in my computer for the webcam, therefore it shows that i need to start youcam.
Since i dont have enough reputation to post an image, so please see the following link in order to view the output i got when webcam not already switched on.
http://i.imgur.com/h4bTZ7z.png
Hope this helps!!
I'm try to get the error of opencv! say I have this program:
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
int main (){
cv::Mat frame;
cv::VideoCapture cap(1); // I don't have a second videoinput device!
int key = 0;
while(key !=27){
cap >> frame;
cv::imshow("frame",frame);
key = cv::waitKey(10);
}
cap.release();
return 0;
}
when I run this program I get in the console this message :
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in unknown functi
on, file ..\..\..\opencv\modules\highgui\src\window.cpp, line 261
My question is how can I get this message and save it in a string for every error that I get!
and if it'S possible escaping the program crash!
thanks in advance!
It uses C++ exceptions. See here in the doc for more.
try
{
... // call OpenCV
}
catch( cv::Exception& e )
{
const char* err_msg = e.what();
std::cout << "exception caught: " << err_msg << std::endl;
}
A CV_Assert in the OpenCV code is a macro which calls the OpenCV function error. That function can be seen here. It will always print the error text on stderr unless you don't have the customErrorCallback set. You do that via cvRedirectError, see here.
You have to check whether OpenCV function calls in your code is successfully executed or not. Then you can understand the exact problem. Here is the modified code.
int main (){
cv::Mat frame;
cv::VideoCapture cap(1); // I don't have a second videoinput device!
if ( !cap.isOpened() ) // if not success, exit program
{
cout << "Cannot open the video cam" << endl;
return -1;
}
int key = 0;
while(key !=27){
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video cam" << endl;
break;
}
cv::imshow("frame",frame);
key = cv::waitKey(10);
}
cap.release();
return 0;
}