Tak jak w temacie pisze program korzystając z OpenCV oraz Qt C++. W tym momencie próbuje uzyskać większą płynność wyświetlanego obrazu z kamery internetowej Logitech C920. Kamera pozwala na wyświetlanie obrazu Full HD z 30FPS co potwierdza komenda v4l2-ctl -d /dev/video0 --list-formats-ext. Jednak w mojej sytuacji bardzo często występuje sytuacja że pobranie ramki zajmuje więcej niż 33ms (1000ms/30FPS=33ms), inna sprawa to znaczne obciążenie procesora (rdzeni).
Plik main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Plik mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&processor, SIGNAL(inDisplay(QPixmap)), ui->inVideo, SLOT(setPixmap(QPixmap)));
processor.start(QThread::HighestPriority);
}
MainWindow::~MainWindow()
{
processor.requestInterruption();
processor.wait();
delete ui;
}
Plik videoprocessorthread.cpp
#include "videoprocessorthread.h"
#include <iostream>
#include <string>
VideoProcessorThread::VideoProcessorThread()
{
}
void VideoProcessorThread::run()
{
using namespace cv;
VideoCapture camera(0 + CAP_ANY);
camera.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
camera.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
camera.set(CV_CAP_PROP_FPS,30);
// camera.set(CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
// camera.set(CAP_PROP_FOURCC, CV_FOURCC('H', '2', '6', '4'));
Mat inFrame;
while (camera.isOpened() && !isInterruptionRequested()) {
myTimer1.start();
playFrameFPS = camera.get(CV_CAP_PROP_FPS);
// camera >> inFrame;
camera.read(inFrame);
if(inFrame.empty())
continue;
emit inDisplay(QPixmap::fromImage(QImage(inFrame.data, inFrame.cols, inFrame.rows, inFrame.step, QImage::Format_RGB888).rgbSwapped()));
timeReadFrame = myTimer1.elapsed();
timeSleepThread = (static_cast<int>(1000.0/playFrameFPS) - timeReadFrame);
qDebug() << "FPS:" << playFrameFPS << "|| t odczyt:" << static_cast<int>(1000.0/playFrameFPS) << "ms" << "|| t odczytu z kamery:" << timeReadFrame << "ms" << timeSleepThread;
if (timeSleepThread>0) {
qDebug() << "odpoczywam :P";
this->msleep(timeSleepThread);
}
}
}
Ważne informacje:
- program piszę po linuxem zatem obsługa kamery jest realizowana poprzez v4l2
- główne opóźnienie bo wynoszące nawet 90% przewidzianego czasu na odczyt zajmuje camera.read(inFrame). Stwierdzone po wykomentowaniu wszystkiego co zbędne łącznie z samym wyświetlaniem obrazu.
- zwiększenie czasu odczytu występuje wówczas gdy obraz jest niedoświetlony
Moje pytania:
- jak zmusić kamerę aby był możliwy odczyt z wykorzystaniem MJPG lub H264 bo poleceni camera.set(CAP_PROP_FOURCC, CV_FOURCC('H', '2', '6', '4')) nic nie zmienia
- czy jest możliwość uzyskania płynnych 30FPS z Full HD na USB2.0 bez znacznego obciążania procesora
- a jaki wam się udało uzyskać wskaźnik FPS przy Full HD
- może ma ktoś jakiś pomysł jak poprawić kod aby przetwarzanie było bardziej płynne oraz mnie obciążające CPU