Ask Your Question

Revision history [back]

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 exception or "assertion" stating that the frame's width and height were 0. Ports 1, 3, 5 and 7 do not have this problem. Even the ports that are not connected to a camera only display a blue screen, which is expected behaviour for the grabber card. Could it be the analogue camera's stream cannot be opened by OpenCV, but somehow in DirectShow? The build information returned shows that the build supports DirectShow, but it doesn't seem to help.

Second thing, is that this application, when run through the Visual Studio 2013 IDE (build and launch from the IDE with F5), all of the ports, 0 through 7, return empty frames. Only when you run the executable spawned by the IDE's build process does the application work as described in the paragraph above.

If anyone can give me any information regarding any of these issues, please advise. The OpenCV library is exactly what I need for my application, but if it can't open the hardware's video streams, I need to move to another option.