Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.12.2019, 07:38   #1
25-й кадр
Человек
Форумчанин
 
Регистрация: 04.04.2011
Сообщений: 178
По умолчанию Python, QML, OpenCV

Доброго времени суток.
Пытаюсь сделать отображение с веб-камеры в графическом интерфейсе написанном на qml.
Код программы:
Код:
#системные библиотеки
import cv2
import numpy as np
import sys
import threading
 
#PyQt библиотеки
from PyQt5.QtGui import QGuiApplication, QImage
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
 
#интерфейсы

class Vision(QObject):

    def __init__(self):
        super().__init__()
        #self.frameChanged = frameChanged
    
        
        t1 = threading.Thread(name = 'Vision', target=self.vis())
        t1.start()
        print ('Thread ' + t1.name + ' is load')
    frameChanged = pyqtSignal(bytes, arguments = ['vis'])    #не работает :(

    @pyqtSlot(bytes)
    def vis(self):
     
        cap = cv2.VideoCapture(0)
     
        while(True):
            ret, frame = cap.read() # frame - переменная куда записываются показания с камеры
            ####################################################################
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            height, width, channel = frame.shape
            step = channel * width
            qImg = QImage(frame.data, width, height, step, QImage.Format_RGB888)
            self.frameChanged.emit(qImg)    #не знаю, как перевести
            ####################################################################
            cv2.imshow('frame', frame) # отображение показаний с камеры в окне созданном opencv
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
            
        #cap.release()
        cv2.destroyAllWindows()

if __name__ == "__main__":
 
    # создаём экземпляр приложения
    app = QGuiApplication(sys.argv)
    # создаём QML движок
    engine = QQmlApplicationEngine()
    # создаём объект vision
    videoProvider = Vision()
    # и регистрируем его в контексте QML
    engine.rootContext().setContextProperty("videoProvider", videoProvider)
    # загружаем файл qml в движок
    engine.load("Interface_vr_eyes.qml")
    #Vision()
    engine.quit.connect(app.quit)
    sys.exit(app.exec_())
Вот код формы:

Код:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window 
{
    id: ive_win
    width: 640
    height: 480
	visible: true				
    title: qsTr("Test title")

    Rectangle 
	{
        width: parent.width
        height: parent.height
        color: "blue"
		
		Image
		{
			id: videoLayer
			anchors.fill: parent
			cache: false

			onSourceChanged:{
				videoProvider.framePainted();
			}
		}
		
		Connections
		{
			target: videoProvider
			property int frameCounter: 0

			onFrameChanged:
			{
				videoLayer.source = "image://videoCapture/hoge" + frameCounter;
				frameCounter ^= 1;
			}
		}
    }
}
Читал статью про слоты и сигналы в python https://evileg.com/ru/post/242/, но пока не могу сообразить, как это всё складывается воедино.
Представленный код отображает окно с веб-камерой и окно qml интерфейста.
И да, при работе с веб-камерой, данные которые нужно отправлять(полагаю) через сигнал имеют тип "byte". В питоне обозначаются, как bytes. Что-то типа:
Код:
frameChanged = pyqtSignal(bytes, arguments = ['vis'])
Есть на C++ образец... Я в нём не силён, подсобите перевести на python3.
http://qaru.site/questions/14597959/...eak-opencv-qml

Спасибо!
Это вам не это

Последний раз редактировалось 25-й кадр; 07.12.2019 в 07:41.
25-й кадр вне форума Ответить с цитированием
Старый 07.12.2019, 09:15   #2
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Не морочьте себе голову, поставьте просто
Код:
        frameChanged = pyqtSignal(object)
Black Fregat вне форума Ответить с цитированием
Старый 07.12.2019, 16:20   #3
25-й кадр
Человек
Форумчанин
 
Регистрация: 04.04.2011
Сообщений: 178
По умолчанию

Спасибо за подсказку, только в qml форму всё равно не выводит.)
Это вам не это
25-й кадр вне форума Ответить с цитированием
Старый 09.12.2019, 09:32   #4
25-й кадр
Человек
Форумчанин
 
Регистрация: 04.04.2011
Сообщений: 178
По умолчанию

Нашёл ещё такой материал с картинкой. Пока что затрудняюсь вместо картинки отправлять видео поток.
https://stackoverflow.com/questions/...provider-pyqt5
Это вам не это
25-й кадр вне форума Ответить с цитированием
Старый 09.12.2019, 10:43   #5
25-й кадр
Человек
Форумчанин
 
Регистрация: 04.04.2011
Сообщений: 178
По умолчанию

Обновил код и получил некий результат по материалу отображения картинки.
Код программы:
Код:
#системные библиотеки
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_())
Код qml формы:
Код:
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"
    }
}
Получается, что в qml форме отображается последний кадр снятый веб-камерой. Есть идеи, как отобразить постоянный поток с веб-камеры в форму qml?
Это вам не это
25-й кадр вне форума Ответить с цитированием
Старый 13.04.2021, 21:48   #6
Vladimir82
Новичок
Джуниор
 
Регистрация: 10.04.2021
Сообщений: 1
По умолчанию QML_PyQt5_OpenCV

Ссылка на рабочий код связки QML_PyQt5_OpenCV.
Один хороший человек создал модуль, реализующий обработчик камеры с помощью opencv, в дополнение к средству просмотра и универсальному классу, позволяющие добавлять фильтры.
Осознаем и допиливаем под свои задачи
https://coderoad.ru/52944567/%D0%9D%...0%BD%D0%B0-QML

Только в строке dir_path = os.path.dirname(os.path.realpath(__ file__)) <-- добавьте скобочку
Vladimir82 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Начальный уровень Python. Функции - Python YYYUUU Python 5 09.06.2017 12:09
Установка Python и OpenCV Hhrusst Python 0 02.04.2017 15:21
OpenCV Taner Visual C++ 1 17.05.2014 18:01
Python или C++ и OpenCV, программа eiscalle Фриланс 1 05.03.2013 04:51
OpenCV. C++ API. TheVampire Общие вопросы C/C++ 3 11.04.2010 19:41