0

I am working on trying to collect the video from a Basler GigE camera using PyPylon and converting it to an array. I want to be able to take this image array that is constantly updating and show it on a PyQt5 gui. I am unsure what I am doing wrong. Below is the code, any help would be greatly appreciated!

from PyQt5 import QtGui
from PyQt5.QtWidgets import QWidget, QApplication, QLabel, QVBoxLayout
from PyQt5.QtGui import QPixmap
import sys
import cv2
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QThread
import numpy as np
from pypylon import pylon

class BaslerVideo():
    def _videoGrab(self):
        camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
        
        camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
        converter = pylon.ImageFormatConverter()
        
        converter.OutputPixelFormat = pylon.PixelType_BGR8packed
        converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
        
        while camera.IsGrabbing():
            grabResult = camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
            
            if grabResult.GrabSucceeded():
                image = converter.Convert(grabResult)
                img = image.GetArray()
        return img




class VideoThread(QThread, BaslerVideo):
    change_pixmap_signal = pyqtSignal(np.ndarray)

    def run(self):
        # capture from web cam
        cap = BaslerVideo()
        while True:
            cv_img = cap._videoGrab()
            self.change_pixmap_signal.emit(cv_img)
            
class App(QWidget):
    def __inti__(self):
        super().__init__()
        self.setWindowTitle("GigE Cam Test")
        self.display_width = 640
        self.display_height = 480
        #Create the label that holds the image 
        self.image_label = QLabel(self)
        self.image_label.resize(self.display_width,self.display_height)
        #Create a text label 
        self.textLabel = QLabel("GigE Cam")
        
        #Create the box that will hold the image 
        vbox = QVBoxLayout()
        vbox.addWidget(self.image_label)
        vbox.addWidget(self.textLabel)
        #Set the layout 
        self.setLayout(vbox)
        
        #create the video capture thread 
        self.thread = VideoThread()
        #connect its signal to the update_image slot
        self.thread.change_pixmap_signal.connect(self.update_image)
        #Start the thread
        self.thread.start()
        
        @pyqtSlot(np.ndarray)
        def update_image(self, cv_img):
            """Updates the image_label with a new opencv image"""
            qt_img = self.convert_cv_qt(cv_img)
            self.image_label.setPixmap(qt_img)
            
        def convert_cv_qt(self, cv_img):
            """Convert from a numpy array img to a Qpixmap"""
            rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
            h, w, ch = rgb_image.shape
            bytes_per_line = ch * w
            convert_to_Qt_format = QtGui.QImage(rgb_image.data, w, h, bytes_per_line,QtGui.QImage.Format_RGB888)
            p = convert_to_Qt_format.scaled(self.display_width,self.display_height, Qt.KeepAspectRatio)
            return QPixmap().fromImage(p)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    a = App()
    a.show()
    sys.exit(app.exec_())
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • why do you think you're doing anything wrong? please review [mre] – Christoph Rackwitz Sep 13 '22 at 18:59
  • I can see two things that are clearly wrong. 1. The fact that you're inheriting from `BaslerVideo` *and* creating a new instance; 2. `_videoGrab` doesn't return while it's grabbing, so it won't return anything. All this doesn't make a lot of sense, and the `BaslerVideo` class seems rather useless. Just implement the `_videoGrab` logic in the `run()` of `VideoThread`. – musicamante Sep 13 '22 at 22:25
  • talk to this person: https://stackoverflow.com/questions/73684543/how-to-display-opencv-camera-feed-in-a-qml-pyside6-application – Christoph Rackwitz Sep 14 '22 at 00:18

0 Answers0