OpenCV C++ Video Capture does not seem to work - c++

I am using a Mac OS X 10.6 machine. I have OpenCV 2.1 x64 compiled from source using Xcode and its GCC compiler.
I am having trouble using the C++ video reading features of OpenCV. Here is the simple test code I am using (came straight from OpenCV documentation):
#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(200) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
The program compiles fine, but when I try to run it, I see the green light on my webcam come on for a few seconds, then the program exits with the error message:
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /Users/mark/Downloads/OpenCV-2.1.0/src/cxcore/cxarray.cpp, line 2476
terminate called after throwing an instance of 'cv::Exception'
what(): /Users/mark/Downloads/OpenCV-2.1.0/src/cxcore/cxarray.cpp:2476: error: (-206) Unrecognized or unsupported array type in function cvGetMat
Under debug mode, the matrix still seems to be empty after the cap >> frame line.
I get similar behavior when I try to capture from a video file or an image, so it's not the camera. What is wrong, do you think? Anything I can do to make this work?
EDIT: I'd like to add that if I use the C features, everything works fine. But I would like to stick with C++ if I can.
Thanks

I've seen the same problem. When I use the C features, sometimes the similar question also comes up. From the error message of the C code, I think it happened because the camera got a NULL frame. So I think it can be solved in this way:
do
{
capture>>frame;
}while(frame.empty());
That way it works on my machine.

I encountered the same problem, it seems that the first two attempts to get the video wont return any signal, so if you try to use it you'll get an error, here is how I got around this, simply by adding a counter and checking the size of the video.
int cameraNumber = 0;
if ( argc > 1 )
cameraNumber = atoi(argv[1]);
cv::VideoCapture camera;
camera.open(cameraNumber);
if ( !camera.isOpened() ) {
cerr << "ERROR: Could not access the camera or video!" << endl;
exit(1);
}
//give the camera 40 frames attempt to get the camera object,
//if it fails after X (40) attemts the app will terminatet,
//till then it will display 'Accessing camera' note;
int CAMERA_CHECK_ITERATIONS = 40;
while (true) {
Mat cameraFrame;
camera >> cameraFrame;
if ( cameraFrame.total() > 0 ) {
Mat displayFrame( cameraFrame.size(), CV_8UC3 );
doSomething( cameraFrame, displayFrame );
imshow("Image", displayFrame );
} else {
cout << "::: Accessing camera :::" << endl;
if ( CAMERA_CHECK_ITERATIONS > 0 ) CAMERA_CHECK_ITERATIONS--;
if ( CAMERA_CHECK_ITERATIONS < 0 ) break;
}
int key = waitKey(200);
if (key == 27) break;
}

Try simplifying the program so that you can identify the exact location of the problem, e.g. change your loop so that it looks like this:
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);
imshow("edges", frame);
if(waitKey(200) >= 0) break;
}
If that works OK then try adding the processing calls back in, one at a time, e.g
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(200) >= 0) break;
}
and so on...
Once you've identified the problematic line you can then focus on that and investigate further.

Go to project->project properties->configuration properties->linker->input
In the additional dependencies paste cv210.lib cvaux210.lib cxcore210.lib highgui210.lib

Hi I got the solution for you :)
VideoCapture san_cap(0);
if (san_cap.isOpened()) {
while (1) {
san_cap.read(san);
imshow("Video", san);
Mat frame;
san_cap.read(frame); // get a new frame from camera
cvtColor(frame, edges, CV_BGR2GRAY);
imshow("Video2", edges);
int key = cv::waitKey(waitKeyValue);
if (key == 27 ) {
break;
}
}
}

Related

Picture and text on video capture

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

Modifying a video stream in real time

I need to access the pixel data from a video camera attached to my Windows PC in real time. Once accessed, I will modify it and output it as part of the video stream. In other words, I need to find the easiest way to modify a video stream in real time. I know about OpenCV and Matlab functionality, but I am wondering if anyone has found a simpler way to do this.
If you want to do this with C++, OpenCV, as long as it works with your camera, is one of the simplest ways there is. The code below is from the OpenCV documentation VideoCapture. The only trick is instantiating the VideoCapture instance. How much simpler can it be?
#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 edges;
namedWindow("edges",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
cvtColor(frame, edges, COLOR_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;
}
There is even a python version at Capture Video from Camera that looks very similar to the C++ version above.

Contours opencv c++ Assertation failed (scn == 3 || scn == 4) [duplicate]

I read alot from other solution but i still confused what should i do with mine...
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(int argc, const char** argv)
{
//create the cascade classifier object used for the face detection
CascadeClassifier face_cascade;
//use the haarcascade_frontalface_alt.xml library
face_cascade.load("haarcascade_frontalface_alt.xml");
//setup video capture device and link it to the first capture device
VideoCapture captureDevice;
captureDevice.open(0);
//setup image files used in the capture process
Mat captureFrame;
Mat grayscaleFrame;
//create a window to present the results
namedWindow("outputCapture", 1);
//create a loop to capture and find faces
while (true)
{
//capture a new image frame
captureDevice >> captureFrame;
//convert captured image to gray scale and equalize
cvtColor(captureFrame, grayscaleFrame, CV_BGR2GRAY);
equalizeHist(grayscaleFrame, grayscaleFrame);
//create a vector array to store the face found
std::vector<Rect> faces;
//find faces and store them in the vector array
face_cascade.detectMultiScale(grayscaleFrame, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_SCALE_IMAGE, Size(30, 30));
//draw a rectangle for all found faces in the vector array on the original image
for (int i = 0; i < faces.size(); i++)
{
Point pt1(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
Point pt2(faces[i].x, faces[i].y);
rectangle(captureFrame, pt1, pt2, cvScalar(0, 255, 0, 0), 1, 8, 0);
}
//print the output
imshow("outputCapture", captureFrame);
//pause for 33ms
waitKey(33);
}
return 0;
}
This is the error
OpenCV Error: Assertion failed in unknown function
It seems the error happened after "captureDevice >> captureFrame;" Please guide me, this is taking image from camera.
It seems like VideoCapture can't grab frame from your camera. Add this code to check result of frame grabbing:
//create a loop to capture and find faces
while (true)
{
//capture a new image frame
captureDevice >> captureFrame;
if (captureFrame.empty())
{
cout << "Failed to grab frame" << endl;
break;
}
...
If it is a problem of VideoCapture check that you installed drivers for your camera.
Okay, I think I know what happened. I tried running the program and it worked perfectly.
You have probably not linked the required DLL's.. Make sure (in case you are using Windows) your opencv/bin is included in your environment variables. This is my CMakeLists.txt file to make things easier for you,
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(SO_example)
FIND_PACKAGE(OpenCV REQUIRED)
SET (SOURCES
#VTKtoPCL.h
main.cpp
)
add_executable(so_example ${SOURCES})
target_link_libraries(so_example ${OpenCV_LIBS})

How to close camera (OpenCv Beaglebone)

Good Day,
I am trying to figure out how to close the camera on a beaglebone in openCV. I have tried numerous commands such as release(&camera) but none exist and the camera continues to stay on when I don't want it to.
VideoCapture capture(0);
capture.set(CV_CAP_PROP_FRAME_WIDTH,320);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,240);
if(!capture.isOpened()){
cout << "Failed to connect to the camera." << endl;
}
Mat frame, edges, cont;
while(1){
cout<<sending<<endl;
if(sending){
for(int i=0; i<frames; i++){
capture >> frame;
if(frame.empty()){
cout << "Failed to capture an image" << endl;
return 0;
}
cvtColor(frame, edges, CV_BGR2GRAY);
Code is something like this, at the end of the for loop, I want to close the camera, but of course it still stays open
The camera will be deinitialized automatically in VideoCapture destructor.
Check this example from opencv docu:
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;
}
Also
cvQueryFrame
Grabs and returns a frame from camera or file
IplImage* cvQueryFrame( CvCapture* capture );
capture video capturing structure.
The function cvQueryFrame grabs a frame from camera or video file, decompresses and > returns it. This function is just a combination of cvGrabFrame and cvRetrieveFrame in one > call. The returned image should not be released or modified by user.
Also check: http://derekmolloy.ie/beaglebone/beaglebone-video-capture-and-image-processing-on-embedded-linux-using-opencv/
I hope this works for you. Best of luck.

Can't capture Video from Cam in OpenCV 2.4.7

This is my code which I copy/paste from here:
#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 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;
}
But I get this error:
OpenCV error: Assertion failed (scn==3 || scn==4)
in unknown function, file ..\..\..\..\opencv\modules\imgproc\src\color.cpp, line 3737
I am using Windows 7 x64, Visual Studio 2008, OpenCV 2.4.7
What can be the problem?
EDIT:
It is sometimes it works, sometimes it does not.
EDIT 2:
I edited VideoCapture cap(0); to cv::VideoCapture cap(0); then, I rebuild my solution and run it. It worked for the first time, I tried to run for the second time, it gave me the same error.
EDIT 3:
I have even edited for(;;):
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("edges", frame);
if(waitKey(30) >= 0) break;
}
This time I receive another error:
OpenCV error: Assertion failed (size.width>0 && size.height>0)
in unknown function, file ..\..\..\..\opencv\modules\highgui\src\window.cpp, line 261
I guess the problem is with imshow.
I get similar problem. I solve it by putting everything after cap >> frame into an if-statement:
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
if (!frame.empty()) {
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;
}
I tested your code in my environment (Win XP 32 bit OS, VS2008, OpenCV2.4.7). It works normally every time. And you can also do it like this:
IplImage* frame,*edges;
CvCapture* pcapture = cvCreateCameraCapture(0);
cvNamedWindow("edges",CV_WINDOW_AUTOSIZE);
while (1)
{
frame = cvQueryFrame(pcapture);
if (!frame) break;
edges = cvCreateImage(cvGetSize(frame),8,1);
cvCvtColor(frame, edges, CV_BGR2GRAY);
cvSmooth(edges,edges,CV_GAUSSIAN,7,7,1.5,1.5);
cvCanny(edges,edges,0,30,3);
cvShowImage("edges",edges);
cvReleaseImage(&edges);
if (cvWaitKey(30)>=0) break;
}
cvReleaseCapture(&pcapture);
cvDestroyWindow("edges");
You can have a try whether its also have some problems in your environment or not.
Hope a little help to you!