2017-02-07 9 views
0

По какой-то причине мне нужно обернуть opencv VideoCapture в классе, который будет использоваться в Qt Quick.Как правильно рисовать последовательное изображение в QQuickPaintedItem

Существует два класса: один - камера, другой - CameraView. CameraView наследуется от QQuickPaintedItem.

Класс камеры будет получать изображение периодически. Это достигается с помощью QObject :: startTimer (int interval). (например, если fps веб-камеры составляет 30, интервал таймера составляет 1000/30 - 8, 8 - отклонение времени). После того, как камера получила изображение, она уведомляет CameraView о перерисовке, вызывая CameraView :: Update().

И в CameraView :: paint (QPainter *) CameraView получит копию изображения из класса Camera и рисует это изображение по вызову QPainter :: drawImage (...).

Я получил некоторые проблемы в процессе кодирования:

  1. Я пытаюсь заменить время события с QThread, чтобы получить изображение с камеры периодически. Когда я вызываю CameraView :: Update() в QThread, CameraView не перерисовывает. В чем проблема?

  2. В моем ноутбуке, когда я рисую изображение CameraView в полноэкранном режиме, я обнаружил, что одна программа python замедляется. Является ли другой способ рисовать изображение с более низкой стоимостью и эффективностью?

ответ

1

Как эффективно обновлять QML элемент на основе QQuickPaintedItem C++ класса? Я делегировал некоторые препроцессоры для выделенного потока вместо таймера в потоке пользовательского интерфейса, и он больше не обновляет изображение в QML-интерфейсе.

Обязательно инициировать обновление пользовательского интерфейса из потока пользовательского интерфейса в Qt, включая QML. Сделайте так, чтобы CameraView открывал открытый слот updateImage.

class CameraView : public QQuickPaintedItem 
{ 
    Q_OBJECT 
    Q_DISABLE_COPY(CameraView) 

public: 
    CameraView(QQuickItem* parent = nullptr); 

public slots: 
    void updateImage(const QImage&); 

protected: 
    QImage m_image; 
}; 

CameraView должны осуществлять updateImage и paint так:

void CameraView::updateImage(const QImage& image) 
{ 
    m_imageThumb = image; // does shallow copy of image data 
    update();    // triggers actual update 
} 

void CameraView::paint(QPainter* painter) 
{ 
    painter->drawImage(this->boundingRect(), m_image); 
} 

Класс OpenCvOnWorkerThread должен начать свой рабочий поток и подвергать signalUiUpdate:

OpenCvOnWorkerThread::OpenCvOnWorkerThread() 
{ 
    this->moveToThread(&m_workerThread); 
    // the below will allow communication between threads 
    connect(this, SIGNAL(signalUiUpdate(QImage)), m_cameraView, SLOT(updateImage(QImage))); 

    m_workerThread.start(); 
} 

void OpenCvOnWorkerThread::cvRead() 
{ 
    QImage image; 

    // OpenCV details available in your code 
    // cv::read 
    // make QImage from frame 


    // deliver QImage to another thread 
    emit signalUiUpdate(image); 
} 

UPDATE: В моем собственном коде для аналогичный QML-вывод из потока «камеры». Я также занимаюсь обработкой задержка потока пользовательского интерфейса, когда он не может обработать видеофрагменты, чтобы отправитель сигнала знал, когда не отправлять видеофрагменты. Но это стоит другого вопроса. Или весь этот пример может быть переопределен без сигнала и слота, но с переменной условия.

+1

спасибо. Я этого добился. И одна важная вещь - установить renderTarget как QQuickPaintedItem :: FramebufferObject в CameraView, это очень важно для моего ноутбука. –

+0

Помог ли мой ответ или нет? – AlexanderVX

+0

Конечно! спасибо –

 Смежные вопросы

  • Нет связанных вопросов^_^