Search code examples
windowsqtwebcam

Windows + Qt and how to capture webcam feed without OpenCV


I'm fighting with this problem from a long time. I can't get OpenCV to work, and I have follow a lot of tutorials about it and how to use in Qt, so I get tired and I want to avoid the use of OpenCV for this.

Now, my requirement or question... I need to show a webcam feed (real time video, without audio) in a Qt GUI application with only one button: "Take Snapshot" which, obviusly, take a picture from the current feed and store it.

That's all.

Is there anyway to get this done without using OpenCV ?

System specification:

  • Qt 4.8

  • Windows XP 32 bits

  • USB 2.0.1.3M UVC WebCam (the one I'm using now, it should support other models too)

Hope anybody can help me with this because I'm getting crazy.

Thanks in advance!


Solution

  • Ok, I finally did it, so I will post here my solution so we have something clear about this.

    I used a library called 'ESCAPI': http://sol.gfxile.net/escapi/index.html

    This provide a extremely easy way to capture frames from the device. With this raw data, I just create a QImage which later show in a QLabel.

    I created a simple object to handle this.

    #include <QDebug>
    #include "camera.h"
    
    Camera::Camera(int width, int height, QObject *parent) :
        QObject(parent),
        width_(width),
        height_(height)
    {
        capture_.mWidth = width;
        capture_.mHeight = height;
        capture_.mTargetBuf = new int[width * height];
    
        int devices = setupESCAPI();
        if (devices == 0)
        {
            qDebug() << "[Camera] ESCAPI initialization failure or no devices found";
        }
    }
    
    Camera::~Camera()
    {
        deinitCapture(0);
    }
    
    int Camera::initialize()
    {
        if (initCapture(0, &capture_) == 0)
        {
            qDebug() << "[Camera] Capture failed - device may already be in use";
            return -2;
        }
        return 0;
    }
    
    void Camera::deinitialize()
    {
        deinitCapture(0);
    }
    
    int Camera::capture()
    {
        doCapture(0);
        while(isCaptureDone(0) == 0);
    
        image_ = QImage(width_, height_, QImage::Format_ARGB32);
        for(int y(0); y < height_; ++y)
        {
            for(int x(0); x < width_; ++x)
            {
                int index(y * width_ + x);
                image_.setPixel(x, y, capture_.mTargetBuf[index]);
             }
        }
        return 1;
    }
    

    And the header file:

    #ifndef CAMERA_H
    #define CAMERA_H
    
    #include <QObject>
    #include <QImage>
    #include "escapi.h"
    
    class Camera : public QObject
    {
        Q_OBJECT
    
    public:
        explicit Camera(int width, int height, QObject *parent = 0);
        ~Camera();
        int initialize();
        void deinitialize();
        int capture();
        const QImage& getImage() const { return image_; }
        const int* getImageRaw() const { return capture_.mTargetBuf; }
    
    private:
        int width_;
        int height_;
        struct SimpleCapParams capture_;
        QImage image_;
    };
    
    #endif // CAMERA_H
    

    It's so simple, but just for example purposes. The use should be something like:

    Camera cam(320, 240);
    cam.initialize();
    cam.capture();
    QImage img(cam.getImage());
    ui->label->setPixmap(QPixmap::fromImage(img));
    

    Of course, you can use a QTimer and update the frame in QLabel and you will have video there...

    Hope it help! and thanks Nicholas for your help!