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...
-
Hi,
Can you show the code you used for your qml element ?
-
Yeah, of course!
@class SHARED_EXPORT CaptureItem : public QQuickPaintedItem {
Q_OBJECTcv::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
-
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!
-
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!