OpenCV 3.1 (C++) sobre Qt 5 en Linux – FPS en video
En proyectos anteriores hemos insertado texto en un video (OpenCV 3.1 sobre Qt 5 en Linux – Texto en video). En este caso, insertaremos en el video la tasa de fotogramas que es capaz de procesar OpenCV durante una acción.
Los fotogramas por segundo, también conocidos como tasa de refresco, fps o frames per second, representan la velocidad (tasa) a la cual un dispositivo muestra imágenes llamadas cuadros o fotogramas. Esta tasa se expresa en cuadros por segundo o por la sigla en inglés FPS (frames per second).
Es muy importante obtener este dato para conocer el rendimiento o la velocidad de procesamiento de cada imagen.
Descripción del proyecto
El proyecto consiste en desplegar la tasa de fotogramas que OpenCV es capaz de procesar.
Este tutorial se basa en el previamente desarrollado OpenCV 3.1 sobre Qt 5 en Linux – Texto en video, por lo que la mayor parte del código se encuentra explicado allí.
Consideraciones clave
cv::getTickCount(); La función getTickCount devuelve el número de ciclos de reloj transcurridos desde que se inició el proceso; en nuestro caso, desde el inicio de la captura.
cv::getTickFrequency(); La función getTickFrequency devuelve la frecuencia del reloj. Al obtener estos datos, es posible calcular los fotogramas por segundo aplicando la siguiente fórmula:
fps = frecuencia / (tiempo_final - tiempo_inicial)
Código de los métodos principales
Se omitieron los namespaces con fines académicos, ya que de esta forma el lector puede identificar a qué 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;
}
/**
* Método para obtener la dirección 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);
}
/**
* Método para procesar el video frame a frame si checked == true
* @brief MainWindow::ProcesarVideo
* @param checked
*/
void MainWindow::ProcesarVideo(bool checked)
{
unsigned long Atime;
int fps;
cv::destroyAllWindows(); // Cierra todas las ventanas
cv::Mat frame; // Frame como arreglo multidimensional
if (!checked) { // Si !checked, detiene el video
ui->play->setText("Iniciar video");
cap.release();
}
else {
ui->play->setText("Parar video");
if (ui->radioVideo->isChecked()) { // Si el radio button está seleccionado, ejecuta el video
cap.open(ui->labelVideo->text().toStdString().c_str());
}
else {
cap.open(0); // Webcam
}
}
while (checked) // Bucle hasta que se presione "Parar video"
{
Atime = cv::getTickCount();
cap >> frame; // Obtiene un nuevo frame del video o cámara
if (frame.empty())
break; // Detiene el bucle si el frame está vacío
cv::namedWindow("Reproductor", cv::WINDOW_KEEPRATIO); // Ventana redimensionable
fps = cv::getTickFrequency() / (cv::getTickCount() - Atime);
// Insertamos el texto en el video
cv::putText(frame,
cv::format("%d fps", fps), // Texto
cv::Point(20, 60), // Ubicación
cv::FONT_HERSHEY_TRIPLEX, // Fuente
2, // Tamaño
cv::Scalar(255, 255, 255), // Color
4); // Grosor
cv::imshow("Reproductor", frame); // Muestra los frames
char key = (char)cv::waitKey(10); // Espera 10 ms
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);
}
Para mayor detalle, puede descargar el código fuente desde aquí: