Seite 1 von 1
Webcam Livebild in PyQt5 anzeigen
Verfasst: Mittwoch 12. Juni 2019, 07:54
von okliw994
Hallo zusammen,
Ich möchte über eine Benutzeroberfläche ein Pop-Up-Fenster öffnen um mir ein Livebild anzuzeigen. Ein neues Fenster zu öffnen und den Buttons Funktionen zuzuweisen funktioniert ohne Probleme. Die Fenster erstelle ich mit dem QtDesigner. Des Weiteren kann ich mir mit folgendem Code ein Livebild anzeigen lassen.
Code: Alles auswählen
cam = cv2.VideoCapture(0)
while(True):
ret_val, img = cam.read()
cv2.imshow('LB', img)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
Mein Problem ist, dass ich das im Code erzeugte Livebild nur über die ESC-Taste schließen kann. Mein System soll am Ende aber ohne Tastatur/nur mittels eines Touchscreens arbeiten. Daher möchte ich das Livebild in einem Fenster darstellen, welches einen Button zum schließen hat.
Kann mir jemand sagen, wie ich das Livebild mit dem Fenster verknüpfe / gemeinsam öffne?
Gruß, okliw994
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Mittwoch 12. Juni 2019, 08:01
von __deets__
Nicht mit opencv. Das zielt mit seiner highgui darauf ab, einen simplen und unkomplizierten Weg anzubieten, Fenster und eine Reihe von GUI controls darzustellen.
In dem Moment, wo du eine echte GUI drum rum willst, kommt die mit der highgui in Konflikt. Stattdessen muss dein Qt Programm die Kontrolle übernehmen, und per Timer die Frames aus dem capture holen. Wie zb hier:
http://benhoff.net/face-detection-opencv-pyqt.html
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Mittwoch 12. Juni 2019, 09:17
von __blackjack__
@okliw994: Randbemerkung: Die Klammern beim ``while`` gehören da nicht hin. Das ist keine Funktion, sollte also auch nicht so geschrieben werden als wäre es eine.
Ausserdem ist die Einrückung falsch. Man rückt vier Leerzeichen pro Ebene ein. Keine Tabs und schon gar nicht Tabs und Leerzeichen gemischt.
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Mittwoch 12. Juni 2019, 10:10
von okliw994
Erstmal Danke für eure Antworten.
Sorry, die Klammern waren wohl reine Gewohnheit aus Java und das mit der Einrückung werde ich zukünftig beachten.
Gibt es denn eine andere Möglichkeit das Fenster, welches mit dem oben gezeigten Code erzeugt wird, ohne Tastatur zu schließen?
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Mittwoch 12. Juni 2019, 10:25
von __deets__
Was passt dir an dem vorgeschlagenen Weg nicht? Und was ist an "Nicht mit opencv" unklar?
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Donnerstag 13. Juni 2019, 07:54
von okliw994
Für den vorgeschlagenen Weg fehlen mir anscheinend zu viel Vorkenntnisse um diesen zu verstehen.
Wie kann ich denn sonst die Webcam ohne opencv nutzen? Gibt es noch andere Bibliotheken?
MfG, okliw994
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Donnerstag 13. Juni 2019, 08:34
von __deets__
Du kannst stattdessen QMultiMedia nehmen. Ob das ohne Vorkenntnisse besser funktioniert wage ich aber zu bezweifeln. Du kannst auch opencv und dem Maus-callback eine GUI von Hand Stricken. Das ist ein bisschen durch die Brust ins Auge, aber je nach Anwendung ggf ok.
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Donnerstag 13. Juni 2019, 08:49
von __deets__
Um das nochmal klarzustellen: du hast von einer Qt5 Integration gesprochen. DAS geht nicht anders als gezeigt. highgui kann Maus Ereignisse, und natürlich kannst du damit auch eine Interaktion bauen. Wird allerdings mühselig.
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Donnerstag 13. Juni 2019, 09:04
von __blackjack__
Pygame hat eine (experimentelle) API für Webcams. Wenn es Dir reicht wenn der Benutzer irgendwo klicken kann oder Du Code für eine Schaltfläche selber schreiben möchtest. Wäre dann halt auch keine Qt-Anwendung. Wenn Du Qt willst, musst Du Dich wohl oder übel mit Qt auseinandersetzen.
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Donnerstag 13. Juni 2019, 09:24
von __deets__
Aber pygame liefert ihm die Bilder nicht direkt so wie OpenCV sie braucht. Das erfordert dann wieder den Erwerb dieser vermaledeiten Vorkenntnisse...
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Donnerstag 13. Juni 2019, 09:46
von __blackjack__
@__deets__: Okay, wenn man die Bilder danach irgendwie mit OpenCV weiterverarbeiten will, dann wäre es natürlich ziemlich unsinnig etwas anderes als OpenCV für das lesen der Bilder von der Webcam zu verwenden.
Einen OpenCV-Frame — also eigentlich ja ein Numpy-Array — in ein Pygame-Surface umzuwandeln ist aber auch nicht sooo schwer. Im Grunde muss man AFAIK nur die BGR→RGB-Konvertierung mit der passenden OpenCV-Funktion machen und dann mit der passenden Pygame-Funktion aus dem Numpy-Array ein Pygame-Surface. Die Frage ist halt was da noch an GUI-Anforderungen sind.
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Donnerstag 13. Juni 2019, 09:49
von __deets__
Nach einem Beispiel per Timer ein OpenCV-capture auslesen und darstellen ist auch nicht sooo schwer

Das ist halt mein Punkt: man wird sich schon ein bisschen reinknieen muessen, wenn man zwei solche Technologien miteinander verheiraten will. Egal wo man am Ende landet.
Re: Webcam Livebild in PyQt5 anzeigen
Verfasst: Freitag 14. Juni 2019, 14:15
von __blackjack__
Ich habe da mal was gebastelt:
Code: Alles auswählen
#!/usr/bin/env python3
import sys
from contextlib import closing
from functools import partial
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication
from PyQt5.uic import loadUi
import cv2
VIDEO_SOURCE = 0
def iter_frames(video_source):
video = cv2.VideoCapture(video_source)
if not video.isOpened():
raise IOError(f'video source {video_source!r} could not be opened')
try:
while True:
is_ok, frame = video.read()
if not is_ok:
break
yield frame
finally:
video.release()
def image_from_frame(frame):
assert frame.itemsize == 1
height, width, bytes_per_color = frame.shape
assert bytes_per_color == 3
return QImage(
frame.data, width, height, frame.strides[0], QImage.Format_RGB888
).rgbSwapped()
def display_next_image(timer, label, images):
try:
image = next(images)
except (StopIteration, IOError):
timer.stop()
else:
label.setPixmap(QPixmap.fromImage(image))
def main():
application = QApplication(sys.argv)
ui = loadUi('test.ui')
ui.exit_button.clicked.connect(ui.close)
with closing(iter_frames(VIDEO_SOURCE)) as frames:
timer = QTimer(ui)
timer.timeout.connect(
partial(
display_next_image,
timer,
ui.image_label,
map(image_from_frame, frames),
)
)
timer.start(50)
ui.show()
sys.exit(application.exec_())
if __name__ == '__main__':
main()
Die UI-Datei:
Code: Alles auswählen
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Cam</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="image_label"/>
</item>
<item>
<widget class="QPushButton" name="exit_button">
<property name="text">
<string>Stop</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>