Video capture not working when launched from IDE (VS2013)
Hello, forum people. I'm new to using DirectShow and OpenCV, and I'm hoping someone could shed some light on some problems that I'm having.
My development environment is Visual Studio 2013 Ultimate. The hardware setup is 2 analogue (PAL input) video streams connected to a video grabber card. The grabber card has 8 ports, but only 2 are connected, ports 0 and 1. A demo application has been supplied that builds off of the Windows SDK AmCap sample of the DirectShow library. It outputs the two video feeds next to one another on the screen. Running AmCap itself delivers the expected results.
Now, here comes the weird part. I have a simple OpenCV application, constructed from what I've gleaned from the tutorials.
#include <iostream> // for standard I/O
#include <string> // for strings
#include <iomanip> // for controlling float print precision
#include <sstream> // string to number conversion
#include <stdlib.h>
#include <chrono>
#include <thread>
#include <Windows.h>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2/imgproc/imgproc.hpp> // Gaussian Blur
#include <opencv2/highgui/highgui.hpp> // OpenCV window I/O
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
const int port = 1;
VideoCapture vidIn;
vidIn.open(CV_CAP_DSHOW + port);
cout << getBuildInformation() << endl;
if (!vidIn.isOpened())
{
cout << "Can't open video capture device." << endl;
waitKey(0);
vidIn.release();
return -1;
}
const char* VID_IN = "Video Capture 1";
namedWindow(VID_IN, CV_WINDOW_AUTOSIZE);
char c;
int frameNum = -1; // Frame counter
Mat frameCam;
int frameEmpty = 0;
for (;;) //Show the image captured in the window and repeat
{
vidIn >> frameCam;
++frameNum;
// Output information per frame
cout << "-------------------------------------------------------------------" << endl;
cout << "FRAME " << frameNum << ": " << endl;
cout << "Brightness " << vidIn.get(CV_CAP_PROP_BRIGHTNESS) << endl;
cout << "Contrast " << vidIn.get(CV_CAP_PROP_CONTRAST) << endl;
cout << "Saturation " << vidIn.get(CV_CAP_PROP_SATURATION) << endl;
cout << "Hue " << vidIn.get(CV_CAP_PROP_HUE) << endl;
cout << "Gain " << vidIn.get(CV_CAP_PROP_GAIN) << endl;
cout << "Exposure " << vidIn.get(CV_CAP_PROP_EXPOSURE) << endl;
cout << "Width " << vidIn.get(CV_CAP_PROP_FRAME_WIDTH) << endl;
cout << "Height " << vidIn.get(CV_CAP_PROP_FRAME_HEIGHT) << endl;
// Show Image
if (frameCam.empty()){
cout << "Frame is empty: " << frameEmpty++ << "times." << endl;
if (frameEmpty >= 10) {
vidIn.release();
return -1;
}
}
else {
imshow(VID_IN, frameCam);
}
c = (char)cvWaitKey(20);
if (c == 27) {
break;
}
}
vidIn.release();
return 0;
}
OK, so that was cobbled together from resources I found online. In theory, this is supposed to work. (I know, I know...) I find an available camera (2 are connected, so the camera in the hardware array space 1 should be the second camera), open the stream, and infinite loop through getting a frame from the stream and painting it on the window.
Now, here's the kicker. When I try to run the application on my laptop (my native dev environment), it picks up my webcam fine and works. When I run it on the system described above, the cameras on ports 0, 2, 4 and 6 return empty frames. In other words, the stream opens successfully, but as soon as the code reaches
if (frameCam.empty())
it triggers the condition. This test condition was put in because displaying the frames resulted in an ...
Oh, one more thing. The video grabber card is identified by the target machine (Windows 7) as a "Sound, video and game controller", whereas the webcam on my development machine (Windows 8 laptop) as an "Imaging device". Could this affect the visibility of the cameras? If so, why does the application pick up odd numbered devices and not all of them?