I have been trying to get openCV to read an image from my computer's webcam. The code below successfully opens the webcam (green light turns on). However, attempts to grab a frame and hence read a frame fail. I am at a loss here. Can anyone help?
Many Thanks,
Hillary
P.S. I am running Mac OS X 10.9 on a MacBook Pro. And my opencv version is 2.4.6.1
And here is the code:
#include "opencv.hpp"
using namespace cv;
int main(int, char**) {
VideoCapture cap = VideoCapture(0);
if(!cap.isOpened()){
printf("failed to open camera\n");
return -1;
}
namedWindow("edges",1);
for(;;){
if(waitKey(50) >= 0 ) break;
if(!cap.grab()){
printf("failed to grab from camera\n");
}
}
return 0;
}
You forgot to read new frames in your loop and show them! There:
for(;;){
if(waitKey(50) >= 0 ) break;
Mat frame;
if(!cap.grab()){
printf("failed to grab from camera\n");
break;
}
cap >> frame;
if(frame.empty()){
printf("failed to grab from camera\n");
break;
}
imshow("edges", frame);
}
Related
I would like to put an image on video and i'm wondering if it's possible in opencv without multithreading.
I would like to avoid it because in my project i am operating on RPI 0W(that's whyi don't want multithreading) .
i can't find anything about it on internet. I got some basic code in c++ . I'm new to open cv.
int main(){
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error"<<endl;
return -1;
}
Mat edges;
namedWindow("edges", 1);
Mat img = imread("logo.png");
for (;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("edges", WINDOW_AUTOSIZE );
imshow("edges", img);
imshow("edges", frame);
if (waitKey(30) >= 0) break;
}
}
In OpenCV showing two things in the same window overwrites the previous one which I think is happening in your case.
You can use OpenCV addWeighted() function or bitwise operations.
OpenCV has good documentation on this. You can find it here
I use OpenCV to read several videos,
but the warning message disturbs me.
My program just reads frames from a video,
and calculates the MD5 of every frame.
string VIDEO::getEndingHash(){
int idx = 0;
cv::Mat frame;
while (1){
Cap_.set(CV_CAP_PROP_POS_FRAMES, _FrameCount - idx);
Cap_ >> frame;
if (frame.empty())
idx++;
else
break;
}
Cap_.set(CV_CAP_PROP_POS_FRAMES, 0);
return MD5::MatMD5(frame);
}
How to hide/disable ffmpeg erros when using OpenCV (C++)?
I'm trying to make a live stereovision setup using OpenCV in C++ and two webcams. It is possible to seperately get frames from the two webcams. However, when I try to access them simultaneously in threads, I get a runtime error:
VIDIOC_STREAMON: Cannot allocate memory
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /home/lorre851/Downloads/opencv-3.1.0/modules/highgui/src/window.cpp, line 281
terminate called after throwing an instance of 'cv::Exception'
what(): /home/lorre851/Downloads/opencv-3.1.0/modules/highgui/src/window.cpp:281: error: (-215) size.width>0 && size.height>0 in function imshow
My code is as follows:
#include <iostream>
#include <thread>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
void stream(int camera) {
VideoCapture cap(camera); // open the default camera
if(cap.isOpened()) { // check if we succeeded
while(true) {
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Stream " + to_string(camera), frame);
if (waitKey(30) >= 0) break;
}
}
}
int main() {
thread cam1 (stream, 1);
thread cam2 (stream, 2);
cam1.join();
cam2.join();
return 0;
}
Anybody got any idea what could be causing this? I'm using CLion on Ubuntu 15.10 LTE.
UPDATE 1: I'm using index 1 and 2 for the camera's because I have a built-in camera in my laptop (0) and two USB camera's (1 and 2) plugged in. The USB camera's are the target hardware here.
UPDATE 2: Putting both camera feeds in one thread (see code below) works just fine (assuming your USB ports use separate busses, otherwise you'll get a 'NO SPACE LEFT ON DEVICE' error), but the delay between the two frames is noticeable, which is not ideal for a stereovision setup.
cv::VideoCapture camera0(0);
cv::VideoCapture camera1(1);
if( !camera0.isOpened() ) return 1;
if( !camera1.isOpened() ) return 1;
cv::Mat3b frame0;
cv::Mat3b frame1;
while(true) {
camera0 >> frame0;
camera1 >> frame1;
if(mat_is_empty(frame0)) cout << "SKIPPED FRAME IN 0";
else cv::imshow("Stream 0", frame0);
if(mat_is_empty(frame1)) cout << "SKIPPED FRAME IN 1";
else cv::imshow("Stream 1", frame1);
int c = cvWaitKey(40);
//exit the loop if user press "Esc" key (ASCII value of "Esc" is 27)
if(27 == char(c)) break;
}
Maybe, I have stupid answer. Your code works fine..
Count cameras from zero.
thread cam1 (stream, 0); THIS works
// thread cam2 (stream, 1); I dont have second camera
First of all, I am on windows machine. My cameras are count from 0,1,2
I do not have second web camera.
In the picture i just use your code and paste cam(0) my web camera
and for the second camera i use testing rtsp stream.
#include <iostream>
#include <thread>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
void stream(int camera) {
VideoCapture cap;
if (camera == 0) {
cap.open(0); // open the default camera
}
if (camera == 1) {
cap.open("rtsp://mpv.cdn3.bigCDN.com:554/bigCDN/definst/mp4:bigbuckbunnyiphone_400.mp4"); // open the default camera
}
if (cap.isOpened()) { // check if we succeeded
while (true) {
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Stream " + to_string(camera), frame);
if (waitKey(30) >= 0) break;
}
}
}
int main() {
thread cam1(stream, 0);
thread cam2(stream, 1);
cam1.join();
cam2.join();
return 0;
}
I'm using OpenCV 3.1, I try to run a simple code as the following one (main function):
cv::VideoCapture cam;
cv::Mat matTestingNumbers;
cam.open(0);
if (!cam.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }
while (cam.read(matTestingNumbers))
{
cv::imshow("matTestingNumbers", matTestingNumbers);
cv::waitKey(5000);
}
When I move the camera it seems that the code does not capture and show the current frame but shows all the captured frames from the previous position and only then from the new one.
So when I capture the wall it shows the correct frames (the wall itself) in the correct delay, but, when I twist the camera to my computer, I first see about 3 frames of the wall and only then the computer, it seems that the frames are stuck.
I've tried to use videoCapture.set() functions and set the FPS to 1, and I tried to switch the method of capturing to cam >> matTestingNumbers (and the rest of the main function according to this change) but nothing helped, I still got "stuck" frames.
BTW, These are the solutions I found on web.
What can I do to fix this problem?
Thank you, Dan.
EDIT:
I tried to retrieve frames as the following:
#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;
Mat frame;
namedWindow("edges",1);
for(;;)
{
cap.grab();
if (waitKey(11) >= 0)
{
cap.retrieve(frame);
imshow("edges", frame);
}
}
return 0;
}
But, it gave the result (when I pointed the camera on one spot and pressed a key it showed one more of the previous frames that were captured of the other point).
It is just like you're trying to picture one person then another but when you picture the second you get the photo of the first person what doesn't make sense.
Then, I tried the following:
#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;
Mat frame;
namedWindow("edges",1);
for(;;)
{
cap >> frame;
if (waitKey(33) >= 0)
imshow("edges", frame);
}
return 0;
}
And it worked as expected.
One of the problems is that you are not calling cv::waitKey(X) to properly freeze the window for X amount of milliseconds. Get rid of usleep()!
I've 4 Axis IP cams. I need a code to capture image from those cams. I've opencv code to capture image from USB cams but I don't kno how to capture from IP cams.
int main()
{
Mat frame;
namedWindow("video", 1);
VideoCapture cap("http://150.214.93.55/mjpg/video.mjpg");
while ( cap.isOpened() )
{
cap >> frame;
if(frame.empty()) break;
imshow("video", frame);
if(waitKey(30) >= 0) break;
}
return 0;
}
no idea, how your urls look like, but opencv seems to insist, it has to end with mjpg.
so if it doesn't, the trick is to append a dummy parameter:
http://my/cool/ip-cam.ie?dummy=video.mjpg
if you need to open all 4 cams at once, you need a VideoCapture for each one:
VideoCapture cap1("url1");
VideoCapture cap2("url2");
VideoCapture cap3("url3");
VideoCapture cap4("url4");