Introdução
QCamera é uma classe do Qt5 que prove para o desenvolvedor toda estrutura necessária para listar dispositivos webcams e cada câmera conectada ao PC, selecionar o dispositivo desejado e executar tarefas como capturar imagem, reproduzir ou até mesmo gravar.
Configuração do sistema
Para sucesso na execução deste artigo, utilizarei a distribuição Linux Mint 17 Qiana 64 bits, mas não há problemas em realizar o procedimento em um Ubuntu ou outra distribuição suportada pelo Qt5. A seguir são listados os seus pré-requisitos:
- Qt5.4 ou Qt5.5 instalado com o Qt Creator;
- QCamera instalado;
- Distribuição Linux suportada pelo Qt5.
O básico do QCamera
Para utilizar o QCamera, que não é um Widget para arrastar e soltar na aplicação, devemos incluir algumas dependências em nosso projeto. Então, vamos criar nosso projeto.
Clique em File > New File or Project…, selecione Application, em seguida Qt Widgets Application e prossiga. Na janela seguinte dê um nome para o projeto (estarei usando o nome myCam) e avance, deixe selecionado os Kits default e avance. Em Base Classe selecione QWidget, avance e Finish.
Primeira alteração que devemos realizar é adicionar multimedia ao QT do myCam.pro.
QT += core gui multimedia
Em seguida no widget.cpp adicionar o header QCamera:
#include "widget.h" #include "ui_widget.h" #include <QCameraInfo>
Pronto, as dependências eram essas, agora vamos a uma primeira aplicação, onde irei listar as câmeras e imprimir no output do console.
O seu widget.h deve ficar como abaixo:
#ifndef WIDGET_H
#define WIDGET_H
#include <Qwidget>
#include <QCamera>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
bool checkCameras(void);
};
#endif // WIDGET_H
E agora o widget.cpp:
#include "widget.h"
#include "ui_widget.h"
#include <QCameraInfo>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
if(checkCameras()){
//codigo
}
}
Widget::~Widget()
{
delete ui;
}
bool Widget::checkCameras()
{
int camCount = QCameraInfo::availableCameras().count();
if ( camCount > 0) {
qDebug() << "Cameras encontradas: " << camCount << endl;
return true;
}
else {
qDebug() << "Nenhuma camera foi detectada!" << endl;
return false;
}
}
Pressionando Ctrl+b construímos a aplicação e Ctrl+r a executamos. A saída da aplicação, no meu caso sem câmera, conectando 1 câmera e depois 2 câmeras:
Starting ../Projetos/build-myCam-Desktop_Qt_5_5_0_GCC_64bit-Debug/myCam... Nenhuma camera foi detectada! Starting ../Projetos/build-myCam-Desktop_Qt_5_5_0_GCC_64bit-Debug/myCam... Cameras encontradas: 1 Starting ../Projetos/build-myCam-Desktop_Qt_5_5_0_GCC_64bit-Debug/myCam... Cameras encontradas: 2
Para realizar estes testes em meu notebook, primeiro eu removi o módulo uvcvideo:
$ sudo rmmod uvcvideo
Executei a aplicação e nenhuma câmera foi detectada. Em seguida, subi o módulo novamente:
$ sudo modprobe uvcvideo
Executei a aplicação e uma câmera foi detectada. Na sequência pluguei uma webcam na porta USB e executei novamente a aplicação. Ela detectou 2 dispositivos.
Quem fez todo o trabalho foi o QCameraInfo::availableCameras() e usando a função count() conseguimos saber quantos dispositivos foram detectados. Validar essa verificação antes de iniciar a aplicação é importante.
Obtendo informações das câmeras
Acima conseguimos listar as câmeras presentes no notebook no qual estamos executando a aplicação, e se quiséssemos obter mais detalhes sobre cada dispositivo, como o nome do dispositivo e descrição.
Vamos editar o widget.cpp da seguinte maneira:
#include "widget.h"
#include "ui_widget.h"
#include <QCameraInfo>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
if(checkCameras()){
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
foreach (const QCameraInfo &cameraInfo, cameras) {
qDebug() << "Device Name : " << cameraInfo.deviceName() << endl;
qDebug() << "Description : " << cameraInfo.description() << endl;
qDebug() << "Position : " << cameraInfo.position() << endl;
qDebug() << "Cam Default : " << cameraInfo.defaultCamera() << endl;
qDebug() << "Orientation : " << cameraInfo.orientation() << endl;
}
}
}
Widget::~Widget()
{
delete ui;
}
/**
* @brief Widget::checkCameras
* @return
*/
bool Widget::checkCameras()
{
int camCount = QCameraInfo::availableCameras().count();
if ( camCount > 0) {
qDebug() << "Cameras encontradas: " << camCount << endl;
return true;
}
else {
qDebug() << "Nenhuma camera foi detectada!" << endl;
return false;
}
}
Usei a mesma aplicação, mas caso sejam encontradas câmeras, irei montar uma QList e imprimir na tela varias informações, que pode ser vista na lista 13 a 19.
Starting ../Projetos/build-myCam-Desktop_Qt_5_5_0_GCC_64bit-Debug/myCam... Cameras encontradas: 2 Device Name : "/dev/video0" Description : "Lenovo EasyCamera" Position : QCamera::UnspecifiedPosition Cam Default : "QCameraInfo(deviceName=/dev/video0, position=UnspecifiedPosition, orientation=0)" Orientation : 0 Device Name : "/dev/video1" Description : "USB2.0 Camera" Position : QCamera::UnspecifiedPosition Cam Default : "QCameraInfo(deviceName=/dev/video0, position=UnspecifiedPosition, orientation=0)" Orientation : 0
Uma análise rápida que podemos fazer é que a webcam do meu notebook é o device /dev/video0 e a webcam USB é /dev/video1. A câmera default é a do meu notebook /dev/video0, tenho a description de cada uma, que facilita saber quem é quem. Position não tem definido, mas é algo muito útil, pois podemos ter QCamera::BackFace e QCamera::FrontFace, uma forma de dizer se a câmera esta atrás da tela ou na frente, igual nos celulares. Além do parâmetro orientation.
Existem 4 possíveis maneiras de selecionar uma câmera com o QCamera():
- QCamera() : Sendo a default selecionada;
- QCamera(const QbyteArray &devicename) : Fornecendo um device name da câmera;
- QCamera(const QcameraInfo &cameraInfo) : Fornecendo o camerainfo da câmera;
- QCamera(QCamera::Position position) : Fornecendo QCamera::FrontFace ou QCamera::BackFace.
Construindo aplicação básica com QCamera
Em poucas linhas vamos desenvolver uma aplicação para abrir nossa câmera padrão e mostrar no Widget de nossa aplicação.
Vamos criar o projeto myCamDefault em File > New File or Project… > Application > Qt Widgets Application > name: myCamDefault > Base Class selecione Qwidget > Finish.
Caso tenha dúvida no procedimento para criar uma aplicação Widget, acesse o artigo Qt5 Console e Widgets.
Editando o arquivo myCamDefault.pro:
QT += core gui multimedia multimediawidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = myCamDefault
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
No .pro adicionamos multimedia e multimediawidgets, que são dependências para QCamera, e agora vamos ao widget.cpp:
#include "widget.h"
#include <QApplication>
#include <QCamera>
#include <QCameraViewfinder>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
/* Construtor Camera com QObject parent e/ou especificação do
* device Camera
*/
QCamera cam(&w);
/* Iniciando o objeto da classe QCameraViewfinder para a visualização
* do nosso device Camera
*/
QCameraViewfinder viewf(&w);
/*
* Setando nosso visualizador para o tamanho Largura x Altura
*/
viewf.setFixedWidth(w.geometry().width());
viewf.setFixedHeight(w.geometry().height());
/*
* Passando para nosso objeto cam o visualizador que
* criamos e setamos as dimensões
*/
cam.setViewfinder(&viewf);
/* Iniciando visualização do nosso device Camera */
cam.start();
/* Exibindo nosso Widget */
w.show();
return a.exec();
}
Tudo começa na linha 15 onde crio o objeto QCamera cam e passo o w, que é o widget atual da minha aplicação. Na linha 20 crio um objeto QCameraViewFinder viewf, que é nosso visualizador, e passo o w novamente. Na linha 25 e 26 é uma macete para que o QCameraViewFinder ocupe o Widget inteiro, ou melhor, seja do tamanho dele. Na linha 32 passo para meu objeto cam quem será meu visualizado, no caso, viewf e logo em seguida inicio a câmera.
Construindo e executando nossa aplicação (Ctrl+b e Ctrl+r), temos a aplicação com a reprodução da câmera, conforme a Figura 1.
Selecionando uma câmera e visualizando
Agora vamos criar outro projeto, onde podemos listar as câmeras disponíveis, escolher uma e reproduzir na aplicação.
Vamos criar o projeto myCamSelect em File > New File or Project… > Application > Qt Widgets Application > name: myCamSelect > Base Class selecione Qwidget > Finish.
OBS: Deve-se adicionar multimediawidgets ao QT do myCamSelect.pro, para trabalhar com o QCameraViewFinder como Widget.
QT += core gui multimedia multimediawidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = myCamSelect
TEMPLATE - app
SOURCES += main.cpp \
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
Primeiramente vamos “desenhar” nossa tela clicando no widget.ui, que possuirá:
| Componente | Nome |
| QpushButton | btnOpenCam |
| QpushButton | btnCloseCam |
| QpushButton | btnCaptureImage |
| QpushButton | btnClose |
| QComboBox | cbListCam |
| QStackedWidget | stackedWidget |
| QWidget | viewfinderPage |
| QCameraViewFinder | camViewFinder |
Caso tenha alguma dificuldade em posicionar ou configurar a interface gráfica (.ui), o projeto completo será disponibilizado no final do artigo. Segue na Figura 2 como ficou a tela.
Agora segue o código com comentários em cada função ou uma importante etapa da aplicação, começando pelo widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QList>
#include <QCameraInfo>
#include <QCameraViewfinder>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void SetCbListCam(QList<QCameraInfo> &cams);
private slots:
void on_btnOpenCam_clicked();
void on_btnCloseCam_clicked();
void on_btnCaptureImage_clicked();
void on_btnClose_clicked();
private:
Ui::Widget *ui;
QCameraViewfinder *viewFinder;
QCamera *camera;
bool checkCameras(void);
void OpenCam(void);
protected:
QList<QCameraInfo> devCameras;
};
#endif // WIDGET_H
Editando o widget.cpp:
#include "widget.h"
#include "ui_widget.h"
#include <QCameraInfo>
#include <QDebug>
#include <QMessageBox>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QMessageBox msgApp;
/* Check if find device cameras here */
if(checkCameras()){
devCameras = QCameraInfo::availableCameras();
foreach (const QCameraInfo &cameraInfo, devCameras) {
qDebug() << "Device Name : " << cameraInfo.deviceName() << endl;
qDebug() << "Description : " << cameraInfo.description() << endl;
qDebug() << "Position : " << cameraInfo.position() << endl;
qDebug() << "Cam Default : " << cameraInfo.defaultCamera() << endl;
qDebug() << "Orientation : " << cameraInfo.orientation() << endl;
}
}
/* Set in ComboxBox list of device cameras */
this->SetCbListCam(devCameras);
/* If find camera OK, enable button Conectar
* else Message Box "Not Found Device Camera"
*/
if(ui->cbListCam->count() < 1) {
msgApp.setWindowTitle("Informação");
msgApp.setInformativeText("Nenhuma camera foi encontrada...");
msgApp.setIcon(QMessageBox::Information);
msgApp.exec();
}
else {
ui->btnOpenCam->setEnabled(true);
}
}
/**
* @brief Widget::~Widget
* Object Destructor Class Widget
*/
Widget::~Widget()
{
delete ui;
}
/**
* @brief Widget::SetCbListCam
* @param cams
* Function to load device cameras in ComboBox
*/
void Widget::SetCbListCam(QList<QCameraInfo> &cams)
{
QStringList AllCams;
foreach (const QCameraInfo &cam, cams) {
/* Set Description in ComboBox */
//AllCams.append(cam.description());
/* Set DeviceName in ComboBox */
AllCams.append(cam.deviceName());
}
ui->cbListCam->addItems(AllCams);
}
/**
* @brief Widget::on_btnOpenCam_clicked
*/
void Widget::on_btnOpenCam_clicked()
{
QByteArray myDeviceCam;
/* Enable Button "Capturar Image" and "Desconectar" */
ui->btnCaptureImage->setEnabled(true);
ui->btnCloseCam->setEnabled(true);
/* Trick: Convert to QString to QByteArray using .toUtf8() */
myDeviceCam = ui->cbListCam->itemText(ui->cbListCam->currentIndex()).toUtf8();
/* Set device select in ComboxBox */
camera = new QCamera(myDeviceCam);
/*
* Create ViewFinder "Visualizador" to device camera
*/
viewFinder = new QCameraViewfinder(ui->camViewfinder);
/* Call function OpenCam() */
this->OpenCam();
}
/**
* @brief Widget::checkCameras
* @return True or False if find device cameras
*/
bool Widget::checkCameras()
{
int camCount = QCameraInfo::availableCameras().count();
if ( camCount > 0) {
qDebug() << "Cameras encontradas: " << camCount << endl;
return true;
}
else {
qDebug() << "Nenhuma camera foi detectada!" << endl;
return false;
}
}
/**
* @brief Widget::OpenCam
*/
void Widget::OpenCam(void)
{
/*
* Set resize screen width x heigth with size my ViewFinder
*/
viewFinder->setFixedWidth(ui->camViewfinder->width());
viewFinder->setFixedHeight(ui->camViewfinder->height());
/*
* Set my ViewFinder Widget in ViewFinder object QCamera
*/
camera->setViewfinder(viewFinder);
/*
* Show ViewFinder
*/
viewFinder->show();
/*
* Start capture video
*/
camera->start();
}
/**
* @brief Widget::on_btnCloseCam_clicked
*/
void Widget::on_btnCloseCam_clicked()
{
/*
* Stop capture video
*/
camera->stop();
/* Destruct objects created in OpenCam */
delete camera;
delete viewFinder;
/*
* Enable button "Conectar"
* Disable buttons "Descontar" and "Captura Image"
*/
ui->btnOpenCam->setEnabled(true);
ui->btnCloseCam->setEnabled(false);
ui->btnCaptureImage->setEnabled(false);
}
/**
* @brief Widget::on_btnCaptureImage_clicked
*/
void Widget::on_btnCaptureImage_clicked()
{
/* Implement Code Here! */
/* Future Implementation */
}
void Widget::on_btnClose_clicked()
{
ui->btnCloseCam->click();
close();
}
Em main.cpp não houve alterações.
Para entender o que foi feito, criamos dois ponteiros, um para QCamera que será o objeto cam e um para QCameraViewFinder que será o objeto viewFinder. No widget.cpp setamos o cam com o device selecionado no QComboBox e configuramos nossa viewFinder com o QCameraViewFinder no QStackedWidget, e os botões possuem ações de iniciar e parar a câmera. O botão Captura Image é um aperitivo para o próximo artigo.
Compilando e executando nossa aplicação:
Como não tenho mais um Tux, o Sidney (Figura 3) auxiliou na captura da webcam externa 🙂 e eu na webcam onboard.
As aplicações aqui apresentadas têm por fim mostrar as possibilidades da ferramenta em uma abordagem didática. A partir desta base pode-se customizar e explorar os recursos de acordo com a necessidade da aplicação ou projeto.
[wpdm_asset id=’12’]Referências







Parabéns, companheiro! Este tutorial me foi verdadeiramente útil.
O arquivo de descarga nao esta disponivel, acho que o link ficou no html errado
O arquivo deste tuto nao esta disponivel?