Qt 5.2.1 + OpenCV 2.4.9 in Visual Studio 2012



  • Hi!

    I'm currently trying to capture camera using cv::VideoCapture.
    Basically I subclassed QQuickPaintedItem, starting the camera and installing a QTimer, that calls update() every 50ms, in componentCompleted(). In paint() I then grab a frame and convert it to a QImage like this:
    @cv::Mat frame;
    cap >> frame;

    QImage qFrame(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
    qFrame = qFrame.rgbSwapped();@

    My problem now is, that as soon as I start the program the output in Visual Studio looks like this:
    @[...]
    The thread 0xec4 has exited with code 0 (0x0).
    The thread 0x1b0c has exited with code 0 (0x0).
    The thread 0x4f8 has exited with code 0 (0x0).
    The thread 0x1b14 has exited with code 0 (0x0).
    The thread 0x19e4 has exited with code 0 (0x0).
    The thread 0x1a4c has exited with code 0 (0x0).
    The thread 0x10c8 has exited with code 0 (0x0).
    The thread 0x58c has exited with code 0 (0x0).
    The thread 0xe10 has exited with code 0 (0x0).
    The thread 0x1ac4 has exited with code 0 (0x0).
    The thread 0x1578 has exited with code 0 (0x0).
    The thread 0x128c has exited with code 0 (0x0).
    The thread 0x1a64 has exited with code 0 (0x0).
    The thread 0x1a6c has exited with code 0 (0x0).
    The thread 0x1844 has exited with code 0 (0x0).
    The thread 0x1a60 has exited with code 0 (0x0).
    The thread 0x1924 has exited with code 0 (0x0).
    The thread 0x10d0 has exited with code 0 (0x0).
    The thread 0x1af0 has exited with code 0 (0x0).
    The thread 0x10e4 has exited with code 0 (0x0).
    [...]
    @
    And that's just a small part of it!
    I wrote another program with OpenCV only:
    @int main( int argc, char** argv ) {
    cv::VideoCapture cap(0);
    if (!cap.isOpened())
    return -1;

    cap.set(CV_CAP_PROP_FRAME_WIDTH, 1024);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 768);
    
    cv::namedWindow("frame", 1);
    while (true) {
        cv::Mat frame;
        cap >> frame;
    
        imshow("frame", frame);
    
        if(cv::waitKey(30) >= 0) break;
    }
    
    return 0;
    

    }@
    This works fine. No threads exiting all the time.

    I really don't know why this happens. I only found out that this starts as soon as I open the camera and I also tried to grab all frames in an extra thread. Nothing works...
    At least I see the output works correctly and everything is fine on the front-end, but this output is not only a bit strange but also annoying...

    Any ideas?

    Regards



  • I now also tried a Widget-based Qt app (as cv::namedWindow uses Widgets) with the following source code:
    @int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    cv::VideoCapture cap(0);
    if(!cap.isOpened())
        return -1;
    
    cv::namedWindow("frame", 1);
    
    cv::Mat frame;
    while (true) {
        cap >> frame;
    
        imshow("frame", frame);
    
        if(cv::waitKey(30) >= 0) break;
    }
    

    }@

    Same result...


  • Lifetime Qt Champion

    Hi,

    Can you show the code you used for your qml element ?



  • Yeah, of course!
    @class SHARED_EXPORT CaptureItem : public QQuickPaintedItem {
    Q_OBJECT

    cv::VideoCapture cap;
    QTimer timedUpdate;
    

    public:
    CaptureItem(QQuickItem *parent = 0);

    public:
    void paint(QPainter *painter);

    protected:
    void componentComplete();
    };@
    @CaptureItem::CaptureItem(QQuickItem parent / = 0 */)
    : QQuickPaintedItem(parent)
    {
    }

    void CaptureItem::paint(QPainter *painter) {
    QRectF boundingRect = contentsBoundingRect();
    boundingRect.setWidth(boundingRect.width() - 1);
    boundingRect.setHeight(boundingRect.height() - 1);

    cv::Mat frame;
    if (cap.isOpened()) {
        cap >> frame;
    
        QImage qFrame(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
        qFrame = qFrame.rgbSwapped();
    
        float aspectRatio = qFrame.width() / (float)qFrame.height();
        float itemAspectRatio = boundingRect.width() / boundingRect.height();
    
        QRectF paintRect;
        if (aspectRatio >= itemAspectRatio) {
            paintRect.setWidth(boundingRect.width());
    
            int height = boundingRect.width() / aspectRatio;
            paintRect.setY((boundingRect.height() - height) / 2.f);
            paintRect.setHeight(height);
        } else {
            paintRect.setHeight(boundingRect.height());
    
            int width = boundingRect.height() * aspectRatio;
            paintRect.setX((boundingRect.width() - width) / 2.f);
            paintRect.setWidth(width);
        }
    
        painter->drawImage(paintRect, qFrame);
    }
    

    }

    void CaptureItem::componentComplete() {
    QQuickPaintedItem::componentComplete();

    cap.open(0);
    
    timedUpdate.setInterval(100);
    connect(&timedUpdate, SIGNAL(timeout()), this, SLOT(update()));
    timedUpdate.start();
    

    }@

    Then within registerTypes(const char *):
    @qmlRegisterType<CaptureItem>(uri, 1, 0, "CaptureImpl");@

    And the qml file:
    @CaptureImpl {
    implicitWidth: 300
    implicitHeight: 300
    }@

    Is that enough? ^^

    Regards


  • Lifetime Qt Champion

    This:

    @timedUpdate.setInterval(100);
    connect(&timedUpdate, SIGNAL(timeout()), this, SLOT(update()));@

    Why not put it in the constructor ?



  • Of course I could put this in the contructor, but in the end that doesn't make any difference!


  • Lifetime Qt Champion

    It might since it looks like there's some threading strange things going on.



  • Yeah, could habe been...
    I tried both... not changing anything... :/

    I'll try to get another webcam and will have a look if that is the reason!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.