подружить qml и opencv
Доброго времени суток.
Пытаюсь сделать отображение с веб-камеры в графическом интерфейсе написанном на qml.
Код программы:
#системные библиотеки import cv2 import numpy as np import sys import threading #PyQt библиотеки from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtQml import * from PyQt5.QtQuick import * class MyImageProvider(QQuickImageProvider): def __init__(self): super(MyImageProvider, self).__init__(QQuickImageProvider.Image) def requestImage(self, p_str, size): cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() #image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) height, width, channel = frame.shape #step = channel * width img = QImage(frame, width, height, QImage.Format_RGB888) #img.fill(Qt.green) return img, img.size() cv2.waitKey(1) if __name__ == '__main__': app = QGuiApplication(sys.argv) MyImageProvider() engine = QQmlApplicationEngine() engine.addImageProvider("myprovider", MyImageProvider()) engine.load(QUrl.fromLocalFile("tst.qml")) if len(engine.rootObjects()) == -1: sys.exit(-1) sys.exit(app.exec_())
Вот код формы:
import QtQuick 2.12 import QtQuick.Window 2.12 Window{ visible: true width: 800 height: 600 title: ("QML OPENCV") color: "green" Image { //anchors.fill : parent source: "image://myprovider/test.png" } }
Читал статью про
слоты и сигналы в python
, но пока не могу сообразить, как это всё складывается воедино.
Представленный код отображает окно с веб-камерой и окно qml интерфейста.
Есть на C++ образец... Я в нём не силён, подсобите перевести на python3. :)
Утечка памяти (OpenCV + QML)
Нашёл пример с изображением:
QQuickImageProvider PyQt5
С помощью этого примера почти получилось добиться желаемого результата. Получается, что отображается только последний снятый кадр веб-камерой, а не поток. Есть идеи, как сделать поток из кадров в форму qml?
Спасибо!
Вот такой набросок пока что получился.
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.Вам это нравится? Поделитесь в социальных сетях!
Комментарии
Пожалуйста, авторизуйтесь или зарегистрируйтесь
- Akiv Doros
- 11 ноября 2024 г. 20:58
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:50баллов,
- Очки рейтинга-4
- molni99
- 26 октября 2024 г. 7:37
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:80баллов,
- Очки рейтинга4
- molni99
- 26 октября 2024 г. 7:29
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:20баллов,
- Очки рейтинга-10
Добрый день.
Да... OpenCV, конечно, интересная тема. Но вот я от неё далёк.
QQuickImageProvider использутеся для предоставления изображений, но точно не для потока этих самых изображений. В каком-то смысле все те примеры выглядят как костыли, поскольку QQuickImageProvider используется не по своему прямому назначению. Но тем не менее это должно работать.
Обратите своё внимание на то, что в примере с утечкой памяти имеется сигнал, который сообщает об изменении изображения на каждый новый кадр. Вам нужно сделать тоже самое. Вам нуэно использовать сигналы и слоты для этого. Не помню, вы уже кажется смотрели ту статью по сигналам и слотам PyQt5 - Урок 007. Работаем с QML QtQuick (Сигналы и слоты)
Добрый.
Да, я пытался связаться через сигналы и слоты, но у меня не выходит перевести программу с плюсов на питон. Если не затруднит помочь в переводе, то есть вероятность, что получится написать конечный результат. :)
Думаю, что в QQuickImageProvider следует добавить сигнал, что-то вроде такого
А потом как минимум подключить к этому сигналу обработчик в QML и посмотреть, сыпется ли что-то нибудь в консоль QML
Тогда уже можно будет пытаться сообразить что-нибудь дальше
А через "console.log" Вы куда выводите сообщения? В PyCharm? Я работаю в основном в стандартной IDLE Python. Такое не срабатывает в стандартной IDLE. PyCharm у меня стоит.
вообще - это тоже должно сыпаться в консоль и без разницы, какую IDE использовать. К IDE это не должно иметь никакого отношения. Если вывода нет, то скорее всего не работает.
А да, ещё этот сигнал нужно вызывать
И кстати сам запрос изображения у вас как-то странно написан
Вы сейчас разбираете некий костыль, посоветовали с сигналами и слотами поработать, вот и хочу с ними разобраться, если так имеет место быть более правильное решение.) Я могу по-новому написать, чтобы было понятнее работать.
что предоставлено, с тем и работаю. не писать же мне с нуля ваш проект ))
Это понятное дело.)
Я сделал вот так, чтобы проверить, работает ли счётчик.
Код программы:
Код формы:
Не хочет работать.
Я сделал простой вывод текста по испусканию сигнала...
Чего не хватает программе?)
Python:
QML:
Есть на qml что-то типа window.onload? Чтобы при загрузке формы срабатывал сигнал. По нажатию кнопки всё прекрасно работает... А вот при загрузке формы нет...
Да, с console.log() я разобрался, счётчик ничего не показывает
У всех компонентов есть встраиваемый обработчик Component.onCompleted, который выполняется, когда объект полностью создан
Наверное сигнал всё-таки не вызывается правильно
А не подскажете, как вызвать правильно? :)
Сделал вот такой вариант и он работает, только мне непонятно, почему в консоли пишется undefined...
Форма:
Скрипт:
undefined пишет потому, что метод сам по себе ничего не возвращает, то есть void, напишите так
Вернул код инструкции, если я правильно понял.
Вернулся указатель на ваш объект. Ну слот срабатывает. Вам теперь нужно дальше развить вашу задачу. У меня к сожалению нет времени разбираться с opencv, поэтому не могу ответить на некоторые вопросы.
С opencv я разберусь. :) У меня пока только вопросы по сигналам и слотам.)
На сколько мне известно в opencv с камеры подпются картинки через определенное время и так выходит видео. По идее можно по получении этой картинки передавать ее в qml. Прикрепить сигнал к получению картинки или таймеру и так подовать сигнал в qml об необходимости обновления.
Если смотреть глубже, то там подаётся массив байтов(bytes в питоне). Ну, а по простому, то да. Я пока не разобрался как переменную передавать в qml форму. В этой самой переменной, пускай будет frame, как раз хранится поток с веб-камеры. Как только я передам её на форму, то по идее, элемент в котором будет "отображаться" данная переменная, нужно же перерисовывать, чтобы кадры обновлялись.