import os import ctypes as C from ctypes import wintypes as W # ========================= # CONFIG # ========================= SDK_DIR = os.path.join(os.path.dirname(__file__), "dlls") DLL_NAME = "VT_SDK64.dll" TIMEOUT_MS = 2000 WINDOW_NAME = "GAL5000 4CH Preview (E=AEC toggle, G=AGC toggle, Q=quit)" # Camera scan/open DEVICE_UDEF = 0 DEVICE_INDEX = 0 DATA_RAW = 0 # RAW geometry (como você já capturou) RAW_W = 2592 RAW_H = 2056 # Bayer+NIR pattern (2x2): # R G # IR B # => R = [0::2,0::2], G=[0::2,1::2], IR=[1::2,0::2], B=[1::2,1::2] # ========================= # PARAM IDs (VT_Param.h) # ========================= BUF_SIZE = 256 # PARAM_VALUETYPE VALUE_INT = 0 VALUE_FLOAT = 1 VALUE_STR = 2 # ========================= # PARAM IDs (recorte útil do VT_Param.h) # ========================= # COMMON / Display interno PARAM_ID_COMMON_DISPLAYENABLE = 0x00000200 PARAM_ID_COMMON_DISPLAYHWND = 0x00000201 PARAM_ID_COMMON_DISPLAYVSYNC = 0x00000202 PARAM_ID_COMMON_DISPLAYFPS = 0x00000203 PARAM_ID_COMMON_DISPLAYWIDTH = 0x00000204 PARAM_ID_COMMON_DISPLAYHEIGHT = 0x00000205 PARAM_ID_COMMON_DISPLAYPOSX = 0x00000206 PARAM_ID_COMMON_DISPLAYPOSY = 0x00000207 # SFNC Device info PARAM_ID_SFNC_DEVICETYPE = 0x00001001 PARAM_ID_SFNC_DEVICESCANTYPE = 0x00001002 PARAM_ID_SFNC_DEVICEVENDORNAME = 0x00001003 PARAM_ID_SFNC_DEVICEMODELNAME = 0x00001004 PARAM_ID_SFNC_DEVICEFAMILYNAME = 0x00001005 PARAM_ID_SFNC_DEVICEMANUFACTURERINFO = 0x00001006 PARAM_ID_SFNC_DEVICEVERSION = 0x00001007 PARAM_ID_SFNC_DEVICEFIRMWAREVERSION = 0x00001008 PARAM_ID_SFNC_DEVICESERIALNUMBER = 0x00001009 PARAM_ID_SFNC_DEVICEUSERID = 0x0000100B # SFNC image format / ROI PARAM_ID_SFNC_SENSORWIDTH = 0x00001101 PARAM_ID_SFNC_SENSORHEIGHT = 0x00001102 PARAM_ID_SFNC_WIDTHMAX = 0x00001106 PARAM_ID_SFNC_HEIGHTMAX = 0x00001107 PARAM_ID_SFNC_WIDTH = 0x00001111 PARAM_ID_SFNC_HEIGHT = 0x00001112 PARAM_ID_SFNC_OFFSETX = 0x00001113 PARAM_ID_SFNC_OFFSETY = 0x00001114 # SFNC Acquisition / Trigger / Exposure PARAM_ID_SFNC_ACQUISITIONFRAMERATEENABLE = 0x00001209 PARAM_ID_SFNC_ACQUISITIONLINERATE = 0x0000120A PARAM_ID_SFNC_ACQUISITIONLINERATEENABLE = 0x0000120B PARAM_ID_SFNC_TRIGGERSELECTOR = 0x0000120E PARAM_ID_SFNC_TRIGGERMODE = 0x0000120F PARAM_ID_SFNC_TRIGGERSOFTWARE = 0x00001210 PARAM_ID_SFNC_TRIGGERSOURCE = 0x00001211 PARAM_ID_SFNC_TRIGGERACTIVATION = 0x00001212 PARAM_ID_SFNC_TRIGGERDELAY = 0x00001214 PARAM_ID_SFNC_TRIGGERDIVIDER = 0x00001215 PARAM_ID_SFNC_TRIGGERMULTIPLIER = 0x00001216 PARAM_ID_SFNC_EXPOSUREMODE = 0x00001217 PARAM_ID_SFNC_EXPOSURETIMEMODE = 0x00001218 PARAM_ID_SFNC_EXPOSURETIMESELECTOR = 0x00001219 PARAM_ID_SFNC_EXPOSURETIME = 0x0000121A PARAM_ID_SFNC_EXPOSUREAUTO = 0x0000121B # SENSOR (ROI + Exposure/Gain, etc) PARAM_ID_SENSOR_OFFSETV = 0x00003001 PARAM_ID_SENSOR_WIDTH = 0x00003002 PARAM_ID_SENSOR_HEIGHT = 0x00003003 PARAM_ID_SENSOR_BLANKINGH = 0x00003004 PARAM_ID_SENSOR_BLANKINGV = 0x00003005 PARAM_ID_SENSOR_EXPOSURETIMERAW = 0x00003010 PARAM_ID_SENSOR_EXPOSUREAUTOENABLE = 0x00003011 PARAM_ID_SENSOR_GAINANALOGRAW = 0x00003020 PARAM_ID_SENSOR_GAINANALOGAUTOENABLE = 0x00003021 PARAM_ID_SENSOR_GAINANALOGAGCMAX = 0x00003022 PARAM_ID_SENSOR_GAINDIGITRAW = 0x0000302A PARAM_ID_SENSOR_GAINDIGITAUTOENABLE = 0x0000302B PARAM_ID_SENSOR_GAINDIGITAGCMAX = 0x0000302C PARAM_ID_SENSOR_BITLUT = 0x00003040 # IPU (Image Process Unit) PARAM_ID_IPU_BRIGHTNESS = 0x00003100 PARAM_ID_IPU_CONTRAST = 0x00003101 # GRAB (imagem / stream) PARAM_ID_GRAB_FRAMERATE = 0x00005001 # ========================= # TABELA DE PROBE # (nome, id, tipo do VALUE_*) # ========================= PARAMS_TO_PROBE = [ # COMMON display ("COMMON_DISPLAYENABLE", PARAM_ID_COMMON_DISPLAYENABLE, VALUE_INT), ("COMMON_DISPLAYVSYNC", PARAM_ID_COMMON_DISPLAYVSYNC, VALUE_INT), ("COMMON_DISPLAYFPS", PARAM_ID_COMMON_DISPLAYFPS, VALUE_FLOAT), ("COMMON_DISPLAYWIDTH", PARAM_ID_COMMON_DISPLAYWIDTH, VALUE_INT), ("COMMON_DISPLAYHEIGHT", PARAM_ID_COMMON_DISPLAYHEIGHT, VALUE_INT), ("COMMON_DISPLAYPOSX", PARAM_ID_COMMON_DISPLAYPOSX, VALUE_INT), ("COMMON_DISPLAYPOSY", PARAM_ID_COMMON_DISPLAYPOSY, VALUE_INT), # Device info ("SFNC_DEVICETYPE", PARAM_ID_SFNC_DEVICETYPE, VALUE_INT), ("SFNC_DEVICESCANTYPE", PARAM_ID_SFNC_DEVICESCANTYPE, VALUE_INT), ("SFNC_DEVICEVENDORNAME", PARAM_ID_SFNC_DEVICEVENDORNAME, VALUE_STR), ("SFNC_DEVICEMODELNAME", PARAM_ID_SFNC_DEVICEMODELNAME, VALUE_STR), ("SFNC_DEVICEFAMILYNAME", PARAM_ID_SFNC_DEVICEFAMILYNAME, VALUE_STR), ("SFNC_DEVICEVERSION", PARAM_ID_SFNC_DEVICEVERSION, VALUE_STR), ("SFNC_DEVICEFIRMWAREVERSION",PARAM_ID_SFNC_DEVICEFIRMWAREVERSION, VALUE_STR), ("SFNC_DEVICESERIALNUMBER", PARAM_ID_SFNC_DEVICESERIALNUMBER, VALUE_STR), ("SFNC_DEVICEUSERID", PARAM_ID_SFNC_DEVICEUSERID, VALUE_STR), # SFNC ROI / image ("SFNC_SENSORWIDTH", PARAM_ID_SFNC_SENSORWIDTH, VALUE_INT), ("SFNC_SENSORHEIGHT", PARAM_ID_SFNC_SENSORHEIGHT, VALUE_INT), ("SFNC_WIDTHMAX", PARAM_ID_SFNC_WIDTHMAX, VALUE_INT), ("SFNC_HEIGHTMAX", PARAM_ID_SFNC_HEIGHTMAX, VALUE_INT), ("SFNC_WIDTH", PARAM_ID_SFNC_WIDTH, VALUE_INT), ("SFNC_HEIGHT", PARAM_ID_SFNC_HEIGHT, VALUE_INT), ("SFNC_OFFSETX", PARAM_ID_SFNC_OFFSETX, VALUE_INT), ("SFNC_OFFSETY", PARAM_ID_SFNC_OFFSETY, VALUE_INT), # SFNC acquisition / trigger / exposure ("SFNC_ACQFRAMERATEENABLE", PARAM_ID_SFNC_ACQUISITIONFRAMERATEENABLE, VALUE_INT), ("SFNC_ACQLINERATE", PARAM_ID_SFNC_ACQUISITIONLINERATE, VALUE_FLOAT), ("SFNC_ACQLINERATEENABLE", PARAM_ID_SFNC_ACQUISITIONLINERATEENABLE, VALUE_INT), ("SFNC_TRIGGERSELECTOR", PARAM_ID_SFNC_TRIGGERSELECTOR, VALUE_INT), ("SFNC_TRIGGERMODE", PARAM_ID_SFNC_TRIGGERMODE, VALUE_INT), ("SFNC_TRIGGERSOFTWARE", PARAM_ID_SFNC_TRIGGERSOFTWARE, VALUE_INT), ("SFNC_TRIGGERSOURCE", PARAM_ID_SFNC_TRIGGERSOURCE, VALUE_INT), ("SFNC_TRIGGERACTIVATION", PARAM_ID_SFNC_TRIGGERACTIVATION, VALUE_INT), ("SFNC_TRIGGERDELAY", PARAM_ID_SFNC_TRIGGERDELAY, VALUE_FLOAT), ("SFNC_TRIGGERDIVIDER", PARAM_ID_SFNC_TRIGGERDIVIDER, VALUE_INT), ("SFNC_TRIGGERMULTIPLIER", PARAM_ID_SFNC_TRIGGERMULTIPLIER, VALUE_INT), ("SFNC_EXPOSUREMODE", PARAM_ID_SFNC_EXPOSUREMODE, VALUE_INT), ("SFNC_EXPOSURETIMEMODE", PARAM_ID_SFNC_EXPOSURETIMEMODE, VALUE_INT), ("SFNC_EXPOSURETIMESELECTOR",PARAM_ID_SFNC_EXPOSURETIMESELECTOR, VALUE_INT), ("SFNC_EXPOSURETIME", PARAM_ID_SFNC_EXPOSURETIME, VALUE_FLOAT), ("SFNC_EXPOSUREAUTO", PARAM_ID_SFNC_EXPOSUREAUTO, VALUE_INT), # SENSOR ROI + gains ("SENSOR_OFFSETV", PARAM_ID_SENSOR_OFFSETV, VALUE_INT), ("SENSOR_WIDTH", PARAM_ID_SENSOR_WIDTH, VALUE_INT), ("SENSOR_HEIGHT", PARAM_ID_SENSOR_HEIGHT, VALUE_INT), ("SENSOR_BLANKINGH", PARAM_ID_SENSOR_BLANKINGH, VALUE_INT), ("SENSOR_BLANKINGV", PARAM_ID_SENSOR_BLANKINGV, VALUE_INT), ("SENSOR_EXPOSURETIMERAW", PARAM_ID_SENSOR_EXPOSURETIMERAW, VALUE_INT), ("SENSOR_EXPOSUREAUTOENABLE",PARAM_ID_SENSOR_EXPOSUREAUTOENABLE, VALUE_INT), ("SENSOR_GAINANALOGRAW", PARAM_ID_SENSOR_GAINANALOGRAW, VALUE_INT), ("SENSOR_GAINANALOGAUTOENABLE",PARAM_ID_SENSOR_GAINANALOGAUTOENABLE, VALUE_INT), ("SENSOR_GAINANALOGAGCMAX", PARAM_ID_SENSOR_GAINANALOGAGCMAX, VALUE_INT), ("SENSOR_GAINDIGITRAW", PARAM_ID_SENSOR_GAINDIGITRAW, VALUE_INT), ("SENSOR_GAINDIGITAUTOENABLE",PARAM_ID_SENSOR_GAINDIGITAUTOENABLE, VALUE_INT), ("SENSOR_GAINDIGITAGCMAX", PARAM_ID_SENSOR_GAINDIGITAGCMAX, VALUE_INT), ("SENSOR_BITLUT", PARAM_ID_SENSOR_BITLUT, VALUE_INT), # IPU ("IPU_BRIGHTNESS", PARAM_ID_IPU_BRIGHTNESS, VALUE_INT), ("IPU_CONTRAST", PARAM_ID_IPU_CONTRAST, VALUE_INT), # Grab ("GRAB_FRAMERATE", PARAM_ID_GRAB_FRAMERATE, VALUE_FLOAT), ] # ========================= # STRUCTS (mínimo necessário) # ========================= class VT_FRAMEINFO(C.Structure): _fields_ = [ ("lFrameID", W.DWORD), ("lBufSize", W.DWORD), ("lWidth", W.DWORD), ("lHeight", W.DWORD), ("lPixBits", C.c_ubyte), ("_pad0", C.c_ubyte * 3), ("pBufPtr", C.POINTER(C.c_ubyte)), ("lFrameStatus", W.DWORD), ("lPixType", W.DWORD), ("lTimeStamp", W.DWORD), ("_reserve", W.DWORD * 8), ] class VT_DEVPARAM(C.Structure): _fields_ = [ ("bUseName", W.BOOL), ("lParamByID", W.DWORD), ("lParamByName", C.c_char * BUF_SIZE), ] def devparam_by_id(pid: int) -> VT_DEVPARAM: p = VT_DEVPARAM() p.bUseName = False p.lParamByID = pid p.lParamByName = b"" # <- CORRETO: bytes (fica zerado / string vazia) return p # ========================= # DLL LOAD + prototypes # ========================= os.add_dll_directory(SDK_DIR) dll = C.WinDLL(os.path.join(SDK_DIR, DLL_NAME)) print("DLL carregada OK:", dll) dll.VT_DeviceScan.argtypes = [C.POINTER(C.c_ubyte), C.c_int] dll.VT_DeviceScan.restype = C.c_int dll.VT_DeviceOpen.argtypes = [C.c_void_p, C.POINTER(W.HANDLE), C.c_int, C.c_int] dll.VT_DeviceOpen.restype = C.c_int dll.VT_SingleFrameCapture.argtypes = [W.HANDLE, C.POINTER(VT_FRAMEINFO), C.c_int, C.c_int, W.BOOL] dll.VT_SingleFrameCapture.restype = C.c_int dll.VT_DeviceClose.argtypes = [C.POINTER(W.HANDLE)] dll.VT_DeviceClose.restype = C.c_int # Param API dll.VT_ParamGetValue.argtypes = [W.HANDLE, VT_DEVPARAM, C.c_void_p, C.c_int] dll.VT_ParamGetValue.restype = C.c_int dll.VT_ParamSetValue.argtypes = [W.HANDLE, VT_DEVPARAM, C.c_void_p, C.c_int] dll.VT_ParamSetValue.restype = C.c_int def ck(ret: int, name: str): if ret != 0: print(f"{name} falhou, ret={ret}") raise RuntimeError(f"{name} falhou, ret={ret}") def param_get_int(h: W.HANDLE, pid: int) -> int: p = devparam_by_id(pid) v = C.c_int(0) ret = dll.VT_ParamGetValue(h, p, C.byref(v), VALUE_INT) ck(ret, f"VT_ParamGetValue({hex(pid)})") return int(v.value) def param_get_float(h: W.HANDLE, pid: int) -> float: p = devparam_by_id(pid) v = C.c_float(0) ret = dll.VT_ParamGetValue(h, p, C.byref(v), VALUE_FLOAT) ck(ret, f"VT_ParamGetValue({hex(pid)})") return float(v.value) def param_get_str(h: W.HANDLE, pid: int) -> str: p = devparam_by_id(pid) # buffer de tamanho razoável (ajusta se precisar) buf_size = 256 buf = C.create_string_buffer(buf_size) ret = dll.VT_ParamGetValue(h, p, buf, VALUE_STR) ck(ret, f"VT_ParamGetValue({hex(pid)})") # strip em caso de lixo no final return buf.value.decode(errors="ignore").strip() def param_supported(h, pid, vtype): p = devparam_by_id(pid) minv = C.c_int() maxv = C.c_int() inc = C.c_int() ret = dll.VT_ParamGetRange(h, p, C.byref(minv), C.byref(maxv), C.byref(inc), vtype) return ret == 0 def probe_params(h: W.HANDLE): print("\n==== PARAM PROBE (VT SDK) ====") print(f"{'Name':35s} {'ID':10s} {'Supported':10s} Value") print("-" * 70) for name, pid, vtype in PARAMS_TO_PROBE: supported = param_supported(h, pid, vtype) if not supported: print(f"{name:35s} {hex(pid):10s} {'NO':10s} -") continue # tentar ler o valor atual try: if vtype == VALUE_INT: val = param_get_int(h, pid) elif vtype == VALUE_FLOAT: val = param_get_float(h, pid) elif vtype == VALUE_STR: val = param_get_str(h, pid) else: val = "" print(f"{name:35s} {hex(pid):10s} {'YES':10s} {val}") except Exception as e: print(f"{name:35s} {hex(pid):10s} {'YES':10s} ") def main(): # scan n = C.c_ubyte(0) ret = dll.VT_DeviceScan(C.byref(n), DEVICE_UDEF) ck(ret, "VT_DeviceScan") if n.value == 0: raise RuntimeError("Nenhuma câmera encontrada.") # open idx = C.c_ubyte(0) h = W.HANDLE() ret = dll.VT_DeviceOpen(C.byref(idx), C.byref(h), DEVICE_INDEX, DEVICE_UDEF) ck(ret, "VT_DeviceOpen") print("DeviceOpen OK, handle=", h.value) probe_params(h) if __name__ == "__main__": main()