How to open usb camera using openCV and paint it into a custom widget?
-
Hello, I'm quite new on qt. I'm trying to create a tab on my ui that can give the option to count how many usb cameras are connected to computer and list then using OPENCV. After that, I want to select one of then and start streaming a video into a custom widget, using paintEvent. My main difficulties are: how to start and stop a streaming one the buttons are presses. Below i'm posting my code.
mainwindow.h
//includes... namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void on_CheckCamerasButton_clicked(); void on_StartStreamingButton_clicked(); private: Ui::MainWindow *ui; cameraimage camera; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow(){ delete ui; } void MainWindow::on_StartStreamingButton_clicked(){ camera.startStreaming(); } void MainWindow::on_CheckCamerasButton_clicked(){ camera.stopStreaming(); }
camerawindow.h
//includes... class cameraimage : public QWidget { Q_OBJECT public: explicit cameraimage(QWidget *parent = nullptr); private: QPoint mPoint; QTimer *timer; cv::VideoCapture captureVideo; public slots: void paintEvent(QPaintEvent * event); void startStreaming(); void stopStreaming(); }; #endif // CAMERAIMAGE_H
cameraimage.cpp
#include "cameraimage.h" cameraimage::cameraimage(QWidget *parent) : QWidget(parent) { setMouseTracking(true); captureVideo.open(0); if (captureVideo.isOpened() == false){ qDebug() << "Camera can't open"; return; } timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); void cameraimage::startStreaming(){ qDebug() << "Starting Streaming"; timer->start(1); } void cameraimage::stopStreaming(){ captureVideo.release(); qDebug() << "Stop Streaming"; timer->stop(); } void cameraimage::paintEvent(QPaintEvent *){ cv::Mat tmpImage; cv::Mat image; captureVideo.read(tmpImage); if (tmpImage.empty() == true){ qDebug() << "EMPTY!"; return; } cv::cvtColor(tmpImage, image, CV_BGR2RGB); QImage img((const unsigned char*)(image.data), image.cols, image.rows, QImage::Format_RGB888); QPixmap pixmap = QPixmap::fromImage(img); QPainter painter(this); float comprimento = 1.0*width()/pixmap.width(); float altura = 1.0*height()/pixmap.height(); float ratio = 0.; if (comprimento<=altura) ratio = comprimento; else ratio = altura; QSize size = ratio*pixmap.size(); size.setHeight(size.height()-10); QPoint p; p.setX(0 + (width()-size.width())/2); p.setY(5); painter.drawPixmap(QRect(p, size), pixmap.scaled(size, Qt::KeepAspectRatio)); painter.setPen(QPen(Qt::red, 20, Qt::SolidLine)); }
The start and top buttons are on mainwindow, when i click, image do not appear.
Can someone help me?
Thank you for your attention.
Regards :D
-
Hello, I'm quite new on qt. I'm trying to create a tab on my ui that can give the option to count how many usb cameras are connected to computer and list then using OPENCV. After that, I want to select one of then and start streaming a video into a custom widget, using paintEvent. My main difficulties are: how to start and stop a streaming one the buttons are presses. Below i'm posting my code.
mainwindow.h
//includes... namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void on_CheckCamerasButton_clicked(); void on_StartStreamingButton_clicked(); private: Ui::MainWindow *ui; cameraimage camera; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow(){ delete ui; } void MainWindow::on_StartStreamingButton_clicked(){ camera.startStreaming(); } void MainWindow::on_CheckCamerasButton_clicked(){ camera.stopStreaming(); }
camerawindow.h
//includes... class cameraimage : public QWidget { Q_OBJECT public: explicit cameraimage(QWidget *parent = nullptr); private: QPoint mPoint; QTimer *timer; cv::VideoCapture captureVideo; public slots: void paintEvent(QPaintEvent * event); void startStreaming(); void stopStreaming(); }; #endif // CAMERAIMAGE_H
cameraimage.cpp
#include "cameraimage.h" cameraimage::cameraimage(QWidget *parent) : QWidget(parent) { setMouseTracking(true); captureVideo.open(0); if (captureVideo.isOpened() == false){ qDebug() << "Camera can't open"; return; } timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); void cameraimage::startStreaming(){ qDebug() << "Starting Streaming"; timer->start(1); } void cameraimage::stopStreaming(){ captureVideo.release(); qDebug() << "Stop Streaming"; timer->stop(); } void cameraimage::paintEvent(QPaintEvent *){ cv::Mat tmpImage; cv::Mat image; captureVideo.read(tmpImage); if (tmpImage.empty() == true){ qDebug() << "EMPTY!"; return; } cv::cvtColor(tmpImage, image, CV_BGR2RGB); QImage img((const unsigned char*)(image.data), image.cols, image.rows, QImage::Format_RGB888); QPixmap pixmap = QPixmap::fromImage(img); QPainter painter(this); float comprimento = 1.0*width()/pixmap.width(); float altura = 1.0*height()/pixmap.height(); float ratio = 0.; if (comprimento<=altura) ratio = comprimento; else ratio = altura; QSize size = ratio*pixmap.size(); size.setHeight(size.height()-10); QPoint p; p.setX(0 + (width()-size.width())/2); p.setY(5); painter.drawPixmap(QRect(p, size), pixmap.scaled(size, Qt::KeepAspectRatio)); painter.setPen(QPen(Qt::red, 20, Qt::SolidLine)); }
The start and top buttons are on mainwindow, when i click, image do not appear.
Can someone help me?
Thank you for your attention.
Regards :D
@gabrielschubert
Hi, friend,welcome.Can you show some debug info below code?
void cameraimage::paintEvent(QPaintEvent *){ cv::Mat tmpImage; cv::Mat image; captureVideo.read(tmpImage); if (tmpImage.empty() == true){ qDebug() << "EMPTY!"; return; } cv::cvtColor(tmpImage, image, CV_BGR2RGB); QImage img((const unsigned char*)(image.data), image.cols, image.rows, QImage::Format_RGB888); #if 1 qDebug() << "img Size: "<< img.size(); #endif QPixmap pixmap = QPixmap::fromImage(img); QPainter painter(this); float comprimento = 1.0*width()/pixmap.width(); float altura = 1.0*height()/pixmap.height(); float ratio = 0.; if (comprimento<=altura) ratio = comprimento; else ratio = altura; QSize size = ratio*pixmap.size(); size.setHeight(size.height()-10); QPoint p; p.setX(0 + (width()-size.width())/2); p.setY(5); #if 1 qDebug() << "p: " << p; qDebug() << "size:" << size; #endif painter.drawPixmap(QRect(p, size), pixmap.scaled(size, Qt::KeepAspectRatio)); painter.setPen(QPen(Qt::red, 20, Qt::SolidLine));
-
Hello @joeQ , thank you for your answer.
When you say debug info you're saying the app output? If yes, here it is:
Starting Streaming Starting Streaming VIDEOIO ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV Unable to stop the stream: Device or resource busy Camera can't open EMPTY! EMPTY!
When I pass the mouse on the cameraimage widget, it keeps printing "EMPTY!", cause of the "mouseTracking(true)".
If it is not debug info, could you tell me how can I get this?
Thank you again :)
-
Hello @joeQ , thank you for your answer.
When you say debug info you're saying the app output? If yes, here it is:
Starting Streaming Starting Streaming VIDEOIO ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV Unable to stop the stream: Device or resource busy Camera can't open EMPTY! EMPTY!
When I pass the mouse on the cameraimage widget, it keeps printing "EMPTY!", cause of the "mouseTracking(true)".
If it is not debug info, could you tell me how can I get this?
Thank you again :)
-
@joeQ, now camera is opened. I made a mistake and was opening camera twice. But still not starting steaming when I click on start streaming button, that is on mainwindow. Below the code and output.
#include "cameraimage.h" cameraimage::cameraimage(QWidget *parent) : QWidget(parent) { setMouseTracking(true); } void cameraimage::startStreaming(){ qDebug() << "Starting Streaming"; captureVideo.open(-1); if (captureVideo.isOpened() == false){ qDebug() << "Camera can't open"; return; } timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer->start(1); } void cameraimage::stopStreaming(){ captureVideo.release(); timer->stop(); } void cameraimage::paintEvent(QPaintEvent *){ cv::Mat tmpImage; cv::Mat image; captureVideo.read(tmpImage); if (tmpImage.empty() == true){ qDebug() << "EMPTY!"; return; } cv::cvtColor(tmpImage, image, CV_BGR2RGB); QImage img((const unsigned char*)(image.data), image.cols, image.rows, QImage::Format_RGB888); #if 1 qDebug() << "img Size: "<< img.size(); #endif QPixmap pixmap = QPixmap::fromImage(img); QPainter painter(this); float comprimento = 1.0*width()/pixmap.width(); float altura = 1.0*height()/pixmap.height(); float ratio = 0.; if (comprimento<=altura) ratio = comprimento; else ratio = altura; QSize size = ratio*pixmap.size(); size.setHeight(size.height()-10); QPoint p; p.setX(0 + (width()-size.width())/2); p.setY(5); #if 1 qDebug() << "p: " << p; qDebug() << "size:" << size; #endif painter.drawPixmap(QRect(p, size), pixmap.scaled(size, Qt::KeepAspectRatio)); }
output after button clicked:
Starting Streaming... EMPTY! EMPTY! EMPTY! ...
-
Problem solved, changed line
camera.startStreaming()
on mainwindow.cpp to
ui->cameraWidget->startString()
Now it's running.
Thank you. :)