Recently installed OpenCV 2.4.3 to try to do some video capturing and object distinction. But sadly, every attempt to capture video through web-camera results in memory access violation.
I'm using Visual Studio 2010 (Win 7 x86), and web-camera "A4 Tech USB2.0". First I thought that maybe problem is with camera itself, but then i tried using videoInput.h lib to get any response from camera, still no result. (Other apps like Skype see it (and make it work) no-problem).
Here is a code (almost by the book):
<pre>
#include "cv.h"
#include "highgui.h"
#include "stdlib.h"
#include "stdio.h"
int main(int argc, char* argv[])
{
CvCapture* capture = cvCreateCameraCapture(CV_CAP_ANY); //cvCaptureFromCAM( 0 );
assert( capture );
double width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
double height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
printf("[i] %.0f x %.0f\n", width, height );
IplImage* frame=0;
cvNamedWindow("capture", CV_WINDOW_AUTOSIZE);
printf("[i] press Esc for quit!\n\n");
if(capture != NULL)
{
while(true)
{
frame = cvQueryFrame( capture ); //it crashes here all the time
cvShowImage("capture", frame);
char c = cvWaitKey(35);
if (c == 27)
{
break;
}
}
}
cvReleaseCapture( &capture );
cvDestroyWindow("capture");
return 0;
}
</pre>
Read other topics with the same issue and tried to account some problems:
(add interval between captures cvWaitKey(35),
add check for if capture device really exists if (capture != NULL)
) but still can`t understand why this keep happening.
UPDATE: What i basically get in the end is console with generated atributes of the OpenCVwindow and window itself(gray background it seems). And memory access violation error.
After some thought and testing, found the resolution.
It seems, that DirectVobSub filter on DirectShow somehow prevented me from accessing my camera programmly (both through OpenCV and VideoInput libs). It created a new instance of itself every time I ran my program and accessed my camera, which led to Access Memory Violation). After uninstalling it from my PC, the code started to work.
Related
Problem description:
With the simple code I can access my internal camera webcam and also change the resolution. So displaying the frame with default resolution and with a predefined resolution (e.g., from 640x480 to 320x240, with cap.set(CV_CAP_PROP_FRAME_WIDTH,320), and FRAME_HEIGHT, 240)) – both work fine.
Using the same code with slight adaption so that it works with a Ximea camera (VideoCapture cap(CV_CAP_XIAPI)), does work for the default resolution.
It is a MU9PC_MH with a default resolution of 2592x1944, so 648 x486 is the lower resolution which is required.
For a manually set resolution the displayed window/grabbed frame has the size of the default resolution (2592x1944) and shows the lower amount of pixels of the capture in the this huge display, so that the upper fifths is filled with puzzled pixels and the rest of the window is black.
This effect happens for both, C++ with VideoCapture and Mat and for C CvCaptureFromCAM and IplImage*.
When I’m using the set flag CV_CAP_PROP_XI_DOWNSAMPLING, then I can see the output image with pixels in correct order, but the display frame has still the default high resolution and the output image is shown multiple times (the factor depends on the factor I am using for downsampling).
I’m even not able to force the Mat or IplImage to a predefined size, because then an error of assertion or access violation occurs(Mat image(XRES, YRES, CV_8UC3, Scalar(0,0,255)) (frame = cvCreateImage(cvSize( XRES, YRES), IPL_DEPTH_8U,3);. I've checked through frame.type(), that the output is an CV_8UC3
What I want is a Ximea camera output of 648x486 shown in an (ideally) Mat of same size.
Did anyone experience the same problem?
Probably it is due to a lack in my knowledge about industrial camera configuration/development, but any help is appreciated.
Situation:
Windows 7(x64)
Visual Studio Professional 2012
OpenCV Version 2.4.10 compiled for x86 with following flags checked: WITH_XIMEA and WITH_OPENGL
Simple VS2012 Project in x86 (both release and debug) for camera streaming and displaying of camera frame in window.
Simple Code Snippets(not mine, copied from opencv tutorials and ximea):
C++-Style:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char **argv) {
VideoCapture cap(0); // open the default camera
//VideoCapture cap(CV_CAP_XIAPI);
if(!cap.isOpened()) // check if we succeeded
return -1;
cout<<" "<<cap.get(CV_CAP_PROP_FRAME_WIDTH)<<" "<<cap.get(CV_CAP_PROP_FRAME_HEIGHT)<<endl; //output: 640, 480
cap.set(CV_CAP_PROP_FRAME_WIDTH,XRES);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,YRES);
cout<<" "<<cap.get(CV_CAP_PROP_FRAME_WIDTH)<<" "<<cap.get(CV_CAP_PROP_FRAME_HEIGHT)<<endl; //output: 320, 240
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("camera frame", frame);
if(waitKey(30) == 27) //wait for 'esc' key press
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;}
C-Style:
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <iostream>
using namespace cv;
using namespace std;
// A Simple Camera Capture Framework
int main()
{
CvCapture* capture = cvCaptureFromCAM( CV_CAP_XIAPI );
if ( !capture ) {
fprintf( stderr, "ERROR: capture is NULL \n" );
getchar();
return -1;
}
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 648 );
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 486 );
// Create a window in which the captured images will be presented
cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );
// Show the image captured from the camera in the window and repeat
while ( 1 ) {
// Get one frame
IplImage* frame = cvQueryFrame( capture );
cout<<cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH); //output: 648
cout<<cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT); //output: 486
cout<<frame->height<<frame->width<<endl; //output: 1944, 2592
if ( !frame ) {
fprintf( stderr, "ERROR: frame is null...\n" );
getchar();
break;
}
cvShowImage( "mywindow", frame );
// Do not release the frame!
//If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
//remove higher bits using AND operator
if ( (cvWaitKey(10) & 255) == 27 ) break;
}
// Release the capture device housekeeping
cvReleaseCapture( &capture );
cvDestroyWindow( "mywindow" );
return 0;
}
thank you karlphillip for your answer. Unfortunately, you are right that this was not an ideal way. So I take yesterday's snowy wheather and found the solution myself:
There's a mistake in the resetCvImage() method of the cap_ximea.cpp.
line 207 if( (int)image.width != width || (int)image.height != height
|| image.frm != (XI_IMG_FORMAT)format)
has to be:
if( (int)image.width != **frame->**width || (int)image.height != **frame->**height || image.frm != (XI_IMG_FORMAT)format)
VideoCapture::set() returns a bool to indicate the success of the method. You shouldn't let your application continue to run without checking the success/failure of this call and readjusting the size of the capture when necessary.
The fact is that some camera drivers don't accept arbitrary dimensions, and there's simply nothing you can do about it. However, you can retrieve the frame using the default size and then cv::resize() it to your needs.
It's not ideal, but it will get the job done.
I have a simple GTK+ v3 GUI application, and I am making use of the OpenCV library so that I have a simple function for taking pictures from the one webcam connected to my computer. The code is included at the bottom of this post.
I'm able to successfully acquire image data and render it on screen, but when I include this code in my GTK+ v3 project, I get a startup error like so:
(result:2944): Gtk-ERROR **: GTK+ 2.x symbols detected.
Using GTK+ 2.x and GTK+3 in the same process is not supported.
Trace/breakpoint trap.
So, this makes sense so far. One of the OpenCV libraries apparently makes use of Gtk+ v2. It turns out that if I remove libopencv_highgui from my list of libraries to link against, I won't have this issue. However, the functions used to acquire image data from the webcam is included in that library for some reason.
Are there other functions accessble via the C or C++ APIs for OpenCV that don't require me to make use of libopencv_highgui and allow me to take a snapshot from a webcam with ease?
The other alternative seem to be re-writing my project as a Gtk+ v2 application, which wouldn't be so bad, seeing as I haven't gone too far into it.
Is there a hidden option C out there? (Pardon the pun ;) ).
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
#include <errno.h>
using namespace std;
using namespace cv;
#define PROJECT_NAME "CAMERA_MODULE" // Include before liblog
#include "../../lib/liblog/inc/log.h"
int cameraAcquireImage(void) {
CvCapture* capture = 0;
Mat frame, frameCopy, image;
//0=default, -1=any camera, 1..99=your camera
capture = cvCaptureFromCAM(CV_CAP_ANY);
if(!capture) {
logError("No camera interface detected");
return (-EIO);
}
cvNamedWindow( "result", CV_WINDOW_AUTOSIZE );
if(capture) {
logError("Capture in progress");
for( ; ;) {
IplImage* iplImg = cvQueryFrame(capture);
frame = iplImg;
if(frame.empty()) {
break;
}
if(iplImg->origin == IPL_ORIGIN_TL) {
frame.copyTo(frameCopy);
} else {
flip(frame, frameCopy, 0);
}
cvShowImage( "result", iplImg );
if( waitKey( 10 ) >= 0 ) {
break;
}
}
}
cvReleaseCapture( &capture );
cvDestroyWindow("result");
return 0;
}
I can think of the following solutions:
Downgrade to GTK 2 - pretty simple.
Since VideoCapture is one the very few modules that depend on
highgui, use something else for video capture (Video4Linux perhaps)
and then use OpenCV modules which do not depend on highgui.
Build OpenCV with GTK 3 support (WITH_GTK=ON WITH_GTK3=ON).
Use Qt instead of GTK if you can.
I'm new at this but have been doing my share of reading and trying different setups to help narrow down the problem! Any help tp get me past this road block would be much appreciated.
Currently I'm running: Win 7 Ultimate, Visual C++ 2010 Express, OpenCV 2.2.0, and a Microsoft - LifeCam Studio Webcam - Silver 1080p HD.
I'm getting no Build errors and when I run the program my camera comes on (blue light indicating it being on) and the screen pops up that i thought should show my camera feed but instead its just a grey box with nothing inside. The below code I thought would help narrow down the problem but I'm at a loss.
int main()
{
CvCapture *webcam = NULL;
webcam = cvCreateCameraCapture(-1);
if(webcam!=NULL)
{
IplImage *frame = cvQueryFrame(webcam);
cvShowImage("WEBCAM_TEST",frame);
cvWaitKey(0);
return 0;
}
else
{
std::cout<<"CAMERA NOT DETECTED"<<std::endl;
return 0;
}
}
your code is some times showing a black image sometimes showing a correct image on my system(Windows 7 64 VS2010 OpenCV 2.4.3)...how ever when I put it in a loop for non stop streaming the image is ok...so just modify your code slightly and try...
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
int main()
{
CvCapture *webcam = NULL;
webcam = cvCreateCameraCapture(-1);
if(webcam!=NULL)
{
while(true)
{
IplImage *frame = cvQueryFrame(webcam);
cvShowImage("WEBCAM_TEST",frame);
cvWaitKey(20);
}
}
else
{
std::cout<<"CAMERA NOT DETECTED"<<std::endl;
return 0;
}
return 0;
}
In OpenCV if you get frame just after creating camera capture usually it's grey. All you have to do is just get next frame or wait before getting first frame. This code:
int _tmain(int argc, _TCHAR* argv[])
{
VideoCapture cap(0);
if(!cap.isOpened())
return -1;
Mat frame;
namedWindow("01",1);
//cap >> frame; //option 1
//waitKey(5000); //option 2
cap >> frame;
imshow("01", frame);
int key = waitKey(30);
return 0;
}
will show grey frame, but if you uncomment option 1 or option 2 - it will work fine.
Good day everyone! So currently I'm working on a project with video processing, so I decided to give a try to OpenCV. As I'm new to it, I decided to find few sample codes and test them out. First one, is C OpenCV and looks like this:
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <stdio.h>
int main( void ) {
CvCapture* capture = 0;
IplImage *frame = 0;
if (!(capture = cvCaptureFromCAM(0)))
printf("Cannot initialize camera\n");
cvNamedWindow("Capture", CV_WINDOW_AUTOSIZE);
while (1) {
frame = cvQueryFrame(capture);
if (!frame)
break;
IplImage *temp = cvCreateImage(cvSize(frame->width/2, frame->height/2), frame->depth, frame->nChannels); // A new Image half size
cvResize(frame, temp, CV_INTER_CUBIC); // Resize
cvSaveImage("test.jpg", temp, 0); // Save this image
cvShowImage("Capture", frame); // Display the frame
cvReleaseImage(&temp);
if (cvWaitKey(5000) == 27) // Escape key and wait, 5 sec per capture
break;
}
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
return 0;
}
So, this one works perfectly well and stores image to hard drive nicely. But problems begin with next sample, which uses C++ OpenCV:
#include "opencv2/opencv.hpp"
#include <string>
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_RGB2XYZ);
imshow("edges", edges);
//imshow("edges2", frame);
//imwrite("test1.jpg", frame);
if(waitKey(1000) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
So, yeah, generally, in terms of showing video (image frames) there is practically no changes, but when it comes to using im** functions, some problems arise.
Using cvSaveImage() works out nicely, but the moment I try to use imwrite(), unhandled exception arises in regards of 'access violation reading location'. Same goes for imread(), when I'm trying to load image.
So, the thing I wanted to ask, is it possible to use most of the functionality with C OpenCV? Or is it necessary to use C++ OpenCV. If yes, is there any solution for the problem I described earlier.
Also as stated here, images initially are in BGR-format, so conversion needed. But doing BGR2XYZ conversion seems to invert colors, while RGB2XYZ preserve them. Examples:
images
Or is it necessary to use C++ OpenCV?
No, there is no necessity whatsoever. You can use any interface you like and you think you are good with it (OpenCV offers C, C++, Python interfaces).
For your problem about imwrite() and imread() :
For color images the order channel is normally Blue, Green, Red , this
is what imshow() , imread() and imwrite() expect
Quoted from there
I have searched a lot about my simple problem but I didn't find solution. When I run my code black console shows me the camera frame size but in the window video is not showing, it shows a solid gray screen. But if I play a video from HDD then it works fine.
Please help me some one.
This is my code
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace std;
int main(int argc, char** argv){
CvCapture *capture;
IplImage* img=0;
cvNamedWindow("Window");
capture = cvCreateCameraCapture( -1);
//capture = cvCaptureFromAVI("1.mp4");
//capture = cvCaptureFromCAM(-1);
int ext=0;
assert( capture );
if(capture==NULL){
cout<<"Cam Not Found!!!"<<endl;
getchar();
return -5;
}
while ( true ){
img = cvQueryFrame( capture );
cvSaveImage("1.jpg",img);
if (!img){
printf("Image not Found\n");
break;
}
cvShowImage("Window", img);
cvWaitKey(50);
}
cvReleaseImage(&img);
cvDestroyWindow("Window");
cvReleaseCapture(&capture);
return 0;
}
I use opencv 2.2 and Visual studio 2010
One thing is obviouslly wrong, you need to change the order of the calls to:
cvShowImage("Window", img);
cv::waitKey(20);
Second, it's essential that you check the success of cvQueryFrame():
img = cvQueryFrame( capture );
if (!img)
{
// print something
break;
}
EDIT:
By the way, I just noticed you are mixing the C interface of OpenCV with the C++ interface. Don't do that! Replace cv::waitKey(50); by cvWaitKey(50);.
For debugging purposes, if cvQueryFrame() succeeds I suggest you store one frame to the disk with cvSaveImage(), and if that image is OK it means the capture procedure is actually working perfectly and the problem is somewhere else.
I jast switch the openCV version 2.2 to 2.1 and its work perfectly.......
I am using OpenCV version 3.1, I got the same problem, I re-built openCV 3.1 and re-checked Environment Variables, so my problem resolved. You can back-up built-opencv and extract if you need. Sorry for my bad english :)