Bild einer Wärmebildkamera in PyQt5 Label ausgeben

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
DSY
User
Beiträge: 1
Registriert: Dienstag 1. Juni 2021, 13:34

Dienstag 1. Juni 2021, 13:57

Hallo liebe Community, ich habe folgendes Problem:

Mir wurde folgender Code zur Verfügung gestellt um Temperaturdaten und Videomaterial von einer Wärmebildkamera zu erhalten:

Code: Alles auswählen

from ctypes.util import find_library
import numpy as np
import ctypes as ct
import cv2
import os

#Define EvoIRFrameMetadata structure for additional frame infos
class EvoIRFrameMetadata(ct.Structure):
    
      
    _fields_ = [("counter", ct.c_uint),
                 ("counterHW", ct.c_uint),
                 ("timestamp", ct.c_longlong),
                 ("timestampMedia", ct.c_longlong),
                 ("flagState", ct.c_int),
                 ("tempChip", ct.c_float),
                 ("tempFlag", ct.c_float),
                 ("tempBox", ct.c_float),
                 ]
    
   


    def run(self):
        # load library
        if os.name == 'nt':
                #windows:
                libir = ct.CDLL("C:\\Users\\Danie\\Desktop\\libirimager-8.7.0-windows\\irDirectSDK\\sdk\\x64\\libirimager.dll") 
        else:
                #linux:
                libir = ct.cdll.LoadLibrary(ct.util.find_library("irdirectsdk"))

        #path to config xml file
        pathXml = ct.c_char_p(b'C:\\Users\\Danie\\Desktop\\libirimager-8.7.0-windows\\irDirectSDK\\examples\\python\\generic.xml')

        # init vars
        pathFormat = ct.c_char_p()
        pathLog = ct.c_char_p(b'logfilename')

        palette_width = ct.c_int()
        palette_height = ct.c_int()

        thermal_width = ct.c_int()
        thermal_height = ct.c_int()

        serial = ct.c_ulong()
        

        # init lib
        ret = libir.evo_irimager_usb_init(pathXml, pathFormat, pathLog)
        if ret != 0:
                print("error at init")
                exit(ret)

        # get the serial number
        ret = libir.evo_irimager_get_serial(ct.byref(serial))
        print('serial: ' + str(serial.value))

        # get thermal image size
        libir.evo_irimager_get_thermal_image_size(ct.byref(thermal_width), ct.byref(thermal_height))
        print('thermal width: ' + str(thermal_width.value))
        print('thermal height: ' + str(thermal_height.value))

        # init thermal data container
        np_thermal = np.zeros([thermal_width.value * thermal_height.value], dtype=np.uint16)
        npThermalPointer = np_thermal.ctypes.data_as(ct.POINTER(ct.c_ushort))

        # get palette image size, width is different to thermal image width duo to stride alignment!!!
        libir.evo_irimager_get_palette_image_size(ct.byref(palette_width), ct.byref(palette_height))
        print('palette width: ' + str(palette_width.value))
        print('palette height: ' + str(palette_height.value))

        # init image container
        np_img = np.zeros([palette_width.value * palette_height.value * 3], dtype=np.uint8)
        npImagePointer = np_img.ctypes.data_as(ct.POINTER(ct.c_ubyte))


        # capture and display image till q is pressed
        while chr(cv2.waitKey(1) & 255) != 'q':
                #get thermal and palette image with metadat
                ret = libir.evo_irimager_get_thermal_palette_image_metadata(thermal_width, thermal_height, npThermalPointer, palette_width, palette_height, npImagePointer, ct.byref(metadata))

                if ret != 0:
                        print('error on evo_irimager_get_thermal_palette_image ' + str(ret))
                        continue

                #calculate total mean value
                mean_temp = np_thermal.mean()
                mean_temp = mean_temp / 10. - 100

                print('mean temp: ' + str(mean_temp))

                #display palette image
                frame = np_img.reshape(palette_height.value, palette_width.value, 3)[:,:,::-1]
                cv2.imshow('image',frame)
    
                
             

                
        # clean shutdown
        libir.evo_irimager_terminate()
        cv2.destroyAllWindows()
        
metadata = EvoIRFrameMetadata()
metadata.run()
Die Grundsätzlich ausgabe mit opencv funktioniert reibungslos. Gerne würde ich das Videomaterial und die Temperaturdaten jedoch in einer GUI(PyQt5) ausgeben. Dieses gelingt mir bisher nicht. Mit anderen Kameras war es mir bereits möglich mit Hilfe einer Kombination von Thread und Pixmap Videomaterial in einem Label ausgeben zu lassen. Dieses lässt sich jedoch leider nicht analog auf dieses Problem übertragen. Vielleicht hat ja jemand eine Idee, einen Tipp oder einen Denkanstoß für mich.
__deets__
User
Beiträge: 9833
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dienstag 1. Juni 2021, 17:10

Der Frame ist doch einfach ein numpy Array. Was ist daran anders als an all den anderen, bei denen es geht? Was versuchst du, und was geht nicht?
Sirius3
User
Beiträge: 14569
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 2. Juni 2021, 08:04

Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 4 und mal 8.
Die Klasse `EvoIRFrameMetadata` ist seltsam. Du erzeugst ein leere Struktur und benutzt die nie.
`run` sollte also eine ganz normale Funktion sein.

Statt ctypes-Typen anzulegen, solltest Du den C-Funktionen Funktionssignaturen geben und ctypes die Konvertierung automatisch machen lassen.
`exit` sollte nicht irgendwo mitten drin auftauchen. Benutze Exceptions.
String setzt man nicht per str und + zusammen, sondern benutzt Formatstrings.

Code: Alles auswählen

from ctypes.util import find_library
import numpy as np
import ctypes as ct
import cv2
import os

#Define EvoIRFrameMetadata structure for additional frame infos
class EvoIRFrameMetadata(ct.Structure):
    _fields_ = [("counter", ct.c_uint),
                 ("counterHW", ct.c_uint),
                 ("timestamp", ct.c_longlong),
                 ("timestampMedia", ct.c_longlong),
                 ("flagState", ct.c_int),
                 ("tempChip", ct.c_float),
                 ("tempFlag", ct.c_float),
                 ("tempBox", ct.c_float),
                 ]


def load_lib():
    # load library
    if os.name == 'nt':
        #windows:
        libir = ct.CDLL("C:\\Users\\Danie\\Desktop\\libirimager-8.7.0-windows\\irDirectSDK\\sdk\\x64\\libirimager.dll") 
    else:
        #linux:
        libir = ct.cdll.LoadLibrary(ct.util.find_library("irdirectsdk"))

    libir.evo_irimager_usb_init.argtypes = [ct.c_char_p, ct.c_char_p, ct.char_p]
    libir.evo_irimager_get_serial.argtypes = [ct.POINTER(ct.c_ulong)]
    libir.evo_irimager_get_thermal_image_size.argtypes = [ct.POINTER(ct.c_int), ct.POINTER(ct.c_int)]
    libir.evo_irimager_get_palette_image_size.argtypes = [ct.POINTER(ct.c_int), ct.POINTER(ct.c_int)]
    libir.evo_irimager_get_thermal_palette_image_metadata.argtypes = [
        ct.c_int. ct.c_int, ct.POINTER(ct.c_ushort),
        ct.c_int, ct.c_int, ct.POINTER(ct.c_ubytes),
        ct.POINTER(EvoIRFrameMetadata),
    ]
    return libir

def main():
    libir = load_lib()

    result = libir.evo_irimager_usb_init(
        b'C:\\Users\\Danie\\Desktop\\libirimager-8.7.0-windows\\irDirectSDK\\examples\\python\\generic.xml', 
        b'',
        b'logfilename')
    if result != 0:
        raise RuntimeError("error at init", result)
    
    # get the serial number
    serial = ct.c_ulong()
    libir.evo_irimager_get_serial(ct.byref(serial))
    print(f'serial: {serial.value}')

    # get thermal image size
    thermal_width = ct.c_int()
    thermal_height = ct.c_int()
    libir.evo_irimager_get_thermal_image_size(ct.byref(thermal_width), ct.byref(thermal_height))
    print(f'thermal width: {thermal_width.value}')
    print(f'thermal height: {thermal_height.value}')

    # get palette image size, width is different to thermal image width duo to stride alignment!!!
    palette_width = ct.c_int()
    palette_height = ct.c_int()
    libir.evo_irimager_get_palette_image_size(ct.byref(palette_width), ct.byref(palette_height))
    print(f'palette width: {palette_width.value}')
    print(f'palette height: {palette_height.value}')

    
    # init thermal data container
    thermal_image = np.zeros([thermal_width.value, thermal_height.value], dtype=np.uint16)
    # init image container
    palette_image = np.zeros([palette_width.value, palette_height.value, 3], dtype=np.uint8)


    # capture and display image till q is pressed
    metadata = EvoIRFrameMetadata()
    while chr(cv2.waitKey(1) & 255) != 'q':
            #get thermal and palette image with metadat
            result = libir.evo_irimager_get_thermal_palette_image_metadata(
                thermal_width, thermal_height, thermal_image.ctypes.data_as(ct.POINTER(ct.c_ushort)),
                palette_width, palette_height, palette_image.ctypes.data_as(ct.POINTER(ct.c_ubyte)),
                ct.byref(metadata)
            )

            if ret != 0:
                print(f'error on evo_irimager_get_thermal_palette_image {result}')
            else:
                #calculate total mean value
                mean_thermal = thermal_image.mean() / 10 - 100
                print(f'mean temp: {mean_temp}')

                #display palette image
                cv2.imshow('image', palette_image[:,:,::-1])
            
    # clean shutdown
    libir.evo_irimager_terminate()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()
Antworten