I can not capture image from my webcam using following OpenCV code.
The code can show images from a local AVI file or a video device. It works fine on a "test.avi" file.
When I make use my default webcam(CvCapture* capture =cvCreateCameraCapture(0)), the program can detected the size of the image from webcam,but just unable to display the image.
/I forgot to mention that I can see the iSight is working because the LED indicator is turn on/
Anyone encounter the same problem?
cvNamedWindow( "Example2", CV_WINDOW_AUTOSIZE );
CvCapture* capture =cvCreateFileCapture( "C:\\test.avi" ) ;// display images from avi file, works well
// CvCapture* capture =cvCreateCameraCapture(0); //display the frame(images) from default webcam not work
assert( capture );
IplImage* image;
while(1) {
image = cvQueryFrame( capture );
if( !image ) break;
cvShowImage( "Example2", image );
char c = cvWaitKey(33);
if( c == 27 ) break;
}
cvReleaseCapture( &capture );
cvDestroyWindow( "Example2" );
opencv 2.2
Debug library *d.lib
WebCam isight
Macbook OS win7 32
VS2008
I'm working on opencv 2.3 with Macbook pro Mid 2012 and I had that problem with the Isight cam. Somehow I managed to make it work on opencv by simply adjusting the parameters of the Cvcapture and adjusting the frame width and height:
CvCapture* capture = cvCaptureFromCAM(0);
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 500 );
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 600 );
You can also change these numbers to the frame width and height you want.
Did you try the example from the opencv page?
namely,
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat edges;
namedWindow("edges",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
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;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
Works on a macbook pro for me (although on OS X). If it doesn't work, some kind of error message would be helpful.
Try this:
int main(int, char**) {
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) { // check if we succeeded
cout << "===couldn't open camera" << endl;
return -1;
}
Mat edges, frame;
frame = cv::Mat(10, 10, CV_8U);
namedWindow("edges", 1);
for (;;) {
cap >> frame; // get a new frame from camera
cout << "frame size: " << frame.cols << endl;
if (frame.cols > 0 && frame.rows > 0) {
imshow("edges", frame);
}
if (waitKey(30) >= 0)
break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
Latest update! Problem solved!
This happen to be one of OpenCV 2.2′s bug
Here is how to fix it:
http://dusijun.wordpress.com/2011/01/11/opencv-unable-to-capture-image-from-isight-webcam/
Why dont you try
capture=cvCaptureFromCam(0);
I think this may work.
Let me know about wheather its working or not.
Related
I'm developing a project with visual studio 2010 and opencv. Here is my problem: i acquire a video from webcam, analize it, do some operation on it and then i show the result in another window (Object Tracking). The code is ok, no compiling errors but as soon as i start the program the console windows it closes immediately and i cannot see both the original and the modified video. If i debug the code i can see the webcam works and acquire images but obviously i ned to do this in real time. Any suggestion?
Can you give any code?
Are you write and compile any video player program like this?
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
//Video Capture cap(path_to_video); // open the video file
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("Video",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Video", frame);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
Try this:
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main() {
VideoCapture cap(0);
while (true)
{
Mat imgOriginal;
Mat imgHSV;
bool bSuccess = cap.read(imgOriginal);
cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
imshow("Thresholded Image", imgHSV);
imshow("Original", imgOriginal);
waitKey(33);
}
return 0;
}
I tried to open default camera using below code. But it can't. There is a topic same issue.But I can't find a menu to include HAVE_VIDEOINPUT HAVE_DSHOW. ( I tried cap(0) and cap(1) )
VideoCapture cap(1); // open the default camera
int iSliderValue1 = 50, iSliderValue2 = 255;
Mat thresholdImage;
Mat frame;
if(!cap.isOpened()) // check if we succeeded
{
cout << "Webcam cannot open!\n" ;
return -1;
}
Also,when I run "lsusb" command, the output is below
I am trying to use this code for background subtraction for a live camera feed. but this code is giving a white image in both the windows. the problem is that when tested with a video file from the same camera it is working fine, without any error but when the video file is replaced by a camera feed it becomes white and in the running window terminal it displays error as:
HIGHGUI ERROR: V4L2: Unable to get property (1) - Invalid
argument
The above error is continuously being repeated when the video is taken from camera feed. Please help to solve this problem.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <cv.h>
#include <iostream>
#include <sstream>
using namespace cv;
using namespace std;
Mat frame; //current frame
Mat fgMaskMOG; //fg mask generated by MOG method
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor
int keyboard;
int main()
{
//create GUI windows
namedWindow("Frame",0);
//namedWindow("FG Mask MOG",0);
namedWindow("FG Mask MOG 2",0);
namedWindow("eroded",0);
namedWindow("eroded2",0);
//create Background Subtractor objects
pMOG= new BackgroundSubtractorMOG(); //MOG approach
pMOG2 = new BackgroundSubtractorMOG2(); //MOG2 approach
//create the capture object
VideoCapture capture(0);
//read input data. ESC or 'q' for quitting
while( (char)keyboard != 'q' && (char)keyboard != 27 )
{
//read the current frame
if(!capture.read(frame))
{
cerr << "Unable to read next frame." << endl;
cerr << "Exiting..." << endl;
exit(EXIT_FAILURE);
}
//update the background model
//AND HERE!!!
//pMOG->operator()(frame, fgMaskMOG);
pMOG2->operator()(frame, fgMaskMOG2);
//get the frame number and write it on the current frame
stringstream ss;
rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
cv::Scalar(255,255,255), -1);
ss << capture.get(CV_CAP_PROP_POS_FRAMES);
string frameNumberString = ss.str();
putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
//show the current frame and the fg masks
imshow("Frame", frame);
imshow("FG Mask MOG", fgMaskMOG);
imshow("FG Mask MOG 2", fgMaskMOG2);
//get the input from the keyboard
keyboard = waitKey( 30 );
}
//delete capture object
capture.release();
//destroy GUI windows
distroyAllWindows();
return EXIT_SUCCESS;
}
I think property
CV_CAP_PROP_POS_FRAMES
not valid for camera.
When you read in an image, there is a flag you can set to 0 to force it as grayscale.
cv::Mat img = cv::imread(file, 0); // keeps it grayscale
Is there an equivalent for videos?
There's not.
You need to query the frames and convert them to grayscale yourself.
Using the C interface: https://stackoverflow.com/a/3444370/176769
With the C++ interface:
VideoCapture cap(0);
if (!cap.isOpened())
{
// print error msg
return -1;
}
namedWindow("gray",1);
Mat frame;
Mat gray;
for(;;)
{
cap >> frame;
cvtColor(frame, gray, CV_BGR2GRAY);
imshow("gray", gray);
if(waitKey(30) >= 0)
break;
}
return 0;
I just installed cvblob for object detection.
When I tried to run the program, the image would not show up and it gives me an error:
"VIDIOC_QUERYMENU: Invalid argument"
Here is the code.
#include "highgui.h"
#include "cv.h"
#include "cvaux.h"
#include "iostream"
#include <stdio.h>
#include <ctype.h>
#include <cvblob.h>
using namespace cv;
using namespace std;
using namespace cvb;
int main(int argc, char** argv) {
CvTracks tracks;
namedWindow("frame", CV_WINDOW_AUTOSIZE);
cvMoveWindow("frame", 50, 100);
CvCapture* capture;
IplImage* frame = 0;
// frame = cvLoadImage("fruits.jpg", 1);
capture = cvCreateCameraCapture( 1 ); //capture frames from cam on index 0: /dev/video0/
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 240);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 320);
frame = cvQueryFrame(capture);
while(capture) {
IplImage *gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
cvCvtColor(frame, gray, CV_BGR2GRAY);
cvThreshold(gray, gray, 150, 255, CV_THRESH_BINARY);
IplImage *labelImg=cvCreateImage(cvGetSize(gray), IPL_DEPTH_LABEL, 1);
CvBlobs blobs;
unsigned int result=cvLabel(gray, labelImg, blobs);
cvFilterByArea(blobs, 500, 1000000);
cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX);
cvUpdateTracks(blobs, tracks, 200., 5);
cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX);
// for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it) {
// cout << "Blob #" << it->second->label << ": Area=" << it->second->area << ", Centroid=(" << it->second->centroid.x << ", " << it->second->centroid.y << ")" << endl;
// }
cvShowImage("frame", frame);
frame = cvQueryFrame(capture);
}
}
If I uncomment the commented part, the blob information will be shown.
Can anyone help me find out why the image is not showing?
Thanks,
Milo
That error is coming from the video capture system, not cvBlob.
I see a few issues:
You must test capture after creating it to make sure you have successfully opened a camera.
Your while loop should be testing frame, not capture to make sure you've successfully received a frame of video.
Are you sure you have a camera at index 1?
Try this simplified version and see if it works. Note that I'm testing capture, looping while frame is not 0, and opening the camera at index 0. This works on my system.
int main(int argc, char** argv) {
namedWindow("frame", CV_WINDOW_AUTOSIZE);
cvMoveWindow("frame", 50, 100);
CvCapture* capture;
IplImage* frame = 0;
capture = cvCreateCameraCapture( 0 ); //capture frames from cam on index 0: /dev/video0/
if (!capture) {
return -1;
}
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 240);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 320);
frame = cvQueryFrame(capture);
while(frame) {
cvShowImage("frame", frame);
frame = cvQueryFrame(capture);
}
}
If this works for you, try changing the cvCreateCameraCapture argument to 1. Then try adding back your code a little at a time.