OpenCV (Open Source Computer Vision) es un excelente conjunto de herramientas para la visión artificial. También ofrece una manera fácil de capturar secuencia de vídeo desde dispositivos externos como una cámara. En este tutorial se introducirá OpenCV y mostrara un método para la captura de vídeo a partir de una cámara web o de un archivo de vídeo desplegando un texto en tiempo real sobre el vídeo, esto en conjunto con QT.

Para la instalación y configuración de OpenCV 3.1 y QT den Debian 8 Linux les recomiendo la guía que desarrolle hace un tiempo: OpenCV 3.1 con CUDA 7.5 sobre QT 5 en Debían 8 (pueden omitir la instalación de CUDA si su GPU no es soportada)

Descripción del proyecto

El proyecto consiste en poder visualizar un texto obtenido desde un "QlineEdir" o "input text" en un vídeo pre-grabado u obtenido desde la WebCam del Notebook o PC en tiempo real.

Diagrama de flujo simplificado
Diagrama de flujo del proyecto
Creación del proyecto

Seleccionamos crear un nuevo proyecto.

Creación de un nuevo proyecto QT5

Configuramos el archivo .pro agregando las librerías necesarias para el correcto funcionamiento de OpenCV.

INCLUDEPATH += /usr/local/include/opencv-3.1.0
LIBS += `pkg-config opencv --libs --cflags`

En mi caso el archivo en cuestión TextoEnVideo-OpenCV.pro queda de esta forma:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = TextoEnVideo-OpenCV
TEMPLATE = app

INCLUDEPATH += /usr/local/include/opencv-3.1.0
LIBS += `pkg-config opencv --libs --cflags`

SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

Headers

Agregamos los header de OpenCV y QFileDialog (para poder obtener el seleccionador de archivos) a nuestro proyecto en el archivo "mainwindow.h".


#include <QFileDialog>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
Interfaz de usuario (UI)

El diseño siempre es a gusto del usuario, en todo caso lo básico que debe tener la aplicación son dos "botones" con uno configurado como checkable para el "play", "parar" y otro para seleccionar el archivo, ademas de los "Radio Buttons" para identificar la entrada de vídeo.
Dejare el código fuente completo por si presentan dudas.

QT OpenCV Video Texto
Código de las funciones principales

Se omitieron los namespaces para fines académicos, ya que de esta forma el lector sabrá a que clase corresponde cada método.

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

/**
 * Metodo para obtener la direccion del video
 * @brief MainWindow::SeleccionarVideo
 */
void MainWindow::SeleccionarVideo()
{
    // Declara la variable con la ruta del archivo
    QString archivo = QFileDialog::getOpenFileName(this,
        tr("Abrir Video"),
        "",
        tr("Videos (*.avi *.mp4 *.mov)"));
    //Agrega la ruta del archivo
    ui->labelVideo->setText(archivo);
    ui->radioVideo->setChecked(true);
}

/**
 * Metodo para procesar el video frame a frame si ckecked==true
 * @brief MainWindow::ProcesarVideo
 * @param checked
 *
 */
void MainWindow::ProcesarVideo(bool checked)
{

    cv::destroyAllWindows(); // Para cerrar todas las ventanas

    cv::Mat frame; // Frame como array multidimencional

    if (!checked) { // Si !checked detiene el video si no lo procesa
        ui->play->setText("Iniciar video");
        cap.release();
    }
    else {
        ui->play->setText("Parar video");

        if (ui->radioVideo->isChecked()) { // si el "radio button" esta seleccionado ejecuta el video si no la webcam
            cap.open(ui->labelVideo->text().toStdString().c_str());
        }
        else {
            cap.open(0);
        }
    }

    while (checked) // bucle hasta que se precione "parar video"
    {
        cap >> frame; // obtiene un nuevo frame del video o camara
        if (frame.empty())
            break; // detiene el bucle si elframe esta vacio

        //insertamos el texto en el video
        cv::putText(frame, //frame o imagen
            ui->lineTexto->text().toStdString(), //texto en formato estandar
            cv::Point(20, 60), // ubicacion del texto
            cv::FONT_HERSHEY_TRIPLEX, // fuente del texto
            2, // tamano del texto
            cv::Scalar(255, 255, 255), // color del texto
            4); // ancho del texto

        cv::namedWindow("Reproductor", cv::WINDOW_KEEPRATIO); // creamos una ventana la cual permita redimencionar
        cv::imshow("Reproductor", frame); // se muestran los frames

        char key = (char)cv::waitKey(20); //espera 20ms por la tecla ESC
        if (key == 27)
            break; //detiene el bucle
    }
}

void MainWindow::on_toolButton_clicked()
{
    SeleccionarVideo();
}

void MainWindow::on_actionAbrir_Video_triggered()
{
    SeleccionarVideo();
}

void MainWindow::on_play_toggled(bool checked)
{
    ProcesarVideo(checked);
}

Cada método debe estar previamente definido en el/los headers, para mayor detalle puede descargar el código fuente disponible aquí: