diff --git a/src/components/galaxy_camera.py b/src/components/galaxy_camera.py index e0851a6..123922f 100644 --- a/src/components/galaxy_camera.py +++ b/src/components/galaxy_camera.py @@ -3,7 +3,7 @@ import sys from itertools import cycle import cv2 -import gxipy as gx +import src.components.gxipy as gx import imutils import numpy as np from PyQt5.QtCore import QMutex, Qt, QThread, pyqtSignal diff --git a/src/components/gxipy/__init__.py b/src/components/gxipy/__init__.py new file mode 100644 index 0000000..96d090f --- /dev/null +++ b/src/components/gxipy/__init__.py @@ -0,0 +1,11 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- +# -*-mode:python ; tab-width:4 -*- ex:set tabstop=4 shiftwidth=4 expandtab: -*- + +from gxiapi import * +from gxidef import * + + +__all__ = ["gxwrapper", "dxwrapper", "gxiapi", "gxidef"] + +__version__ = '2.0.2105.9261' diff --git a/src/components/gxipy/dxwrapper.py b/src/components/gxipy/dxwrapper.py new file mode 100644 index 0000000..6501d47 --- /dev/null +++ b/src/components/gxipy/dxwrapper.py @@ -0,0 +1,910 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- +# -*-mode:python ; tab-width:4 -*- ex:set tabstop=4 shiftwidth=4 expandtab: -*- +# + +from ctypes import * +import sys +import os + +if sys.platform == 'linux2' or sys.platform == 'linux': + if os.path.exists('/usr/lib/libdximageproc.so') : + filepath = '/usr/lib/libdximageproc.so' + else: + filepath = '/usr/lib/libgxiapi.so' + try: + dll = CDLL(filepath) + except OSError: + print('Cannot find libdximageproc.so or libgxiapi.so.') +else: + try: + if (sys.version_info.major == 3 and sys.version_info.minor >= 8) or (sys.version_info.major > 3): + dll = WinDLL('DxImageProc.dll', winmode=0) + else: + dll = WinDLL('DxImageProc.dll') + except OSError: + print('Cannot find DxImageProc.dll.') + + +# status definition +class DxStatus: + OK = 0 # Operation is successful + PARAMETER_INVALID = -101 # Invalid input parameter + PARAMETER_OUT_OF_BOUND = -102 # The input parameter is out of bounds + NOT_ENOUGH_SYSTEM_MEMORY = -103 # System out of memory + NOT_FIND_DEVICE = -104 # not find device + STATUS_NOT_SUPPORTED = -105 # operation is not supported + CPU_NOT_SUPPORT_ACCELERATE = -106 # CPU does not support acceleration + + def __init__(self): + pass + + +# Bayer layout +class DxPixelColorFilter: + NONE = 0 # Isn't bayer format + RG = 1 # The first row starts with RG + GB = 2 # The first line starts with GB + GR = 3 # The first line starts with GR + BG = 4 # The first line starts with BG + + def __init__(self): + pass + + +# image actual bits +class DxActualBits: + BITS_8 = 8 # 8bit + BITS_10 = 10 # 10bit + BITS_12 = 12 # 12bit + BITS_14 = 14 # 14bit + BITS_16 = 16 # 16bit + + def __init__(self): + pass + + +# mono8 image process structure +class MonoImgProcess(Structure): + _fields_ = [ + ('defective_pixel_correct', c_bool), # Pixel correct switch + ('sharpness', c_bool), # Sharpness switch + ('accelerate', c_bool), # Accelerate switch + ('sharp_factor', c_float), # Sharpen the intensity factor + ('pro_lut', c_void_p), # Lookup table + ('lut_length', c_uint16), # Lut Buffer length + ('array_reserved', c_ubyte * 32), # Reserved + ] + + def __str__(self): + return "MonoImgProcess\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +# Raw8 Image process structure +class ColorImgProcess(Structure): + _fields_ = [ + ('defective_pixel_correct', c_bool), # Pixel correct switch + ('denoise', c_bool), # Noise reduction switch + ('sharpness', c_bool), # Sharpness switch + ('accelerate', c_bool), # Accelerate switch + ('arr_cc', c_void_p), # Color processing parameters + ('cc_buf_length', c_uint8), # Color processing parameters length(sizeof(VxInt16)*9) + ('sharp_factor', c_float), # Sharpen the intensity factor + ('pro_lut', c_void_p), # Lookup table + ('lut_length', c_uint16), # The length of the lookup table + ('cv_type', c_uint), # Interpolation algorithm + ('layout', c_uint), # Bayer format + ('flip', c_bool), # Image flip flag + ('array_reserved', c_ubyte * 32), # Reserved + ] + + def __str__(self): + return "ColorImgProcess\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +# Field correction process structure +class FieldCorrectionProcess(Structure): + _fields_ = [ + ('bright_buf', c_void_p), # Bright image buffer + ('dark_buf', c_void_p), # Dark image buffer + ('width', c_uint32), # image width + ('height', c_uint32), # image height + ('actual_bits', c_uint), # image actual bits + ('bayer_type', c_uint), # Bayer Type + ] + + def __str__(self): + return "FieldCorrectionProcess\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +# color transform factor +class ColorTransformFactor(Structure): + _fields_ = [ + ('fGain00', c_float), # red contribution to the red pixel (multiplicative factor) + ('fGain01', c_float), # green contribution to the red pixel (multiplicative factor) + ('fGain02', c_float), # blue contribution to the red pixel (multiplicative factor) + ('fGain10', c_float), # red contribution to the green pixel (multiplicative factor) + ('fGain11', c_float), # green contribution to the green pixel (multiplicative factor) + ('fGain12', c_float), # blue contribution to the green pixel (multiplicative factor) + ('fGain20', c_float), # red contribution to the blue pixel (multiplicative factor) + ('fGain21', c_float), # green contribution to the blue pixel (multiplicative factor) + ('fGain22', c_float), # blue contribution to the blue pixel (multiplicative factor) + ] + + def __str__(self): + return "ColorTransformFactor\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +if hasattr(dll, 'DxGetLut'): + def dx_get_lut(contrast_param, gamma, lightness): + """ + :brief calculating lookup table of 8bit image + :param contrast_param: contrast param,range(-50~100) + :param gamma: gamma param,range(0.1~10) + :param lightness: lightness param,range(-150~150) + :return: status State return value, See detail in DxStatus + lut lookup table + lut_length lookup table length(unit:byte) + """ + contrast_param_c = c_int32() + contrast_param_c.value = contrast_param + + gamma_c = c_double() + gamma_c.value = gamma + + lightness_c = c_int32() + lightness_c.value = lightness + + lut_length_c = c_uint16() + lut_length_c.value = 0 + + # Get length of the lookup table + dll.DxGetLut(contrast_param_c, gamma_c, lightness_c, None, byref(lut_length_c)) + + # Create buff to get LUT data + lut_c = (c_uint8 * lut_length_c.value)() + status = dll.DxGetLut(contrast_param_c, gamma_c, lightness_c, byref(lut_c), byref(lut_length_c)) + + return status, lut_c, lut_length_c.value + +CC_PARAM_ARRAY_LEN = 18 + +if hasattr(dll, "DxCalcCCParam"): + def dx_calc_cc_param(color_cc_param, saturation): + """ + :brief calculating array of image processing color adjustment + :param color_cc_param: color correction param address(get from camera) + :param saturation: saturation factor,Range(0~128) + :return: status: State return value, See detail in DxStatus + cc_param: color adjustment calculating array + """ + color_cc_param_c = c_int64() + color_cc_param_c.value = color_cc_param + + saturation_c = c_int16() + saturation_c.value = saturation + + length_c = c_uint8() + # DxCalcCCParam length = sizeof(int16)*9 = 2 * 9 = 18 + length_c.value = CC_PARAM_ARRAY_LEN + + # Create buff to get cc data + cc_param_c = (c_int16 * length_c.value)() + + status = dll.DxCalcCCParam(color_cc_param_c, saturation_c, byref(cc_param_c), length_c) + + return status, cc_param_c + + +if hasattr(dll, "DxCalcUserSetCCParam"): + def dx_calc_user_set_cc_param(color_transform_factor, saturation): + """ + :brief calculating array of image processing color adjustment + :param color_transform_factor: color correction param address(user set), + type should be list or tuple, size = 3*3=9 + :param saturation: saturation factor,Range(0~128) + :return: status: State return value, See detail in DxStatus + cc_param: color adjustment calculating array + """ + color_transform_factor_c = ColorTransformFactor() + color_transform_factor_c.fGain00 = color_transform_factor[0] + color_transform_factor_c.fGain01 = color_transform_factor[1] + color_transform_factor_c.fGain02 = color_transform_factor[2] + color_transform_factor_c.fGain10 = color_transform_factor[3] + color_transform_factor_c.fGain11 = color_transform_factor[4] + color_transform_factor_c.fGain12 = color_transform_factor[5] + color_transform_factor_c.fGain20 = color_transform_factor[6] + color_transform_factor_c.fGain21 = color_transform_factor[7] + color_transform_factor_c.fGain22 = color_transform_factor[8] + + saturation_c = c_int16() + saturation_c.value = saturation + + length_c = c_uint8() + # DxCalcCCParam length = sizeof(int16)*9 = 2 * 9 = 18 + length_c.value = CC_PARAM_ARRAY_LEN + + # Create buff to get cc data + cc_param_c = (c_int16 * length_c.value)() + + status = dll.DxCalcUserSetCCParam(byref(color_transform_factor_c), saturation_c, byref(cc_param_c), length_c) + + return status, cc_param_c + + +if hasattr(dll, "DxGetGammatLut"): + def dx_get_gamma_lut(gamma_param): + """ + :brief calculating gamma lookup table (RGB24) + :param gamma_param: gamma param,range(0.1 ~ 10) + :return: status: State return value, See detail in DxStatus + gamma_lut: gamma lookup table + lut_length: gamma lookup table length(unit:byte) + """ + gamma_param_c = c_double() + gamma_param_c.value = gamma_param + + lut_length_c = c_int() + status = dll.DxGetGammatLut(gamma_param_c, None, byref(lut_length_c)) + + gamma_lut = (c_ubyte * lut_length_c.value)() + status = dll.DxGetGammatLut(gamma_param_c, byref(gamma_lut), byref(lut_length_c)) + + return status, gamma_lut, lut_length_c.value + + +if hasattr(dll, "DxGetContrastLut"): + def dx_get_contrast_lut(contrast_param): + """ + :brief ccalculating contrast lookup table (RGB24) + :param contrast_param: contrast param,range(-50 ~ 100) + :return: status: State return value, See detail in DxStatus + contrast_lut: contrast lookup table + lut_length: contrast lookup table length(unit:byte) + """ + contrast_param_c = c_int() + contrast_param_c.value = contrast_param + + lut_length_c = c_int() + status = dll.DxGetContrastLut(contrast_param_c, None, byref(lut_length_c)) + + contrast_lut = (c_ubyte * lut_length_c.value)() + status = dll.DxGetContrastLut(contrast_param_c, byref(contrast_lut), byref(lut_length_c)) + + return status, contrast_lut, lut_length_c.value + + +if hasattr(dll, 'DxRaw8toRGB24'): + def dx_raw8_to_rgb24(input_address, output_address, width, height, convert_type, bayer_type, flip): + """ + :brief Convert Raw8 to Rgb24 + :param input_address: The input raw image buff address, buff size = width * height + :param output_address: The output rgb image buff address, buff size = width * height * 3 + :param width: Image width + :param height: Image height + :param convert_type: Bayer convert type, See detail in DxBayerConvertType + :param bayer_type: pixel color filter, See detail in DxPixelColorFilter + :param flip: Output image flip flag + True: turn the image upside down + False: do not flip + :return: status State return value, See detail in DxStatus + data_array Array of output images, buff size = width * height * 3 + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + convert_type_c = c_uint() + convert_type_c.value = convert_type + + bayer_type_c = c_uint() + bayer_type_c.value = bayer_type + + flip_c = c_bool() + flip_c.value = flip + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + status = dll.DxRaw8toRGB24(input_address_p, output_address_p, + width_c, height_c, convert_type_c, bayer_type_c, flip_c) + return status + + +if hasattr(dll, 'DxRaw8toRGB24Ex'): + def dx_raw8_to_rgb24_ex(input_address, output_address, width, height, convert_type, bayer_type, flip, channel_order): + """ + :brief Convert Raw8 to Rgb24 + :param input_address: The input raw image buff address, buff size = width * height + :param output_address: The output rgb image buff address, buff size = width * height * 3 + :param width: Image width + :param height: Image height + :param convert_type: Bayer convert type, See detail in DxBayerConvertType + :param bayer_type: pixel color filter, See detail in DxPixelColorFilter + :param flip: Output image flip flag + True: turn the image upside down + False: do not flip + :param channel_order: RGB channel order of output image + :return: status State return value, See detail in DxStatus + data_array Array of output images, buff size = width * height * 3 + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + convert_type_c = c_uint() + convert_type_c.value = convert_type + + bayer_type_c = c_uint() + bayer_type_c.value = bayer_type + + flip_c = c_bool() + flip_c.value = flip + + channel_order_c = c_uint() + channel_order_c.value = channel_order + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + status = dll.DxRaw8toRGB24Ex(input_address_p, output_address_p, + width_c, height_c, convert_type_c, bayer_type_c, flip_c, channel_order_c) + return status + + +if hasattr(dll, 'DxRaw16toRaw8'): + def dx_raw16_to_raw8(input_address, out_address, width, height, valid_bits): + """ + :brief Raw16 converted to Raw8 + :param input_address: The input image buff address, buff size = width * height * 2 + :param out_address: The output image buff address, buff size = width * height + :param width: Image width + :param height: Image height + :param valid_bits: Data valid digit, See detail in DxValidBit + :return: status State return value, See detail in DxStatus + data_array Array of output images, buff size = width * height + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + valid_bits_c = c_uint() + valid_bits_c.value = valid_bits + + input_address_p = c_void_p() + input_address_p.value = input_address + + out_address_p = c_void_p() + out_address_p.value = out_address + + status = dll.DxRaw16toRaw8(input_address_p, out_address_p, + width_c, height_c, valid_bits_c) + return status + + +if hasattr(dll, 'DxRotate90CW8B'): + def dx_raw8_rotate_90_cw(input_address, out_address, width, height): + """ + :brief To rotate the 8-bit image clockwise by 90 degrees + :param input_address: The input image buff address, buff size = width * height + :param out_address: The output image buff address, buff size = width * height + :param width: Image width + :param height: Image height + :return: status State return value, See detail in DxStatus + data_array Array of output images, buff size = width * height + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + input_address_p = c_void_p() + input_address_p.value = input_address + + out_address_p = c_void_p() + out_address_p.value = out_address + + status = dll.DxRotate90CW8B(input_address_p, out_address_p, + width_c, height_c) + return status + + +if hasattr(dll, 'DxRotate90CCW8B'): + def dx_raw8_rotate_90_ccw(input_address, out_address, width, height): + """ + :brief To rotate the 8-bit image counter clockwise by 90 degrees + :param input_address: The input image buff address, buff size = width * height + :param out_address: The output image buff address, buff size = width * height + :param width: Image width + :param height: Image height + :return: status State return value, See detail in DxStatus + data_array Array of output images, buff size = width * height + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + input_address_p = c_void_p() + input_address_p.value = input_address + + out_address_p = c_void_p() + out_address_p.value = out_address + + status = dll.DxRotate90CCW8B(input_address_p, out_address_p, + width_c, height_c) + return status + + +if hasattr(dll, "DxImageImprovment"): + def dx_image_improvement(input_address, output_address, width, height, + color_correction_param, contrast_lut, gamma_lut): + """ + :brief image quality improvement + :param input_address: input buffer address, buff size = width * height *3 + :param output_address: input buffer address, buff size = width * height *3 + :param width: image width + :param height: image height + :param color_correction_param: color correction param(get from camera) + :param contrast_lut: contrast lookup table + :param gamma_lut: gamma lookup table + :return: status State return value, See detail in DxStatus + data_array Array of output images, buff size = width * height * 3 + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + color_correction_param_c = c_int64() + color_correction_param_c.value = color_correction_param + + status = dll.DxImageImprovment(input_address_p, output_address_p, width_c, height_c, + color_correction_param_c, contrast_lut, gamma_lut) + return status + + +if hasattr(dll, "DxImageImprovmentEx"): + def dx_image_improvement_ex(input_address, output_address, width, height, + color_correction_param, contrast_lut, gamma_lut, channel_order): + """ + :brief image quality improvement + :param input_address: input buffer address, buff size = width * height *3 + :param output_address: input buffer address, buff size = width * height *3 + :param width: image width + :param height: image height + :param color_correction_param: color correction param(get from camera) + :param contrast_lut: contrast lookup table + :param gamma_lut: gamma lookup table + :param channel_order: RGB channel order of output image + :return: status State return value, See detail in DxStatus + data_array Array of output images, buff size = width * height * 3 + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + color_correction_param_c = c_int64() + color_correction_param_c.value = color_correction_param + + channel_order_c = c_uint() + channel_order_c.value = channel_order + + status = dll.DxImageImprovmentEx(input_address_p, output_address_p, width_c, height_c, + color_correction_param_c, contrast_lut, gamma_lut, channel_order_c) + return status + + +if hasattr(dll, "DxBrightness"): + def dx_brightness(input_address, output_address, image_size, factor): + """ + :brief Brightness adjustment (RGB24 or mono8) + :param input_address: input buffer address + :param output_address: output buffer address + :param image_size: image size + :param factor: brightness factor,range(-150 ~ 150) + :return: status: State return value, See detail in DxStatus + """ + image_size_c = c_uint32() + image_size_c.value = image_size + + factor_c = c_int32() + factor_c.value = factor + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + status = dll.DxBrightness(input_address_p, output_address_p, image_size_c, factor_c) + return status + + +if hasattr(dll, "DxContrast"): + def dx_contrast(input_address, output_address, image_size, factor): + """ + :brief Contrast adjustment (RGB24 or mono8) + :param input_address: input buffer address + :param output_address: output buffer address + :param image_size: image size + :param factor: contrast factor,range(-50 ~ 100) + :return: status: State return value, See detail in DxStatus + """ + image_size_c = c_uint32() + image_size_c.value = image_size + + factor_c = c_int32() + factor_c.value = factor + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + status = dll.DxContrast(input_address_p, output_address_p, image_size_c, factor_c) + return status + + +if hasattr(dll, "DxSaturation"): + def dx_saturation(input_address, output_address, image_size, factor): + """ + :brief Saturation adjustment (RGB24) + :param input_address: input buffer address, buff size = width * height * 3 + :param output_address: output buffer address, buff size = width * height * 3 + :param image_size: image size (width * height) + :param factor: saturation factor,range(0 ~ 128) + :return: status: State return value, See detail in DxStatus + """ + image_size_c = c_uint32() + image_size_c.value = image_size + + factor_c = c_int32() + factor_c.value = factor + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + status = dll.DxSaturation(input_address_p, output_address_p, image_size_c, factor_c) + return status + + +if hasattr(dll, "DxAutoRawDefectivePixelCorrect"): + def dx_auto_raw_defective_pixel_correct(inout_address, width, height, bit_num): + """ + :brief Auto raw defective pixel correct,Support image from Raw8 to Raw16, the bit number is actual + bit number, when it is more than 8, the actual bit can be every number between 9 to 16. + And if image format is packed, you need convert it to Raw16. + This function should be used in each frame. + :param inout_address: input & output buffer address + :param width: image width + :param height: image height + :param bit_num: image bit number (for example:if image 10bit, nBitNum = 10, + if image 12bit, nBitNum = 12, + range:8 ~ 16) + :return: status: State return value, See detail in DxStatus + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + bit_num_c = c_int32() + bit_num_c.value = bit_num + + inout_address_p = c_void_p() + inout_address_p.value = inout_address + + status = dll.DxAutoRawDefectivePixelCorrect(inout_address_p, width_c, height_c, bit_num_c) + return status + + +if hasattr(dll, "DxSharpen24B"): + def dx_sharpen_24b(input_address, output_address, width, height, factor): + """ + :brief Sharpen adjustment (RGB24) + :param input_address: input buffer address, buff size = width * height * 3 + :param output_address: output buffer address, buff size = width * height * 3 + :param width: image width + :param height: image height + :param factor: sharpen factor, range(0.1~5.0) + :return: status: State return value, See detail in DxStatus + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + factor_c = c_float() + factor_c.value = factor + + status = dll.DxSharpen24B(input_address_p, output_address_p, width_c, height_c, factor_c) + return status + + +if hasattr(dll, "DxGetWhiteBalanceRatio"): + def dx_get_white_balance_ratio(input_address, width, height): + """ + :brief Get white balance ratios(RGB24), In order to calculate accurately, the camera should + shoot objective "white" area,or input image is white area. + :param input_address: input buffer address, buff size = width * height * 3 + :param width: image width + :param height: image height + :return: status: State return value, See detail in DxStatus + (r_ratio, g_ratio, b_ratio): rgb ratio tuple + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + input_address_p = c_void_p() + input_address_p.value = input_address + + r_ratio_c = c_double() + r_ratio_c.value = 0 + + g_ratio_c = c_double() + g_ratio_c.value = 0 + + b_ratio_c = c_double() + b_ratio_c.value = 0 + + status = dll.DxGetWhiteBalanceRatio(input_address_p, width_c, height_c, byref(r_ratio_c), + byref(g_ratio_c), byref(b_ratio_c)) + + return status, (r_ratio_c.value, g_ratio_c.value, b_ratio_c.value) + + +if hasattr(dll, "DxImageMirror"): + def dx_image_mirror(input_address, output_address, width, height, mirror_mode): + """ + :brief image mirror(raw8) + :param input_address: input buffer address + :param output_address: output buffer address + :param width: image width + :param height: image height + :param mirror_mode: mirror mode + :return: status: State return value, See detail in DxStatus + """ + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + mirror_mode_c = c_uint() + mirror_mode_c.value = mirror_mode + + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + status = dll.DxImageMirror(input_address_p, output_address_p, width_c, height_c, mirror_mode_c) + + return status + + +''' +if hasattr(dll, "DxRaw8ImgProcess"): + def dx_raw8_image_process(input_address, output_address, width, height, color_img_process_param): + """ + :brief Raw8 image process + :param input_address: input buffer address, buff size = width * height + :param output_address: output buffer address, buff size = width * height * 3 + :param width: image width + :param height: image height + :param color_img_process_param: Raw8 image process param, refer to DxColorImgProcess + """ + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + color_img_process_param_c = ColorImgProcess() + color_img_process_param_c.defective_pixel_correct = color_img_process_param.defective_pixel_correct + color_img_process_param_c.denoise = color_img_process_param.denoise + color_img_process_param_c.sharpness = color_img_process_param.sharpness + color_img_process_param_c.accelerate = color_img_process_param.accelerate + if color_img_process_param.cc_param is None: + color_img_process_param_c.arr_cc = None + color_img_process_param_c.cc_buf_length = 0 + else: + color_img_process_param_c.arr_cc = addressof(color_img_process_param.cc_param.get_ctype_array()) + color_img_process_param_c.cc_buf_length = color_img_process_param.cc_param.get_length() + color_img_process_param_c.sharp_factor = color_img_process_param.sharp_factor + if color_img_process_param.pro_lut is None: + color_img_process_param_c.pro_lut = None + color_img_process_param_c.lut_length = 0 + else: + color_img_process_param_c.pro_lut = addressof(color_img_process_param.pro_lut.get_ctype_array()) + color_img_process_param_c.lut_length = color_img_process_param.pro_lut.get_length() + color_img_process_param_c.cv_type = color_img_process_param.convert_type + color_img_process_param_c.layout = color_img_process_param.color_filter_layout + color_img_process_param_c.flip = color_img_process_param.flip + + status = dll.DxRaw8ImgProcess(input_address_p, output_address_p, width_c, + height_c, byref(color_img_process_param_c)) + + return status + + +if hasattr(dll, "DxMono8ImgProcess"): + def dx_mono8_image_process(input_address, output_address, width, height, mono_img_process_param): + """ + :brief mono8 image process + :param input_address: input buffer address, buff size = width * height + :param output_address: output buffer address, buff size = width * height + :param width: image width + :param height: image height + :param mono_img_process_param: mono8 image process param, refer to DxMonoImgProcess + """ + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + mono_img_process_param_c = MonoImgProcess() + mono_img_process_param_c.defective_pixel_correct = mono_img_process_param.defective_pixel_correct + mono_img_process_param_c.sharpness = mono_img_process_param.sharpness + mono_img_process_param_c.accelerate = mono_img_process_param.accelerate + mono_img_process_param_c.sharp_factor = mono_img_process_param.sharp_factor + if mono_img_process_param.pro_lut is None: + mono_img_process_param_c.pro_lut = None + mono_img_process_param_c.lut_length = 0 + else: + mono_img_process_param_c.pro_lut = addressof(mono_img_process_param.pro_lut.get_ctype_array()) + mono_img_process_param_c.lut_length = mono_img_process_param.pro_lut.get_length() + + status = dll.DxMono8ImgProcess(input_address_p, output_address_p, width_c, + height_c, byref(mono_img_process_param_c)) + + return status +''' + + +if hasattr(dll, 'DxGetFFCCoefficients'): + def dx_get_ffc_coefficients(bright_img, dark_img, actual_bits, bayer_type, width, height, target_value): + """ + :brief Get Flat Field Correction Coefficients + (only support raw8 raw10 raw12) + :param bright_img: bright image + :param dark_img: dark image + :param actual_bits: image actual bits + :param bayer_type: bayer type + :param width: image width + :param height: image height + :param target_value: correction target Value + :return status: State return value, See detail in DxStatus + ffc_coefficients: flat field correction coefficients Buffer + ffc_coefficients_length: flat field correction coefficients Buffer length + """ + field_correction_process_c = FieldCorrectionProcess() + field_correction_process_c.bright_buf = bright_img + field_correction_process_c.dark_buf = dark_img + field_correction_process_c.width = width + field_correction_process_c.height = height + field_correction_process_c.actual_bits = actual_bits + field_correction_process_c.bayer_type = bayer_type + + ffc_coefficients_len_c = c_int() + ffc_coefficients_len_c.value = 0 + + if target_value is None: + # Get length of ffc coefficients + dll.DxGetFFCCoefficients(field_correction_process_c, None, byref(ffc_coefficients_len_c), None) + + # Create buff to get coefficients data + ffc_coefficients_c = (c_ubyte * ffc_coefficients_len_c.value)() + status = dll.DxGetFFCCoefficients(field_correction_process_c, byref(ffc_coefficients_c), + byref(ffc_coefficients_len_c), None) + else: + target_value_c = c_int() + target_value_c.value = target_value + + # Get length of ffc coefficients + dll.DxGetFFCCoefficients(field_correction_process_c, None, byref(ffc_coefficients_len_c), + byref(target_value_c)) + + # Create buff to get coefficients data + ffc_coefficients_c = (c_ubyte * ffc_coefficients_len_c.value)() + status = dll.DxGetFFCCoefficients(field_correction_process_c, byref(ffc_coefficients_c), + byref(ffc_coefficients_len_c), byref(target_value_c)) + + return status, ffc_coefficients_c, ffc_coefficients_len_c.value + + +if hasattr(dll, "DxFlatFieldCorrection"): + def dx_flat_field_correction(input_address, output_address, actual_bits, width, height, ffc_coefficients): + """ + :brief Flat Field Correction Process + :param input_address: input buffer address, buff size = width * height + :param output_address: output buffer address, buff size = width * height + :param actual_bits: image actual bits + :param width: image width + :param height: image height + :param ffc_coefficients: flat field correction coefficients Buffer + :return: status: State return value, See detail in DxStatus + """ + input_address_p = c_void_p() + input_address_p.value = input_address + + output_address_p = c_void_p() + output_address_p.value = output_address + + width_c = c_uint32() + width_c.value = width + + height_c = c_uint32() + height_c.value = height + + actual_bits_c = c_uint() + actual_bits_c.value = actual_bits + + ffc_coefficients_len_c = c_int() + ffc_coefficients_len_c.value = ffc_coefficients.get_length() + + status = dll.DxFlatFieldCorrection(input_address_p, output_address_p, actual_bits_c, width_c, height_c, + byref(ffc_coefficients.get_ctype_array()), byref(ffc_coefficients_len_c)) + + return status + + diff --git a/src/components/gxipy/gxiapi.py b/src/components/gxipy/gxiapi.py new file mode 100644 index 0000000..837df3d --- /dev/null +++ b/src/components/gxipy/gxiapi.py @@ -0,0 +1,2837 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- +# -*-mode:python ; tab-width:4 -*- ex:set tabstop=4 shiftwidth=4 expandtab: -*- + +import numpy +from gxwrapper import * +from dxwrapper import * +from gxidef import * +import types + +ERROR_SIZE = 1024 +PIXEL_BIT_MASK = 0x00ff0000 +COLOR_TRANSFORM_MATRIX_SIZE = 9 # 3*3 + +if sys.version_info.major > 2: + INT_TYPE = int +else: + INT_TYPE = (int, long) + + +class DeviceManager(object): + __instance_num = 0 + def __new__(cls, *args, **kw): + cls.__instance_num += 1 + status = gx_init_lib() + StatusProcessor.process(status, 'DeviceManager', 'init_lib') + return object.__new__(cls, *args) + + def __init__(self): + self.__device_num = 0 + self.__device_info_list = [] + + def __del__(self): + self.__class__.__instance_num -= 1 + if self.__class__.__instance_num <= 0: + status = gx_close_lib() + StatusProcessor.process(status, 'DeviceManager', 'close_lib') + + def __get_device_info_list(self, base_info, ip_info, num): + """ + :brief Convert GxDeviceBaseInfo and GxDeviceIPInfo to device info list + :param base_info: device base info list[GxDeviceBaseInfo] + :param ip_info: device ip info list[GxDeviceIPInfo] + :param num: device number + :return: device info list + """ + device_info_list = [] + for i in range(num): + device_info_list.append({ + 'index': i+1, + 'vendor_name': string_decoding(base_info[i].vendor_name), + 'model_name': string_decoding(base_info[i].model_name), + 'sn': string_decoding(base_info[i].serial_number), + 'display_name': string_decoding(base_info[i].display_name), + 'device_id': string_decoding(base_info[i].device_id), + 'user_id': string_decoding(base_info[i].user_id), + 'access_status': base_info[i].access_status, + 'device_class': base_info[i].device_class, + 'mac': string_decoding(ip_info[i].mac), + 'ip': string_decoding(ip_info[i].ip), + 'subnet_mask': string_decoding(ip_info[i].subnet_mask), + 'gateway': string_decoding(ip_info[i].gateway), + 'nic_mac': string_decoding(ip_info[i].nic_mac), + 'nic_ip': string_decoding(ip_info[i].nic_ip), + 'nic_subnet_mask': string_decoding(ip_info[i].nic_subnet_mask), + 'nic_gateWay': string_decoding(ip_info[i].nic_gateWay), + 'nic_description': string_decoding(ip_info[i].nic_description) + }) + + return device_info_list + + def __get_ip_info(self, base_info_list, dev_mum): + """ + :brief Get the network information + """ + + ip_info_list = [] + for i in range(dev_mum): + if base_info_list[i].device_class == GxDeviceClassList.GEV: + status, ip_info = gx_get_device_ip_info(i+1) + StatusProcessor.process(status, 'DeviceManager', '__get_ip_info') + ip_info_list.append(ip_info) + else: + ip_info_list.append(GxDeviceIPInfo()) + + return ip_info_list + + def update_device_list(self, timeout=200): + """ + :brief enumerate the same network segment devices + :param timeout: Enumeration timeout, range:[0, 0xFFFFFFFF] + :return: dev_num: device number + device_info_list: all device info list + """ + if not isinstance(timeout, INT_TYPE): + raise ParameterTypeError("DeviceManager.update_device_list: " + "Expected timeout type is int, not %s" % type(timeout)) + + if (timeout < 0) or (timeout > UNSIGNED_INT_MAX): + print("DeviceManager.update_device_list: " + "timeout out of bounds, timeout: minimum=0, maximum=%s" % hex(UNSIGNED_INT_MAX).__str__()) + return 0, None + + status, dev_num = gx_update_device_list(timeout) + StatusProcessor.process(status, 'DeviceManager', 'update_device_list') + + status, base_info_list = gx_get_all_device_base_info(dev_num) + StatusProcessor.process(status, 'DeviceManager', 'update_device_list') + + ip_info_list = self.__get_ip_info(base_info_list, dev_num) + self.__device_num = dev_num + self.__device_info_list = self.__get_device_info_list(base_info_list, ip_info_list, dev_num) + + return self.__device_num, self.__device_info_list + + def update_all_device_list(self, timeout=200): + """ + :brief Enumerate devices on different network segments + :param timeout: Enumeration timeout, range:[0, 0xFFFFFFFF] + :return: dev_num: device number + device_info_list: all device info list + """ + if not isinstance(timeout, INT_TYPE): + raise ParameterTypeError("DeviceManager.update_all_device_list: " + "Expected timeout type is int, not %s" % type(timeout)) + + if (timeout < 0) or (timeout > UNSIGNED_INT_MAX): + print("DeviceManager.update_all_device_list: " + "timeout out of bounds, timeout: minimum=0, maximum=%s" % hex(UNSIGNED_INT_MAX).__str__()) + return 0, None + + status, dev_num = gx_update_all_device_list(timeout) + StatusProcessor.process(status, 'DeviceManager', 'update_all_device_list') + + status, base_info_list = gx_get_all_device_base_info(dev_num) + StatusProcessor.process(status, 'DeviceManager', 'update_all_device_list') + + ip_info_list = self.__get_ip_info(base_info_list, dev_num) + self.__device_num = dev_num + self.__device_info_list = self.__get_device_info_list(base_info_list, ip_info_list, dev_num) + + return self.__device_num, self.__device_info_list + + def get_device_number(self): + """ + :brief Get device number + :return: device number + """ + return self.__device_num + + def get_device_info(self): + """ + :brief Get all device info + :return: info_dict: device info list + """ + return self.__device_info_list + + def open_device_by_index(self, index, access_mode=GxAccessMode.CONTROL): + """ + :brief open device by index + USB3 device return U3VDevice object + USB2 device return U2Device object + GEV device return GEVDevice object + :param index: device index must start from 1 + :param access_mode: the access of open device + :return: Device object + """ + if not isinstance(index, INT_TYPE): + raise ParameterTypeError("DeviceManager.open_device_by_index: " + "Expected index type is int, not %s" % type(index)) + + if not isinstance(access_mode, INT_TYPE): + raise ParameterTypeError("DeviceManager.open_device_by_index: " + "Expected access_mode type is int, not %s" % type(access_mode)) + + if index < 1: + print("DeviceManager.open_device_by_index: index must start from 1") + return None + elif index > UNSIGNED_INT_MAX: + print("DeviceManager.open_device_by_index: index maximum: %s" % hex(UNSIGNED_INT_MAX).__str__()) + return None + + access_mode_dict = dict((name, getattr(GxAccessMode, name)) for name in dir(GxAccessMode) if not name.startswith('__')) + if access_mode not in access_mode_dict.values(): + print("DeviceManager.open_device_by_index: " + "access_mode out of bounds, %s" % access_mode_dict.__str__()) + return None + + if self.__device_num < index: + # Re-update the device + self.update_device_list() + if self.__device_num < index: + raise NotFoundDevice("DeviceManager.open_device_by_index: invalid index") + + # open devices by index + open_param = GxOpenParam() + open_param.content = string_encoding(str(index)) + open_param.open_mode = GxOpenMode.INDEX + open_param.access_mode = access_mode + status, handle = gx_open_device(open_param) + StatusProcessor.process(status, 'DeviceManager', 'open_device_by_index') + + # get device class + device_class = self.__device_info_list[index-1]["device_class"] + + if device_class == GxDeviceClassList.U3V: + return U3VDevice(handle) + elif device_class == GxDeviceClassList.USB2: + return U2Device(handle) + elif device_class == GxDeviceClassList.GEV: + return GEVDevice(handle) + else: + raise NotFoundDevice("DeviceManager.open_device_by_index: Does not support this device type.") + + def __get_device_class_by_sn(self, sn): + """ + :brief: 1.find device by sn in self.__device_info_list + 2.return different objects according to device class + :param sn: device serial number + :return: device class + """ + for index in range(self.__device_num): + if self.__device_info_list[index]["sn"] == sn: + return self.__device_info_list[index]["device_class"] + + # don't find this id in device base info list + return -1 + + def open_device_by_sn(self, sn, access_mode=GxAccessMode.CONTROL): + """ + :brief open device by serial number(SN) + USB3 device return U3VDevice object + USB2 device return U2Device object + GEV device return GEVDevice object + :param sn: device serial number, type: str + :param access_mode: the mode of open device[GxAccessMode] + :return: Device object + """ + if not isinstance(sn, str): + raise ParameterTypeError("DeviceManager.open_device_by_sn: " + "Expected sn type is str, not %s" % type(sn)) + + if not isinstance(access_mode, INT_TYPE): + raise ParameterTypeError("DeviceManager.open_device_by_sn: " + "Expected access_mode type is int, not %s" % type(access_mode)) + + access_mode_dict = dict((name, getattr(GxAccessMode, name)) for name in dir(GxAccessMode) if not name.startswith('__')) + if access_mode not in access_mode_dict.values(): + print("DeviceManager.open_device_by_sn: " + "access_mode out of bounds, %s" % access_mode_dict.__str__()) + return None + + # get device class from self.__device_info_list + device_class = self.__get_device_class_by_sn(sn) + if device_class == -1: + # Re-update the device + self.update_device_list() + device_class = self.__get_device_class_by_sn(sn) + if device_class == -1: + # don't find this sn + raise NotFoundDevice("DeviceManager.open_device_by_sn: Not found device") + + # open devices by sn + open_param = GxOpenParam() + open_param.content = string_encoding(sn) + open_param.open_mode = GxOpenMode.SN + open_param.access_mode = access_mode + status, handle = gx_open_device(open_param) + StatusProcessor.process(status, 'DeviceManager', 'open_device_by_sn') + + if device_class == GxDeviceClassList.U3V: + return U3VDevice(handle) + elif device_class == GxDeviceClassList.USB2: + return U2Device(handle) + elif device_class == GxDeviceClassList.GEV: + return GEVDevice(handle) + else: + raise NotFoundDevice("DeviceManager.open_device_by_sn: Does not support this device type.") + + def __get_device_class_by_user_id(self, user_id): + """ + :brief: 1.find device according to sn in self.__device_info_list + 2.return different objects according to device class + :param user_id: user ID + :return: device class + """ + for index in range(self.__device_num): + if self.__device_info_list[index]["user_id"] == user_id: + return self.__device_info_list[index]["device_class"] + + # don't find this id in device base info list + return -1 + + def open_device_by_user_id(self, user_id, access_mode=GxAccessMode.CONTROL): + """ + :brief open device by user defined name + USB3 device return U3VDevice object + GEV device return GEVDevice object + :param user_id: user defined name, type:str + :param access_mode: the mode of open device[GxAccessMode] + :return: Device object + """ + if not isinstance(user_id, str): + raise ParameterTypeError("DeviceManager.open_device_by_user_id: " + "Expected user_id type is str, not %s" % type(user_id)) + elif user_id.__len__() == 0: + raise InvalidParameter("DeviceManager.open_device_by_user_id: Don't support user_id's length is 0") + + if not isinstance(access_mode, INT_TYPE): + raise ParameterTypeError("DeviceManager.open_device_by_user_id: " + "Expected access_mode type is int, not %s" % type(access_mode)) + + access_mode_dict = dict((name, getattr(GxAccessMode, name)) for name in dir(GxAccessMode) if not name.startswith('__')) + if access_mode not in access_mode_dict.values(): + print("DeviceManager.open_device_by_user_id: access_mode out of bounds, %s" % access_mode_dict.__str__()) + return None + + # get device class from self.__device_info_list + device_class = self.__get_device_class_by_user_id(user_id) + if device_class == -1: + # Re-update the device + self.update_device_list() + device_class = self.__get_device_class_by_user_id(user_id) + if device_class == -1: + # don't find this user_id + raise NotFoundDevice("DeviceManager.open_device_by_user_id: Not found device") + + # open device by user_id + open_param = GxOpenParam() + open_param.content = string_encoding(user_id) + open_param.open_mode = GxOpenMode.USER_ID + open_param.access_mode = access_mode + status, handle = gx_open_device(open_param) + StatusProcessor.process(status, 'DeviceManager', 'open_device_by_user_id') + + if device_class == GxDeviceClassList.U3V: + return U3VDevice(handle) + elif device_class == GxDeviceClassList.GEV: + return GEVDevice(handle) + else: + raise NotFoundDevice("DeviceManager.open_device_by_user_id: Does not support this device type.") + + def open_device_by_ip(self, ip, access_mode=GxAccessMode.CONTROL): + """ + :brief open device by device ip address + :param ip: device ip address, type:str + :param access_mode: the mode of open device[GxAccessMode] + :return: GEVDevice object + """ + if not isinstance(ip, str): + raise ParameterTypeError("DeviceManager.open_device_by_ip: " + "Expected ip type is str, not %s" % type(ip)) + + if not isinstance(access_mode, INT_TYPE): + raise ParameterTypeError("DeviceManager.open_device_by_ip: " + "Expected access_mode type is int, not %s" % type(access_mode)) + + access_mode_dict = dict((name, getattr(GxAccessMode, name)) for name in dir(GxAccessMode) if not name.startswith('__')) + if access_mode not in access_mode_dict.values(): + print("DeviceManager.open_device_by_ip: access_mode out of bounds, %s" % access_mode_dict.__str__()) + return None + + # open device by ip + open_param = GxOpenParam() + open_param.content = string_encoding(ip) + open_param.open_mode = GxOpenMode.IP + open_param.access_mode = access_mode + status, handle = gx_open_device(open_param) + StatusProcessor.process(status, 'DeviceManager', 'open_device_by_ip') + + return GEVDevice(handle) + + def open_device_by_mac(self, mac, access_mode=GxAccessMode.CONTROL): + """ + :brief open device by device mac address + :param mac: device mac address, type:str + :param access_mode: the mode of open device[GxAccessMode] + :return: GEVDevice object + """ + if not isinstance(mac, str): + raise ParameterTypeError("DeviceManager.open_device_by_mac: " + "Expected mac type is str, not %s" % type(mac)) + + if not isinstance(access_mode, INT_TYPE): + raise ParameterTypeError("DeviceManager.open_device_by_mac: " + "Expected access_mode type is int, not %s" % type(access_mode)) + + access_mode_dict = dict((name, getattr(GxAccessMode, name)) for name in dir(GxAccessMode) if not name.startswith('__')) + if access_mode not in access_mode_dict.values(): + print("DeviceManager.open_device_by_mac: access_mode out of bounds, %s" % access_mode_dict.__str__()) + return None + + # open device by ip + open_param = GxOpenParam() + open_param.content = string_encoding(mac) + open_param.open_mode = GxOpenMode.MAC + open_param.access_mode = access_mode + status, handle = gx_open_device(open_param) + StatusProcessor.process(status, 'DeviceManager', 'open_device_by_mac') + + return GEVDevice(handle) + + def gige_reset_device(self, mac_address, reset_device_mode): + """ + :brief Reconnection/Reset + :param mac_address: The MAC address of the device(str) + :param reset_device_mode: Reconnection mode, refer to GxResetDeviceModeEntry + :return: None + """ + _InterUtility.check_type(mac_address, str, "mac_address", "DeviceManager", "gige_reset_device") + _InterUtility.check_type(reset_device_mode, int, "reset_device_mode", "DeviceManager", "gige_reset_device") + status = gx_gige_reset_device(mac_address, reset_device_mode) + StatusProcessor.process(status, 'DeviceManager', 'gige_reset_device') + + +class Feature: + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + self.__handle = handle + self.__feature = feature + self.feature_name = self.get_name() + + def get_name(self): + """ + brief: Getting Feature Name + return: Success: feature name + Failed: convert feature ID to string + """ + status, name = gx_get_feature_name(self.__handle, self.__feature) + if status != GxStatusList.SUCCESS: + name = (hex(self.__feature)).__str__() + + return name + + def is_implemented(self): + """ + brief: Determining whether the feature is implemented + return: is_implemented + """ + status, is_implemented = gx_is_implemented(self.__handle, self.__feature) + if status == GxStatusList.SUCCESS: + return is_implemented + elif status == GxStatusList.INVALID_PARAMETER: + return False + else: + StatusProcessor.process(status, 'Feature', 'is_implemented') + + def is_readable(self): + """ + brief: Determining whether the feature is readable + return: is_readable + """ + implemented = self.is_implemented() + if not implemented: + return False + + status, is_readable = gx_is_readable(self.__handle, self.__feature) + StatusProcessor.process(status, 'Feature', 'is_readable') + return is_readable + + def is_writable(self): + """ + brief: Determining whether the feature is writable + return: is_writable + """ + implemented = self.is_implemented() + if not implemented: + return False + + status, is_writable = gx_is_writable(self.__handle, self.__feature) + StatusProcessor.process(status, 'Feature', 'is_writable') + return is_writable + + +class IntFeature(Feature): + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + Feature.__init__(self, handle, feature) + self.__handle = handle + self.__feature = feature + + def __range_dict(self, int_range): + """ + :brief Convert GxIntRange to dictionary + :param int_range: GxIntRange + :return: range_dicts + """ + range_dicts = { + "min": int_range.min, + "max": int_range.max, + "inc": int_range.inc + } + return range_dicts + + def get_range(self): + """ + :brief Getting integer range + :return: integer range dictionary + """ + implemented = self.is_implemented() + if not implemented: + print("%s.get_range is not support" % self.feature_name) + return None + + status, int_range = gx_get_int_range(self.__handle, self.__feature) + StatusProcessor.process(status, 'IntFeature', 'get_range') + return self.__range_dict(int_range) + + def get(self): + """ + :brief Getting integer value + :return: integer value + """ + readable = self.is_readable() + if not readable: + print("%s.get is not readable" % self.feature_name) + return None + + status, int_value = gx_get_int(self.__handle, self.__feature) + StatusProcessor.process(status, 'IntFeature', 'get') + return int_value + + def set(self, int_value): + """ + :brief Setting integer value + :param int_value + :return: None + """ + if not isinstance(int_value, INT_TYPE): + raise ParameterTypeError("IntFeature.set: " + "Expected int_value type is int, not %s" % type(int_value)) + + writeable = self.is_writable() + if not writeable: + print("%s.set: is not writeable" % self.feature_name) + return + + int_range = self.get_range() + check_ret = range_check(int_value, int_range["min"], int_range["max"], int_range["inc"]) + if not check_ret: + print("IntFeature.set: " + "int_value out of bounds, %s.range=[%d, %d, %d]" % + (self.feature_name, int_range["min"], int_range["max"], int_range["inc"])) + return + + status = gx_set_int(self.__handle, self.__feature, int_value) + StatusProcessor.process(status, 'IntFeature', 'set') + + +class FloatFeature(Feature): + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + Feature.__init__(self, handle, feature) + self.__handle = handle + self.__feature = feature + + def __range_dict(self, float_range): + """ + :brief Convert GxFloatRange to dictionary + :param float_range: GxFloatRange + :return: range_dicts + """ + range_dicts = { + "min": float_range.min, + "max": float_range.max, + "inc": float_range.inc, + "unit": string_decoding(float_range.unit), + "inc_is_valid": float_range.inc_is_valid + } + return range_dicts + + def get_range(self): + """ + :brief Getting float range + :return: float range dictionary + """ + implemented = self.is_implemented() + if not implemented: + print("%s.get_range is not support" % self.feature_name) + return None + + status, float_range = gx_get_float_range(self.__handle, self.__feature) + StatusProcessor.process(status, 'FloatFeature', 'get_range') + return self.__range_dict(float_range) + + def get(self): + """ + :brief Getting float value + :return: float value + """ + readable = self.is_readable() + if not readable: + print("%s.get: is not readable" % self.feature_name) + return None + + status, float_value = gx_get_float(self.__handle, self.__feature) + StatusProcessor.process(status, 'FloatFeature', 'get') + return float_value + + def set(self, float_value): + """ + :brief Setting float value + :param float_value + :return: None + """ + if not isinstance(float_value, (INT_TYPE, float)): + raise ParameterTypeError("FloatFeature.set: " + "Expected float_value type is float, not %s" % type(float_value)) + + writeable = self.is_writable() + if not writeable: + print("%s.set: is not writeable" % self.feature_name) + return + + float_range = self.get_range() + check_ret = range_check(float_value, float_range["min"], float_range["max"]) + if not check_ret: + print("FloatFeature.set: float_value out of bounds, %s.range=[%f, %f]" % + (self.feature_name, float_range["min"], float_range["max"])) + return + + status = gx_set_float(self.__handle, self.__feature, float_value) + StatusProcessor.process(status, 'FloatFeature', 'set') + + +class EnumFeature(Feature): + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + Feature.__init__(self, handle, feature) + self.__handle = handle + self.__feature = feature + + def get_range(self): + """ + :brief Getting range of Enum feature + :return: enum_dict: enum range dictionary + """ + implemented = self.is_implemented() + if not implemented: + print("%s.get_range: is not support" % self.feature_name) + return None + + status, enum_num = gx_get_enum_entry_nums(self.__handle, self.__feature) + StatusProcessor.process(status, 'EnumFeature', 'get_range') + + status, enum_list = gx_get_enum_description(self.__handle, self.__feature, enum_num) + StatusProcessor.process(status, 'EnumFeature', 'get_range') + + enum_dict = {} + for i in range(enum_num): + enum_dict[string_decoding(enum_list[i].symbolic)] = enum_list[i].value + + return enum_dict + + def get(self): + """ + :brief Getting value of Enum feature + :return: enum_value: enum value + enum_str: string for enum description + """ + readable = self.is_readable() + if not readable: + print("%s.get: is not readable" % self.feature_name) + return None, None + + status, enum_value = gx_get_enum(self.__handle, self.__feature) + StatusProcessor.process(status, 'EnumFeature', 'get') + + range_dict = self.get_range() + new_dicts = {v: k for k, v in range_dict.items()} + return enum_value, new_dicts[enum_value] + + def set(self, enum_value): + """ + :brief Setting enum value + :param enum_value + :return: None + """ + if not isinstance(enum_value, INT_TYPE): + raise ParameterTypeError("EnumFeature.set: " + "Expected enum_value type is int, not %s" % type(enum_value)) + + writeable = self.is_writable() + if not writeable: + print("%s.set: is not writeable" % self.feature_name) + return + + range_dict = self.get_range() + enum_value_list = range_dict.values() + if enum_value not in enum_value_list: + print("EnumFeature.set: enum_value out of bounds, %s.range:%s" % + (self.feature_name, range_dict.__str__())) + return + + status = gx_set_enum(self.__handle, self.__feature, enum_value) + StatusProcessor.process(status, 'EnumFeature', 'set') + + +class BoolFeature(Feature): + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + Feature.__init__(self, handle, feature) + self.__handle = handle + self.__feature = feature + + def get(self): + """ + :brief Getting bool value + :return: bool value[bool] + """ + readable = self.is_readable() + if not readable: + print("%s.get is not readable" % self.feature_name) + return None + + status, bool_value = gx_get_bool(self.__handle, self.__feature) + StatusProcessor.process(status, 'BoolFeature', 'get') + return bool_value + + def set(self, bool_value): + """ + :brief Setting bool value + :param bool_value[bool] + :return: None + """ + if not isinstance(bool_value, bool): + raise ParameterTypeError("BoolFeature.set: " + "Expected bool_value type is bool, not %s" % type(bool_value)) + + writeable = self.is_writable() + if not writeable: + print("%s.set: is not writeable" % self.feature_name) + return + + status = gx_set_bool(self.__handle, self.__feature, bool_value) + StatusProcessor.process(status, 'BoolFeature', 'set') + + +class StringFeature(Feature): + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + Feature.__init__(self, handle, feature) + self.__handle = handle + self.__feature = feature + + def get_string_max_length(self): + """ + :brief Getting the maximum length that string can set + :return: length: the maximum length that string can set + """ + implemented = self.is_implemented() + if not implemented: + print("%s.get_string_max_length is not support" % self.feature_name) + return None + + status, length = gx_get_string_max_length(self.__handle, self.__feature) + StatusProcessor.process(status, 'StringFeature', 'get_string_max_length') + return length + + def get(self): + """ + :brief Getting string value + :return: strings + """ + readable = self.is_readable() + if not readable: + print("%s.get is not readable" % self.feature_name) + return None + + status, strings = gx_get_string(self.__handle, self.__feature) + StatusProcessor.process(status, 'StringFeature', 'get') + return strings + + def set(self, input_string): + """ + :brief Setting string value + :param input_string[string] + :return: None + """ + if not isinstance(input_string, str): + raise ParameterTypeError("StringFeature.set: " + "Expected input_string type is str, not %s" % type(input_string)) + + writeable = self.is_writable() + if not writeable: + print("%s.set: is not writeable" % self.feature_name) + return + + max_length = self.get_string_max_length() + if input_string.__len__() > max_length: + print("StringFeature.set: " + "input_string length out of bounds, %s.length_max:%s" + % (self.feature_name, max_length)) + return + + status = gx_set_string(self.__handle, self.__feature, input_string) + StatusProcessor.process(status, 'StringFeature', 'set') + + +class BufferFeature(Feature): + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + Feature.__init__(self, handle, feature) + self.__handle = handle + self.__feature = feature + + def get_buffer_length(self): + """ + :brief Getting buffer length + :return: length: buffer length + """ + implemented = self.is_implemented() + if not implemented: + print("%s.get_buffer_length is not support" % self.feature_name) + return None + + status, length = gx_get_buffer_length(self.__handle, self.__feature) + StatusProcessor.process(status, 'BuffFeature', 'get_buffer_length') + return length + + def get_buffer(self): + """ + :brief Getting buffer data + :return: Buffer object + + """ + readable = self.is_readable() + if not readable: + print("%s.get_buffer is not readable" % self.feature_name) + return None + + status, buf = gx_get_buffer(self.__handle, self.__feature) + StatusProcessor.process(status, 'BuffFeature', 'get_buffer') + return Buffer(buf) + + def set_buffer(self, buf): + """ + :brief Setting buffer data + :param buf: Buffer object + :return: None + """ + if not isinstance(buf, Buffer): + raise ParameterTypeError("BuffFeature.set_buffer: " + "Expected buff type is Buffer, not %s" % type(buf)) + + writeable = self.is_writable() + if not writeable: + print("%s.set_buffer is not writeable" % self.feature_name) + return + + max_length = self.get_buffer_length() + if buf.get_length() > max_length: + print("BuffFeature.set_buffer: " + "buff length out of bounds, %s.length_max:%s" % (self.feature_name, max_length)) + return + + status = gx_set_buffer(self.__handle, self.__feature, + buf.get_ctype_array(), buf.get_length()) + StatusProcessor.process(status, 'BuffFeature', 'set_buffer') + + +class CommandFeature(Feature): + def __init__(self, handle, feature): + """ + :param handle: The handle of the device + :param feature: The feature code ID + """ + Feature.__init__(self, handle, feature) + self.__handle = handle + self.__feature = feature + + def send_command(self): + """ + :brief Sending command + :return: None + """ + implemented = self.is_implemented() + if not implemented: + print("%s.send_command is not support" % self.feature_name) + return + + status = gx_send_command(self.__handle, self.__feature) + StatusProcessor.process(status, 'CommandFeature', 'send_command') + + +class Buffer: + def __init__(self, data_array): + try: + addressof(data_array) + except TypeError: + error_msg = "Buffer.__init__: param is error type." + raise ParameterTypeError(error_msg) + + self.data_array = data_array + + @staticmethod + def from_file(file_name): + file_object = open(file_name, "rb") + file_string = file_object.read() + data_array = create_string_buffer(file_string) + file_object.close() + return Buffer(data_array) + + @staticmethod + def from_string(string_data): + data_array = create_string_buffer(string_data) + return Buffer(data_array) + + def get_data(self): + buff_p = c_void_p() + buff_p.value = addressof(self.data_array) + string_data = string_at(buff_p, len(self.data_array)) + return string_data + + def get_ctype_array(self): + return self.data_array + + def get_numpy_array(self): + numpy_array = numpy.array(self.data_array) + return numpy_array + + def get_length(self): + return len(self.data_array) + + +''' +class DxColorImgProcess: + def __init__(self): + self.defective_pixel_correct = False # bool + self.denoise = False # bool + self.sharpness = False # bool + self.accelerate = False # bool + self.cc_param = None # Buffer + self.sharp_factor = 0 # float + self.pro_lut = None # Buffer + self.convert_type = DxBayerConvertType.NEIGHBOUR # DxBayerConvertType + self.color_filter_layout = DxPixelColorFilter.RG # DxPixelColorFilter + self.flip = False # bool + + def check_param_type(self): + """ + :chief check param type + """ + _InterUtility.check_type(self.defective_pixel_correct, bool, "defective_pixel_correct", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.denoise, bool, "denoise", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.sharpness, bool, "sharpness", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.accelerate, bool, "accelerate", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.cc_param, (Buffer, type(None)), "cc_param", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.sharp_factor, (float, INT_TYPE), "sharp_factor", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.pro_lut, (Buffer, type(None)), "pro_lut", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.convert_type, INT_TYPE, "convert_type", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.color_filter_layout, INT_TYPE, "color_filter_layout", + "DxColorImgProcess", "check_param_type") + + _InterUtility.check_type(self.flip, bool, "flip", + "DxColorImgProcess", "check_param_type") + + +class DxMonoImgProcess: + def __init__(self): + self.defective_pixel_correct = False # bool + self.sharpness = False # bool + self.accelerate = False # bool + self.sharp_factor = 0 # float + self.pro_lut = None # Buffer + + def check_param_type(self): + """ + :chief check param type + """ + _InterUtility.check_type(self.defective_pixel_correct, bool, "defective_pixel_correct", + "DxMonoImgProcess", "check_param_type") + + _InterUtility.check_type(self.sharpness, bool, "sharpness", + "DxMonoImgProcess", "check_param_type") + + _InterUtility.check_type(self.accelerate, bool, "accelerate", + "DxMonoImgProcess", "check_param_type") + + _InterUtility.check_type(self.sharp_factor, (float, INT_TYPE), "sharp_factor", + "DxMonoImgProcess", "check_param_type") + + _InterUtility.check_type(self.pro_lut, (Buffer, type(None)), "pro_lut", + "DxMonoImgProcess", "check_param_type") +''' + + +class Device: + """ + The Camera class mainly encapsulates some common operations and function attributes, + which are the operations and properties usually found in the camera. + In addition, this class also encapsulates the common operations of some functions in the C interface, + such as SetInt, SetFloat, etc. Can not open to the user, so that when the subsequent addition of features, + Python interface does not upgrade, or only the definition of the control code can support new features + """ + + def __init__(self, handle): + self.__dev_handle = handle + self.data_stream = [] + + self.__c_offline_callback = OFF_LINE_CALL(self.__on_device_offline_callback) + self.__py_offline_callback = None + self.__offline_callback_handle = None + + # ---------------Device Information Section-------------------------- + self.DeviceVendorName = StringFeature(self.__dev_handle, GxFeatureID.STRING_DEVICE_VENDOR_NAME) + self.DeviceModelName = StringFeature(self.__dev_handle, GxFeatureID.STRING_DEVICE_MODEL_NAME) + self.DeviceFirmwareVersion = StringFeature(self.__dev_handle, GxFeatureID.STRING_DEVICE_FIRMWARE_VERSION) + self.DeviceVersion = StringFeature(self.__dev_handle, GxFeatureID.STRING_DEVICE_VERSION) + self.DeviceSerialNumber = StringFeature(self.__dev_handle, GxFeatureID.STRING_DEVICE_SERIAL_NUMBER) + self.FactorySettingVersion = StringFeature(self.__dev_handle, GxFeatureID.STRING_FACTORY_SETTING_VERSION) + self.DeviceUserID = StringFeature(self.__dev_handle, GxFeatureID.STRING_DEVICE_USER_ID) + self.DeviceLinkSelector = IntFeature(self.__dev_handle, GxFeatureID.INT_DEVICE_LINK_SELECTOR) + self.DeviceLinkThroughputLimitMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_DEVICE_LINK_THROUGHPUT_LIMIT_MODE) + self.DeviceLinkThroughputLimit = IntFeature(self.__dev_handle, GxFeatureID.INT_DEVICE_LINK_THROUGHPUT_LIMIT) + self.DeviceLinkCurrentThroughput = IntFeature(self.__dev_handle, GxFeatureID.INT_DEVICE_LINK_CURRENT_THROUGHPUT) + self.DeviceReset = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_DEVICE_RESET) + self.TimestampTickFrequency = IntFeature(self.__dev_handle, GxFeatureID.INT_TIMESTAMP_TICK_FREQUENCY) + self.TimestampLatch = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_TIMESTAMP_LATCH) + self.TimestampReset = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_TIMESTAMP_RESET) + self.TimestampLatchReset = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_TIMESTAMP_LATCH_RESET) + self.TimestampLatchValue = IntFeature(self.__dev_handle, GxFeatureID.INT_TIMESTAMP_LATCH_VALUE) + self.DevicePHYVersion = StringFeature(self.__dev_handle, GxFeatureID.STRING_DEVICE_PHY_VERSION) + self.DeviceTemperatureSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_DEVICE_TEMPERATURE_SELECTOR) + self.DeviceTemperature = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_DEVICE_TEMPERATURE) + + # ---------------ImageFormat Section-------------------------------- + self.SensorWidth = IntFeature(self.__dev_handle, GxFeatureID.INT_SENSOR_WIDTH) + self.SensorHeight = IntFeature(self.__dev_handle, GxFeatureID.INT_SENSOR_HEIGHT) + self.WidthMax = IntFeature(self.__dev_handle, GxFeatureID.INT_WIDTH_MAX) + self.HeightMax = IntFeature(self.__dev_handle, GxFeatureID.INT_HEIGHT_MAX) + self.OffsetX = IntFeature(self.__dev_handle, GxFeatureID.INT_OFFSET_X) + self.OffsetY = IntFeature(self.__dev_handle, GxFeatureID.INT_OFFSET_Y) + self.Width = IntFeature(self.__dev_handle, GxFeatureID.INT_WIDTH) + self.Height = IntFeature(self.__dev_handle, GxFeatureID.INT_HEIGHT) + self.BinningHorizontal = IntFeature(self.__dev_handle, GxFeatureID.INT_BINNING_HORIZONTAL) + self.BinningVertical = IntFeature(self.__dev_handle, GxFeatureID.INT_BINNING_VERTICAL) + self.DecimationHorizontal = IntFeature(self.__dev_handle, GxFeatureID.INT_DECIMATION_HORIZONTAL) + self.DecimationVertical = IntFeature(self.__dev_handle, GxFeatureID.INT_DECIMATION_VERTICAL) + self.PixelSize = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_PIXEL_SIZE) + self.PixelColorFilter = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_PIXEL_COLOR_FILTER) + self.PixelFormat = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_PIXEL_FORMAT) + self.ReverseX = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_REVERSE_X) + self.ReverseY = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_REVERSE_Y) + self.TestPattern = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TEST_PATTERN) + self.TestPatternGeneratorSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TEST_PATTERN_GENERATOR_SELECTOR) + self.RegionSendMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_REGION_SEND_MODE) + self.RegionMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_REGION_MODE) + self.RegionSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_REGION_SELECTOR) + self.CenterWidth = IntFeature(self.__dev_handle, GxFeatureID.INT_CENTER_WIDTH) + self.CenterHeight = IntFeature(self.__dev_handle, GxFeatureID.INT_CENTER_HEIGHT) + self.BinningHorizontalMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_BINNING_HORIZONTAL_MODE) + self.BinningVerticalMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_BINNING_VERTICAL_MODE) + self.SensorShutterMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_SENSOR_SHUTTER_MODE) + + # ---------------TransportLayer Section------------------------------- + self.PayloadSize = IntFeature(self.__dev_handle, GxFeatureID.INT_PAYLOAD_SIZE) + + # ---------------AcquisitionTrigger Section--------------------------- + self.AcquisitionMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_ACQUISITION_MODE) + self.AcquisitionStart = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_ACQUISITION_START) + self.AcquisitionStop = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_ACQUISITION_STOP) + self.TriggerMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TRIGGER_MODE) + self.TriggerSoftware = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_TRIGGER_SOFTWARE) + self.TriggerActivation = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TRIGGER_ACTIVATION) + self.ExposureTime = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_EXPOSURE_TIME) + self.ExposureAuto = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_EXPOSURE_AUTO) + self.TriggerFilterRaisingEdge = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_TRIGGER_FILTER_RAISING) + self.TriggerFilterFallingEdge = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_TRIGGER_FILTER_FALLING) + self.TriggerSource = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TRIGGER_SOURCE) + self.ExposureMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_EXPOSURE_MODE) + self.TriggerSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TRIGGER_SELECTOR) + self.TriggerDelay = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_TRIGGER_DELAY) + self.TransferControlMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TRANSFER_CONTROL_MODE) + self.TransferOperationMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TRANSFER_OPERATION_MODE) + self.TransferStart = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_TRANSFER_START) + self.TransferBlockCount = IntFeature(self.__dev_handle, GxFeatureID.INT_TRANSFER_BLOCK_COUNT) + self.FrameBufferOverwriteActive = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_FRAMESTORE_COVER_ACTIVE) + self.AcquisitionFrameRateMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_ACQUISITION_FRAME_RATE_MODE) + self.AcquisitionFrameRate = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_ACQUISITION_FRAME_RATE) + self.CurrentAcquisitionFrameRate = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_CURRENT_ACQUISITION_FRAME_RATE) + self.FixedPatternNoiseCorrectMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_FIXED_PATTERN_NOISE_CORRECT_MODE) + self.AcquisitionBurstFrameCount = IntFeature(self.__dev_handle, GxFeatureID.INT_ACQUISITION_BURST_FRAME_COUNT) + self.AcquisitionStatusSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_ACQUISITION_STATUS_SELECTOR) + self.AcquisitionStatus = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_ACQUISITION_STATUS) + self.ExposureDelay = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_EXPOSURE_DELAY) + self.ExposureOverlapTimeMax = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_EXPOSURE_OVERLAP_TIME_MAX) + self.ExposureTimeMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_EXPOSURE_TIME_MODE) + + # ----------------DigitalIO Section---------------------------------- + self.UserOutputSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_USER_OUTPUT_SELECTOR) + self.UserOutputValue = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_USER_OUTPUT_VALUE) + self.LineSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_LINE_SELECTOR) + self.LineMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_LINE_MODE) + self.LineInverter = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_LINE_INVERTER) + self.LineSource = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_LINE_SOURCE) + self.LineStatus = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_LINE_STATUS) + self.LineStatusAll = IntFeature(self.__dev_handle, GxFeatureID.INT_LINE_STATUS_ALL) + self.PulseWidth = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_PULSE_WIDTH) + + # ----------------AnalogControls Section---------------------------- + self.GainAuto = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_GAIN_AUTO) + self.GainSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_GAIN_SELECTOR) + self.BlackLevelAuto = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_BLACK_LEVEL_AUTO) + self.BlackLevelSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_BLACK_LEVEL_SELECTOR) + self.BalanceWhiteAuto = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_BALANCE_WHITE_AUTO) + self.BalanceRatioSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_BALANCE_RATIO_SELECTOR) + self.BalanceRatio = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_BALANCE_RATIO) + self.DeadPixelCorrect = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_DEAD_PIXEL_CORRECT) + self.Gain = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_GAIN) + self.BlackLevel = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_BLACK_LEVEL) + self.GammaEnable = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_GAMMA_ENABLE) + self.GammaMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_GAMMA_MODE) + self.Gamma = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_GAMMA) + self.DigitalShift = IntFeature(self.__dev_handle, GxFeatureID.INT_DIGITAL_SHIFT) + self.LightSourcePreset = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_LIGHT_SOURCE_PRESET) + + # ---------------CustomFeature Section------------------------------ + self.ExpectedGrayValue = IntFeature(self.__dev_handle, GxFeatureID.INT_GRAY_VALUE) + self.AAROIOffsetX = IntFeature(self.__dev_handle, GxFeatureID.INT_AAROI_OFFSETX) + self.AAROIOffsetY = IntFeature(self.__dev_handle, GxFeatureID.INT_AAROI_OFFSETY) + self.AAROIWidth = IntFeature(self.__dev_handle, GxFeatureID.INT_AAROI_WIDTH) + self.AAROIHeight = IntFeature(self.__dev_handle, GxFeatureID.INT_AAROI_HEIGHT) + self.AutoGainMin = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_AUTO_GAIN_MIN) + self.AutoGainMax = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_AUTO_GAIN_MAX) + self.AutoExposureTimeMin = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_AUTO_EXPOSURE_TIME_MIN) + self.AutoExposureTimeMax = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_AUTO_EXPOSURE_TIME_MAX) + self.ContrastParam = IntFeature(self.__dev_handle, GxFeatureID.INT_CONTRAST_PARAM) + self.GammaParam = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_GAMMA_PARAM) + self.ColorCorrectionParam = IntFeature(self.__dev_handle, GxFeatureID.INT_COLOR_CORRECTION_PARAM) + self.AWBLampHouse = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_AWB_LAMP_HOUSE) + self.AWBROIOffsetX = IntFeature(self.__dev_handle, GxFeatureID.INT_AWBROI_OFFSETX) + self.AWBROIOffsetY = IntFeature(self.__dev_handle, GxFeatureID.INT_AWBROI_OFFSETY) + self.AWBROIWidth = IntFeature(self.__dev_handle, GxFeatureID.INT_AWBROI_WIDTH) + self.AWBROIHeight = IntFeature(self.__dev_handle, GxFeatureID.INT_AWBROI_HEIGHT) + self.SharpnessMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_SHARPNESS_MODE) + self.Sharpness = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_SHARPNESS) + self.DataFieldSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_USER_DATA_FIELD_SELECTOR) + self.DataFieldValue = BufferFeature(self.__dev_handle, GxFeatureID.BUFFER_USER_DATA_FIELD_VALUE) + self.FlatFieldCorrection = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_FLAT_FIELD_CORRECTION) + self.NoiseReductionMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_NOISE_REDUCTION_MODE) + self.NoiseReduction = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_NOISE_REDUCTION) + self.FFCLoad = BufferFeature(self.__dev_handle, GxFeatureID.BUFFER_FFCLOAD) + self.FFCSave = BufferFeature(self.__dev_handle, GxFeatureID.BUFFER_FFCSAVE) + self.StaticDefectCorrection = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_STATIC_DEFECT_CORRECTION) + + # ---------------UserSetControl Section------------------------------- + self.UserSetSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_USER_SET_SELECTOR) + self.UserSetLoad = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_USER_SET_LOAD) + self.UserSetSave = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_USER_SET_SAVE) + self.UserSetDefault = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_USER_SET_DEFAULT) + + # ---------------Event Section---------------------------------------- + self.EventSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_EVENT_SELECTOR) + self.EventNotification = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_EVENT_NOTIFICATION) + self.EventExposureEnd = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_EXPOSURE_END) + self.EventExposureEndTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_EXPOSURE_END_TIMESTAMP) + self.EventExposureEndFrameID = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_EXPOSURE_END_FRAME_ID) + self.EventBlockDiscard = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_BLOCK_DISCARD) + self.EventBlockDiscardTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_BLOCK_DISCARD_TIMESTAMP) + self.EventOverrun = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_OVERRUN) + self.EventOverrunTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_OVERRUN_TIMESTAMP) + self.EventFrameStartOvertrigger = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAME_START_OVER_TRIGGER) + self.EventFrameStartOvertriggerTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAME_START_OVER_TRIGGER_TIMESTAMP) + self.EventBlockNotEmpty = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_BLOCK_NOT_EMPTY) + self.EventBlockNotEmptyTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_BLOCK_NOT_EMPTY_TIMESTAMP) + self.EventInternalError = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_INTERNAL_ERROR) + self.EventInternalErrorTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_INTERNAL_ERROR_TIMESTAMP) + self.EventFrameBurstStartOvertrigger = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMEBURSTSTART_OVERTRIGGER) + self.EventFrameBurstStartOvertriggerFrameID = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMEBURSTSTART_OVERTRIGGER_FRAMEID) + self.EventFrameBurstStartOvertriggerTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMEBURSTSTART_OVERTRIGGER_TIMESTAMP) + self.EventFrameStartWait = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMESTART_WAIT) + self.EventFrameStartWaitTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMESTART_WAIT_TIMESTAMP) + self.EventFrameBurstStartWait = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMEBURSTSTART_WAIT) + self.EventFrameBurstStartWaitTimestamp = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMEBURSTSTART_WAIT_TIMESTAMP) + self.EventBlockDiscardFrameID = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_BLOCK_DISCARD_FRAMEID) + self.EventFrameStartOvertriggerFrameID = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMESTART_OVERTRIGGER_FRAMEID) + self.EventBlockNotEmptyFrameID = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_BLOCK_NOT_EMPTY_FRAMEID) + self.EventFrameStartWaitFrameID = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMESTART_WAIT_FRAMEID) + self.EventFrameBurstStartWaitFrameID = IntFeature(self.__dev_handle, GxFeatureID.INT_EVENT_FRAMEBURSTSTART_WAIT_FRAMEID) + + # ---------------LUT Section------------------------------------------ + self.LUTSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_LUT_SELECTOR) + self.LUTValueAll = BufferFeature(self.__dev_handle, GxFeatureID.BUFFER_LUT_VALUE_ALL) + self.LUTEnable = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_LUT_ENABLE) + self.LUTIndex = IntFeature(self.__dev_handle, GxFeatureID.INT_LUT_INDEX) + self.LUTValue = IntFeature(self.__dev_handle, GxFeatureID.INT_LUT_VALUE) + + # ---------------ChunkData Section------------------------------------ + self.ChunkModeActive = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_CHUNK_MODE_ACTIVE) + self.ChunkSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_CHUNK_SELECTOR) + self.ChunkEnable = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_CHUNK_ENABLE) + + # ---------------Color Transformation Control------------------------- + self.ColorTransformationMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_COLOR_TRANSFORMATION_MODE) + self.ColorTransformationEnable = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_COLOR_TRANSFORMATION_ENABLE) + self.ColorTransformationValueSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_COLOR_TRANSFORMATION_VALUE_SELECTOR) + self.ColorTransformationValue = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_COLOR_TRANSFORMATION_VALUE) + self.SaturationMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_SATURATION_MODE) + self.Saturation = IntFeature(self.__dev_handle, GxFeatureID.INT_SATURATION) + + # ---------------CounterAndTimerControl Section----------------------- + self.TimerSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TIMER_SELECTOR) + self.TimerDuration = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_TIMER_DURATION) + self.TimerDelay = FloatFeature(self.__dev_handle, GxFeatureID.FLOAT_TIMER_DELAY) + self.TimerTriggerSource = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TIMER_TRIGGER_SOURCE) + self.CounterSelector = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_COUNTER_SELECTOR) + self.CounterEventSource = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_COUNTER_EVENT_SOURCE) + self.CounterResetSource = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_COUNTER_RESET_SOURCE) + self.CounterResetActivation = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_COUNTER_RESET_ACTIVATION) + self.CounterReset = CommandFeature(self.__dev_handle, GxFeatureID.COMMAND_COUNTER_RESET) + self.CounterTriggerSource = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_COUNTER_TRIGGER_SOURCE) + self.CounterDuration = IntFeature(self.__dev_handle, GxFeatureID.INT_COUNTER_DURATION) + self.TimerTriggerActivation = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TIMER_TRIGGER_ACTIVATION) + + # ---------------RemoveParameterLimitControl Section------------------ + self.RemoveParameterLimit = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_REMOVE_PARAMETER_LIMIT) + + def stream_on(self): + """ + :brief send start command, camera start transmission image data + :return: none + """ + status = gx_send_command(self.__dev_handle, GxFeatureID.COMMAND_ACQUISITION_START) + StatusProcessor.process(status, 'Device', 'stream_on') + + payload_size = self.PayloadSize.get() + self.data_stream[0].set_payload_size(payload_size) + self.data_stream[0].acquisition_flag = True + + def stream_off(self): + """ + :brief send stop command, camera stop transmission image data + :return: none + """ + self.data_stream[0].acquisition_flag = False + status = gx_send_command(self.__dev_handle, GxFeatureID.COMMAND_ACQUISITION_STOP) + StatusProcessor.process(status, 'Device', 'stream_off') + + def export_config_file(self, file_path): + """ + :brief Export the current configuration file + :param file_path: file path(type: str) + :return: none + """ + if not isinstance(file_path, str): + raise ParameterTypeError("Device.export_config_file: " + "Expected file_path type is str, not %s" % type(file_path)) + + status = gx_export_config_file(self.__dev_handle, file_path) + StatusProcessor.process(status, 'Device', 'export_config_file') + + def import_config_file(self, file_path, verify=False): + """ + :brief Imported configuration file + :param file_path: file path(type: str) + :param verify: If this value is true, all the imported values will be read out + and checked for consistency(type: bool) + :return: none + """ + if not isinstance(file_path, str): + raise ParameterTypeError("Device.import_config_file: " + "Expected file_path type is str, not %s" % type(file_path)) + + if not isinstance(verify, bool): + raise ParameterTypeError("Device.import_config_file: " + "Expected verify type is bool, not %s" % type(verify)) + + status = gx_import_config_file(self.__dev_handle, file_path, verify) + StatusProcessor.process(status, 'Device', 'import_config_file') + + def close_device(self): + """ + :brief close device, close device handle + :return: None + """ + status = gx_close_device(self.__dev_handle) + StatusProcessor.process(status, 'Device', 'close_device') + self.__dev_handle = None + self.__py_offline_callback = None + self.__offline_callback_handle = None + + def register_device_offline_callback(self, callback_func): + """ + :brief Register the device offline event callback function. + :param callback_func: callback function + :return: none + """ + if not isinstance(callback_func, types.FunctionType): + raise ParameterTypeError("Device.register_device_offline_callback: " + "Expected callback type is function not %s" % type(callback_func)) + + status, offline_callback_handle = gx_register_device_offline_callback\ + (self.__dev_handle, self.__c_offline_callback) + StatusProcessor.process(status, 'Device', 'register_device_offline_callback') + + # callback will not recorded when register callback failed. + self.__py_offline_callback = callback_func + self.__offline_callback_handle = offline_callback_handle + + def unregister_device_offline_callback(self): + """ + :brief Unregister the device offline event callback function. + :return: none + """ + status = gx_unregister_device_offline_callback(self.__dev_handle, self.__offline_callback_handle) + StatusProcessor.process(status, 'Device', 'unregister_device_offline_callback') + self.__py_offline_callback = None + self.__offline_callback_handle = None + + def __on_device_offline_callback(self, c_user_param): + """ + :brief Device offline event callback function with an unused c_void_p. + :return: none + """ + self.__py_offline_callback() + + def get_stream_channel_num(self): + """ + :brief Get the number of stream channels supported by the current device. + :return: the number of stream channels + """ + return len(self.data_stream) + + def read_remote_device_port(self, address, buff, size): + """ + :brief Read Remote Regesiter + :param address: The address of the register to be read(type: int) + :param bytearray: The data to be read from register(type: buffer) + :return: Read Remote Regesiter Data Buff + """ + if not isinstance(address, INT_TYPE): + raise ParameterTypeError("Device.read_remote_device_port: " + "Expected address type is int, not %s" % type(address)) + + if not isinstance(size, INT_TYPE): + raise ParameterTypeError("Device.read_remote_device_port: " + "Expected size type is int, not %s" % type(size)) + + status, read_result = gx_read_remote_device_port(self.__dev_handle, address, buff, size) + StatusProcessor.process(status, 'Device', 'read_remote_device_port') + + return status + + def write_remote_device_port(self, address, buf, size): + """ + :brief Write remote register + :param address: The address of the register to be written.(type: int) + :param bytearray: The data to be written from user.(type: buffer) + :return: none + """ + if not isinstance(address, INT_TYPE): + raise ParameterTypeError("Device.write_remote_device_port: " + "Expected address type is int, not %s" % type(address)) + + status, r_size = gx_write_remote_device_port(self.__dev_handle, address, buf, size) + StatusProcessor.process(status, 'Device', 'write_remote_device_port') + + +class GEVDevice(Device): + def __init__(self, handle): + self.__dev_handle = handle + Device.__init__(self, self.__dev_handle) + self.GevCurrentIPConfigurationLLA = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_GEV_CURRENT_IP_CONFIGURATION_LLA) + self.GevCurrentIPConfigurationDHCP = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_GEV_CURRENT_IP_CONFIGURATION_DHCP) + self.GevCurrentIPConfigurationPersistentIP = BoolFeature(self.__dev_handle, GxFeatureID.BOOL_GEV_CURRENT_IP_CONFIGURATION_PERSISTENT_IP) + self.EstimatedBandwidth = IntFeature(self.__dev_handle, GxFeatureID.INT_ESTIMATED_BANDWIDTH) + self.GevHeartbeatTimeout = IntFeature(self.__dev_handle, GxFeatureID.INT_GEV_HEARTBEAT_TIMEOUT) + self.GevSCPSPacketSize = IntFeature(self.__dev_handle, GxFeatureID.INT_GEV_PACKET_SIZE) + self.GevSCPD = IntFeature(self.__dev_handle, GxFeatureID.INT_GEV_PACKET_DELAY) + self.GevLinkSpeed = IntFeature(self.__dev_handle, GxFeatureID.INT_GEV_LINK_SPEED) + self.DeviceCommandTimeout = IntFeature(self.__dev_handle, GxFeatureID.INT_COMMAND_TIMEOUT) + self.DeviceCommandRetryCount = IntFeature(self.__dev_handle, GxFeatureID.INT_COMMAND_RETRY_COUNT) + self.data_stream.append(GEVDataStream(self.__dev_handle)) + + +class U3VDevice(Device): + """ + The U3VDevice class inherits from the Device class. In addition to inheriting the properties of the Device, + the U3V Device has special attributes such as bandwidth limitation, URBSetting, frame info, etc. + """ + def __init__(self, handle): + self.__dev_handle = handle + Device.__init__(self, self.__dev_handle) + self.data_stream.append(U3VDataStream(self.__dev_handle)) + + +class U2Device(Device): + """ + The U2Device class inherits from the Device class + """ + def __init__(self, handle): + self.__dev_handle = handle + Device.__init__(self, self.__dev_handle) + self.AcquisitionSpeedLevel = IntFeature(self.__dev_handle, GxFeatureID.INT_ACQUISITION_SPEED_LEVEL) + self.AcquisitionFrameCount = IntFeature(self.__dev_handle, GxFeatureID.INT_ACQUISITION_FRAME_COUNT) + self.TriggerSwitch = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_TRIGGER_SWITCH) + self.UserOutputMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_USER_OUTPUT_MODE) + self.StrobeSwitch = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_STROBE_SWITCH) + self.ADCLevel = IntFeature(self.__dev_handle, GxFeatureID.INT_ADC_LEVEL) + self.HBlanking = IntFeature(self.__dev_handle, GxFeatureID.INT_H_BLANKING) + self.VBlanking = IntFeature(self.__dev_handle, GxFeatureID.INT_V_BLANKING) + self.UserPassword = StringFeature(self.__dev_handle, GxFeatureID.STRING_USER_PASSWORD) + self.VerifyPassword = StringFeature(self.__dev_handle, GxFeatureID.STRING_VERIFY_PASSWORD) + self.UserData = BufferFeature(self.__dev_handle, GxFeatureID.BUFFER_USER_DATA) + self.AALightEnvironment = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_AA_LIGHT_ENVIRONMENT) + self.FrameInformation = BufferFeature(self.__dev_handle, GxFeatureID.BUFFER_FRAME_INFORMATION) + self.ImageGrayRaiseSwitch = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_IMAGE_GRAY_RAISE_SWITCH) + self.data_stream.append(DataStream(self.__dev_handle)) + + +class DataStream: + def __init__(self, handle): + self.__dev_handle = handle + + self.__c_capture_callback = CAP_CALL(self.__on_capture_callback) + self.__py_capture_callback = None + + self.StreamAnnouncedBufferCount = IntFeature(self.__dev_handle, GxFeatureID.INT_ANNOUNCED_BUFFER_COUNT) + self.StreamDeliveredFrameCount = IntFeature(self.__dev_handle, GxFeatureID.INT_DELIVERED_FRAME_COUNT) + self.StreamLostFrameCount = IntFeature(self.__dev_handle, GxFeatureID.INT_LOST_FRAME_COUNT) + self.StreamIncompleteFrameCount = IntFeature(self.__dev_handle, GxFeatureID.INT_INCOMPLETE_FRAME_COUNT) + self.StreamDeliveredPacketCount = IntFeature(self.__dev_handle, GxFeatureID.INT_DELIVERED_PACKET_COUNT) + self.StreamBufferHandlingMode = EnumFeature(self.__dev_handle, GxFeatureID.ENUM_STREAM_BUFFER_HANDLING_MODE) + self.payload_size = 0 + self.acquisition_flag = False + + def set_payload_size(self, payload_size): + self.payload_size = payload_size + + def set_acquisition_buffer_number(self, buf_num): + """ + :brief set the number of acquisition buffer + :param buf_num: the number of acquisition buffer, range:[1, 0xFFFFFFFF] + """ + if not isinstance(buf_num, INT_TYPE): + raise ParameterTypeError("DataStream.set_acquisition_buffer_number: " + "Expected buf_num type is int, not %s" % type(buf_num)) + + if (buf_num < 1) or (buf_num > UNSIGNED_LONG_LONG_MAX): + print("DataStream.set_acquisition_buffer_number:" + "buf_num out of bounds, minimum=1, maximum=%s" + % hex(UNSIGNED_LONG_LONG_MAX).__str__()) + return + + status = gx_set_acquisition_buffer_number(self.__dev_handle, buf_num) + StatusProcessor.process(status, 'DataStream', 'set_acquisition_buffer_number') + + def get_image(self, timeout=1000): + """ + :brief Get an image, get successfully create image class object + :param timeout: Acquisition timeout, range:[0, 0xFFFFFFFF] + :return: image object + """ + if not isinstance(timeout, INT_TYPE): + raise ParameterTypeError("DataStream.get_image: " + "Expected timeout type is int, not %s" % type(timeout)) + + if (timeout < 0) or (timeout > UNSIGNED_INT_MAX): + print("DataStream.get_image: " + "timeout out of bounds, minimum=0, maximum=%s" + % hex(UNSIGNED_INT_MAX).__str__()) + return None + + if self.acquisition_flag is False: + print("DataStream.get_image: Current data steam don't start acquisition") + return None + + frame_data = GxFrameData() + frame_data.image_size = self.payload_size + frame_data.image_buf = None + image = RawImage(frame_data) + + status = gx_get_image(self.__dev_handle, image.frame_data, timeout) + if status == GxStatusList.SUCCESS: + return image + elif status == GxStatusList.TIMEOUT: + return None + else: + StatusProcessor.process(status, 'DataStream', 'get_image') + return None + + def flush_queue(self): + status = gx_flush_queue(self.__dev_handle) + StatusProcessor.process(status, 'DataStream', 'flush_queue') + + def register_capture_callback(self, callback_func): + """ + :brief Register the capture event callback function. + :param callback_func: callback function + :return: none + """ + if not isinstance(callback_func, types.FunctionType): + raise ParameterTypeError("DataStream.register_capture_callback: " + "Expected callback type is function not %s" % type(callback_func)) + + status = gx_register_capture_callback(self.__dev_handle, self.__c_capture_callback) + StatusProcessor.process(status, 'DataStream', 'register_capture_callback') + + # callback will not recorded when register callback failed. + self.__py_capture_callback = callback_func + + def unregister_capture_callback(self): + """ + :brief Unregister the capture event callback function. + :return: none + """ + status = gx_unregister_capture_callback(self.__dev_handle) + StatusProcessor.process(status, 'DataStream', 'unregister_capture_callback') + self.__py_capture_callback = None + + def __on_capture_callback(self, capture_data): + """ + :brief Capture event callback function with capture date. + :return: none + """ + frame_data = GxFrameData() + frame_data.image_buf = capture_data.contents.image_buf + frame_data.width = capture_data.contents.width + frame_data.height = capture_data.contents.height + frame_data.pixel_format = capture_data.contents.pixel_format + frame_data.image_size = capture_data.contents.image_size + frame_data.frame_id = capture_data.contents.frame_id + frame_data.timestamp = capture_data.contents.timestamp + # frame_data.buf_id = capture_data.contents.buf_id + image = RawImage(frame_data) + self.__py_capture_callback(image) + + +class U3VDataStream(DataStream): + def __init__(self, handle): + self.__handle = handle + DataStream.__init__(self, self.__handle) + self.StreamTransferSize = IntFeature(self.__handle, GxFeatureID.INT_STREAM_TRANSFER_SIZE) + self.StreamTransferNumberUrb = IntFeature(self.__handle, GxFeatureID.INT_STREAM_TRANSFER_NUMBER_URB) + self.StopAcquisitionMode = EnumFeature(self.__handle, GxFeatureID.ENUM_STOP_ACQUISITION_MODE) + + +class GEVDataStream(DataStream): + def __init__(self, handle): + self.__handle = handle + DataStream.__init__(self, self.__handle) + self.StreamResendPacketCount = IntFeature(self.__handle, GxFeatureID.INT_RESEND_PACKET_COUNT) + self.StreamRescuedPacketCount = IntFeature(self.__handle, GxFeatureID.INT_RESCUED_PACKET_COUNT) + self.StreamResendCommandCount = IntFeature(self.__handle, GxFeatureID.INT_RESEND_COMMAND_COUNT) + self.StreamUnexpectedPacketCount = IntFeature(self.__handle, GxFeatureID.INT_UNEXPECTED_PACKET_COUNT) + self.MaxPacketCountInOneBlock = IntFeature(self.__handle, GxFeatureID.INT_MAX_PACKET_COUNT_IN_ONE_BLOCK) + self.MaxPacketCountInOneCommand = IntFeature(self.__handle, GxFeatureID.INT_MAX_PACKET_COUNT_IN_ONE_COMMAND) + self.ResendTimeout = IntFeature(self.__handle, GxFeatureID.INT_RESEND_TIMEOUT) + self.MaxWaitPacketCount = IntFeature(self.__handle, GxFeatureID.INT_MAX_WAIT_PACKET_COUNT) + self.ResendMode = EnumFeature(self.__handle, GxFeatureID.ENUM_RESEND_MODE) + self.StreamMissingBlockIDCount = IntFeature(self.__handle, GxFeatureID.INT_MISSING_BLOCK_ID_COUNT) + self.BlockTimeout = IntFeature(self.__handle, GxFeatureID.INT_BLOCK_TIMEOUT) + self.MaxNumQueueBuffer = IntFeature(self.__handle, GxFeatureID.INT_MAX_NUM_QUEUE_BUFFER) + self.PacketTimeout = IntFeature(self.__handle, GxFeatureID.INT_PACKET_TIMEOUT) + self.SocketBufferSize = IntFeature(self.__handle, GxFeatureID.INT_SOCKET_BUFFER_SIZE) + + +class UnexpectedError(Exception): + """ + brief: Unexpected error exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class NotFoundTL(Exception): + """ + brief: not found TL exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class NotFoundDevice(Exception): + """ + brief: not found device exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class OffLine(Exception): + """ + brief: device offline exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class InvalidParameter(Exception): + """ + brief: input invalid parameter exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class InvalidHandle(Exception): + """ + brief: invalid handle exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class InvalidCall(Exception): + """ + brief: invalid callback exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class InvalidAccess(Exception): + """ + brief: invalid access exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class NeedMoreBuffer(Exception): + """ + brief: need more buffer exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class FeatureTypeError(Exception): + """ + brief: feature id error exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class OutOfRange(Exception): + """ + brief: param out of range exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class NotInitApi(Exception): + """ + brief: not init api exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class Timeout(Exception): + """ + brief: timeout exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +class ParameterTypeError(Exception): + """ + brief: parameter type error exception + param: args exception description + return: none + """ + def __init__(self, args): + Exception.__init__(self, args) + + +def exception_deal(status, args): + """ + brief: deal with different exception + param: status function return value + param: args exception description + return: none + """ + if status == GxStatusList.ERROR: + raise UnexpectedError(args) + elif status == GxStatusList.NOT_FOUND_TL: + raise NotFoundTL(args) + elif status == GxStatusList.NOT_FOUND_DEVICE: + raise NotFoundDevice(args) + elif status == GxStatusList.OFFLINE: + raise OffLine(args) + elif status == GxStatusList.INVALID_PARAMETER: + raise InvalidParameter(args) + elif status == GxStatusList.INVALID_HANDLE: + raise InvalidHandle(args) + elif status == GxStatusList.INVALID_CALL: + raise InvalidCall(args) + elif status == GxStatusList.INVALID_ACCESS: + raise InvalidAccess(args) + elif status == GxStatusList.NEED_MORE_BUFFER: + raise NeedMoreBuffer(args) + elif status == GxStatusList.ERROR_TYPE: + raise FeatureTypeError(args) + elif status == GxStatusList.OUT_OF_RANGE: + raise OutOfRange(args) + elif status == GxStatusList.NOT_INIT_API: + raise NotInitApi(args) + elif status == GxStatusList.TIMEOUT: + raise Timeout(args) + elif status == GxStatusList.REPEAT_OPENED: + raise InvalidAccess(args) + else: + raise Exception(args) + + +class StatusProcessor: + def __init__(self): + pass + + @staticmethod + def process(status, class_name, function_name): + """ + :brief 1.Error code processing + 2.combine the class name and function name of the transmitted function into a string + 3.Throw an exception + :param status: function return value + :param class_name: class name + :param function_name: function name + :return: none + """ + if status != GxStatusList.SUCCESS: + ret, err_code, string = gx_get_last_error(ERROR_SIZE) + error_message = "%s.%s:%s" % (class_name, function_name, string) + exception_deal(status, error_message) + + @staticmethod + def printing(status, class_name, function_name): + """ + :brief 1.Error code processing + 2.combine the class name and function name of the transmitted function into a string and print it out + :param status: function return value + :param class_name: class name + :param function_name: function name + :return: none + """ + if status != GxStatusList.SUCCESS: + ret, err_code, string = gx_get_last_error(ERROR_SIZE) + error_message = "%s.%s:%s" % (class_name, function_name, string) + print(error_message) + + +class RGBImage: + def __init__(self, frame_data): + self.frame_data = frame_data + + if self.frame_data.image_buf is not None: + self.__image_array = string_at(self.frame_data.image_buf, self.frame_data.image_size) + else: + self.__image_array = (c_ubyte * self.frame_data.image_size)() + self.frame_data.image_buf = addressof(self.__image_array) + + def image_improvement(self, color_correction_param=0, contrast_lut=None, gamma_lut=None, channel_order=DxRGBChannelOrder.ORDER_RGB): + """ + :brief: Improve image quality of the object itself + :param color_correction_param: color correction param address + (get from Device.ColorCorrectionParam.get_int()) + :param contrast_lut: contrast lut + :param gamma_lut: gamma lut + :param channel_order RGB channel order of output image + :return: None + """ + if (color_correction_param == 0) and (contrast_lut is None) and (gamma_lut is None): + return + + if contrast_lut is None: + contrast_parameter = None + elif isinstance(contrast_lut, Buffer): + contrast_parameter = contrast_lut.get_ctype_array() + else: + raise ParameterTypeError("RGBImage.image_improvement: " + "Expected contrast_lut type is Buffer, not %s" % type(contrast_lut)) + + if gamma_lut is None: + gamma_parameter = None + elif isinstance(gamma_lut, Buffer): + gamma_parameter = gamma_lut.get_ctype_array() + else: + raise ParameterTypeError("RGBImage.image_improvement: " + "Expected gamma_lut type is Buffer, not %s" % type(gamma_lut)) + + if not isinstance(color_correction_param, INT_TYPE): + raise ParameterTypeError("RGBImage.image_improvement: " + "Expected color_correction_param type is int, not %s" % type(color_correction_param)) + + if not isinstance(channel_order, INT_TYPE): + raise ParameterTypeError("RGBImage.image_improvement: " + "Expected channel_order type is int, not %s" % type(channel_order)) + + status = dx_image_improvement_ex(self.frame_data.image_buf, self.frame_data.image_buf, + self.frame_data.width, self.frame_data.height, + color_correction_param, contrast_parameter, gamma_parameter, channel_order) + + if status != DxStatus.OK: + raise UnexpectedError("RGBImage.image_improvement: failed, error code:%s" % hex(status).__str__()) + + def brightness(self, factor): + """ + :brief Brightness adjustment (RGB24) + :factor: factor, range(-150 ~ 150) + :return: None + """ + if not isinstance(factor, INT_TYPE): + raise ParameterTypeError("RGBImage.brightness: " + "Expected factor type is int, not %s" % type(factor)) + + status = dx_brightness(self.frame_data.image_buf, self.frame_data.image_buf, self.frame_data.image_size, factor) + + if status != DxStatus.OK: + raise UnexpectedError("RGBImage.brightness: failed, error code:%s" % hex(status).__str__()) + + def contrast(self, factor): + """ + :brief Contrast adjustment (RGB24) + :factor: factor, range(-50 ~ 100) + :return: None + """ + if not isinstance(factor, INT_TYPE): + raise ParameterTypeError("RGBImage.contrast: " + "Expected factor type is int, not %s" % type(factor)) + + status = dx_contrast(self.frame_data.image_buf, self.frame_data.image_buf, self.frame_data.image_size, factor) + + if status != DxStatus.OK: + raise UnexpectedError("RGBImage.contrast: failed, error code:%s" % hex(status).__str__()) + + def saturation(self, factor): + """ + :brief Saturation adjustment (RGB24) + :param factor: saturation factor,range(0 ~ 128) + :return: RGBImage object + """ + if not isinstance(factor, INT_TYPE): + raise ParameterTypeError("RGBImage.saturation: " + "Expected factor type is int, not %s" % type(factor)) + + status = dx_saturation(self.frame_data.image_buf, self.frame_data.image_buf, + self.frame_data.width * self.frame_data.height, factor) + + if status != DxStatus.OK: + raise UnexpectedError("RGBImage.saturation: failed, error code:%s" % hex(status).__str__()) + + def sharpen(self, factor): + """ + :brief Sharpen adjustment (RGB24) + :param factor: sharpen factor, range(0.1 ~ 5.0) + :return: None + """ + if not isinstance(factor, (INT_TYPE, float)): + raise ParameterTypeError("RGBImage.sharpen: " + "Expected factor type is float, not %s" % type(factor)) + + status = dx_sharpen_24b(self.frame_data.image_buf, self.frame_data.image_buf, self.frame_data.width, + self.frame_data.height, factor) + + if status != DxStatus.OK: + raise UnexpectedError("RGBImage.sharpen: failed, error code:%s" % hex(status).__str__()) + + def get_white_balance_ratio(self): + """ + :brief Get white balance ratios(RGB24), In order to calculate accurately, the camera should shoot + objective "white" area,or input image is white area. + :return: rgb_ratio: (r_ratio, g_ratio, b_ratio) + """ + status, rgb_ratio = dx_get_white_balance_ratio(self.frame_data.image_buf, self.frame_data.width, self.frame_data.height) + + if status != DxStatus.OK: + raise UnexpectedError("RGBImage.get_white_balance_ratio: failed, error code:%s" % hex(status).__str__()) + + return rgb_ratio + + def get_numpy_array(self): + """ + :brief: Return data as a numpy.Array type with dimension Image.height * Image.width * 3 + :return: numpy.Array objects + """ + image_np = numpy.frombuffer(self.__image_array, dtype=numpy.ubyte).reshape(self.frame_data.height, self.frame_data.width, 3) + return image_np + + def get_image_size(self): + """ + :brief Get RGB data size + :return: size + """ + return self.frame_data.image_size + + +class RawImage: + def __init__(self, frame_data): + self.frame_data = frame_data + + if self.frame_data.image_buf is not None: + self.__image_array = string_at(self.frame_data.image_buf, self.frame_data.image_size) + else: + self.__image_array = (c_ubyte * self.frame_data.image_size)() + self.frame_data.image_buf = addressof(self.__image_array) + + + def __pixel_format_raw16_to_raw8(self, pixel_format): + """ + :brief convert raw16 to raw8, the pixel format need convert to 8bit bayer format + :param pixel_format(10bit, 12bit, 16bit) + :return: pixel_format(8bit) + """ + gr16_tup = (GxPixelFormatEntry.BAYER_GR10, GxPixelFormatEntry.BAYER_GR12, GxPixelFormatEntry.BAYER_GR16) + rg16_tup = (GxPixelFormatEntry.BAYER_RG10, GxPixelFormatEntry.BAYER_RG12, GxPixelFormatEntry.BAYER_RG16) + gb16_tup = (GxPixelFormatEntry.BAYER_GB10, GxPixelFormatEntry.BAYER_GB12, GxPixelFormatEntry.BAYER_GB16) + bg16_tup = (GxPixelFormatEntry.BAYER_BG10, GxPixelFormatEntry.BAYER_BG12, GxPixelFormatEntry.BAYER_BG16) + mono16_tup = (GxPixelFormatEntry.MONO10, GxPixelFormatEntry.MONO12, + GxPixelFormatEntry.MONO14, GxPixelFormatEntry.MONO16) + + if pixel_format in gr16_tup: + return GxPixelFormatEntry.BAYER_GR8 + elif pixel_format in rg16_tup: + return GxPixelFormatEntry.BAYER_RG8 + elif pixel_format in gb16_tup: + return GxPixelFormatEntry.BAYER_GB8 + elif pixel_format in bg16_tup: + return GxPixelFormatEntry.BAYER_BG8 + elif pixel_format in mono16_tup: + return GxPixelFormatEntry.MONO8 + else: + return -1 + + def __raw16_to_raw8(self, pixel_bit_depth, valid_bits): + """ + :brief convert raw16 to raw8 + :param pixel_bit_depth pixel bit depth + :param valid_bits: data valid digit[DxValidBit] + :return: RAWImage object + """ + if pixel_bit_depth == GxPixelSizeEntry.BPP10: + valid_bits = min(valid_bits, DxValidBit.BIT2_9) + elif pixel_bit_depth == GxPixelSizeEntry.BPP12: + valid_bits = min(valid_bits, DxValidBit.BIT4_11) + else: + print("RawImage.__dx_raw16_to_raw8: Only support 10bit and 12bit") + return None + + frame_data = GxFrameData() + frame_data.status = self.frame_data.status + frame_data.width = self.frame_data.width + frame_data.height = self.frame_data.height + frame_data.pixel_format = self.__pixel_format_raw16_to_raw8(self.frame_data.pixel_format) + frame_data.image_size = self.frame_data.width * self.frame_data.height + frame_data.frame_id = self.frame_data.frame_id + frame_data.timestamp = self.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + image_raw8 = RawImage(frame_data) + + status = dx_raw16_to_raw8(self.frame_data.image_buf, image_raw8.frame_data.image_buf, + self.frame_data.width, self.frame_data.height, valid_bits) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.convert: raw16 convert to raw8 failed, Error core: %s" + % hex(status).__str__()) + else: + return image_raw8 + + def __raw8_to_rgb(self, raw8_image, convert_type, pixel_color_filter, flip): + """ + :brief convert raw8 to RGB + :param raw8_image RAWImage object, bit depth is 8bit + :param convert_type: Bayer convert type, See detail in DxBayerConvertType + :param pixel_color_filter: pixel color filter, See detail in DxPixelColorFilter + :param flip: Output image flip flag + True: turn the image upside down + False: do not flip + :return: RAWImage object + """ + frame_data = GxFrameData() + frame_data.status = raw8_image.frame_data.status + frame_data.width = raw8_image.frame_data.width + frame_data.height = raw8_image.frame_data.height + frame_data.pixel_format = GxPixelFormatEntry.RGB8_PLANAR + frame_data.image_size = raw8_image.frame_data.width * raw8_image.frame_data.height * 3 + frame_data.frame_id = raw8_image.frame_data.frame_id + frame_data.timestamp = raw8_image.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + image_rgb = RGBImage(frame_data) + + status = dx_raw8_to_rgb24(raw8_image.frame_data.image_buf, image_rgb.frame_data.image_buf, + raw8_image.frame_data.width, raw8_image.frame_data.height, + convert_type, pixel_color_filter, flip) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.convert: failed, error code:%s" % hex(status).__str__()) + + return image_rgb + + def __raw8_to_rgb_ex(self, raw8_image, convert_type, pixel_color_filter, flip, channel_order): + """ + :brief convert raw8 to RGB with chosen RGB channel order + :param raw8_image RAWImage object, bit depth is 8bit + :param convert_type: Bayer convert type, See detail in DxBayerConvertType + :param pixel_color_filter: pixel color filter, See detail in DxPixelColorFilter + :param flip: Output image flip flag + True: turn the image upside down + False: do not flip + :param channel_order: RGB channel order of output image + :return: RAWImage object + """ + frame_data = GxFrameData() + frame_data.status = raw8_image.frame_data.status + frame_data.width = raw8_image.frame_data.width + frame_data.height = raw8_image.frame_data.height + frame_data.pixel_format = GxPixelFormatEntry.RGB8_PLANAR + frame_data.image_size = raw8_image.frame_data.width * raw8_image.frame_data.height * 3 + frame_data.frame_id = raw8_image.frame_data.frame_id + frame_data.timestamp = raw8_image.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + image_rgb = RGBImage(frame_data) + + status = dx_raw8_to_rgb24_ex(raw8_image.frame_data.image_buf, image_rgb.frame_data.image_buf, + raw8_image.frame_data.width, raw8_image.frame_data.height, + convert_type, pixel_color_filter, flip, channel_order) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.convert: failed, error code:%s" % hex(status).__str__()) + + return image_rgb + + def __raw8_pixel_format_rotate_90(self, pixel_format, direct): + """ + :brief Rotate pixel format by 90 or -90 degrees + :param pixel_format Image format + :param direct 90 or -90 + :return: success: rotated pixel format + failed: -1 + """ + if pixel_format & PIXEL_BIT_MASK != GX_PIXEL_8BIT: + print("__raw8_pixel_format_rotate_90.pixel_format only support raw8") + return -1 + + if direct != 90 and direct != -90: + print("__raw8_pixel_format_rotate_90.direct only support 90 or -90") + return -1 + + if pixel_format == GxPixelFormatEntry.MONO8: + return GxPixelFormatEntry.MONO8 + + if (pixel_format == GxPixelFormatEntry.BAYER_GR8 and direct == 90) or \ + (pixel_format == GxPixelFormatEntry.BAYER_GB8 and direct == -90): + return GxPixelFormatEntry.BAYER_BG8 + + if (pixel_format == GxPixelFormatEntry.BAYER_RG8 and direct == 90) or \ + (pixel_format == GxPixelFormatEntry.BAYER_BG8 and direct == -90): + return GxPixelFormatEntry.BAYER_GR8 + + if (pixel_format == GxPixelFormatEntry.BAYER_GB8 and direct == 90) or \ + (pixel_format == GxPixelFormatEntry.BAYER_GR8 and direct == -90): + return GxPixelFormatEntry.BAYER_RG8 + + if (pixel_format == GxPixelFormatEntry.BAYER_BG8 and direct == 90) or \ + (pixel_format == GxPixelFormatEntry.BAYER_RG8 and direct == -90): + return GxPixelFormatEntry.BAYER_GB8 + + return -1 + + def __raw8_pixel_format_mirror(self, pixel_format, mirror_mode): + """ + :brief Mirror pixel format + :param pixel_format: Image format + :param mirror_mode: DxImageMirrorMode + :return: success: mirror pixel format + failed: -1 + """ + if pixel_format & PIXEL_BIT_MASK != GX_PIXEL_8BIT: + print("__raw8_pixel_format_mirror.pixel_format only support raw8") + return -1 + + if mirror_mode not in (DxImageMirrorMode.VERTICAL_MIRROR, DxImageMirrorMode.HORIZONTAL_MIRROR): + print("mirror_mode only support VERTICAL_MIRROR or HORIZONTAL_MIRROR") + return -1 + + if pixel_format == GxPixelFormatEntry.MONO8: + return GxPixelFormatEntry.MONO8 + + if (pixel_format == GxPixelFormatEntry.BAYER_GR8 and mirror_mode == DxImageMirrorMode.HORIZONTAL_MIRROR) or \ + (pixel_format == GxPixelFormatEntry.BAYER_GB8 and mirror_mode == DxImageMirrorMode.VERTICAL_MIRROR): + return GxPixelFormatEntry.BAYER_RG8 + + if (pixel_format == GxPixelFormatEntry.BAYER_RG8 and mirror_mode == DxImageMirrorMode.HORIZONTAL_MIRROR) or \ + (pixel_format == GxPixelFormatEntry.BAYER_BG8 and mirror_mode == DxImageMirrorMode.VERTICAL_MIRROR): + return GxPixelFormatEntry.BAYER_GR8 + + if (pixel_format == GxPixelFormatEntry.BAYER_GB8 and mirror_mode == DxImageMirrorMode.HORIZONTAL_MIRROR) or \ + (pixel_format == GxPixelFormatEntry.BAYER_GR8 and mirror_mode == DxImageMirrorMode.VERTICAL_MIRROR): + return GxPixelFormatEntry.BAYER_BG8 + + if (pixel_format == GxPixelFormatEntry.BAYER_BG8 and mirror_mode == DxImageMirrorMode.HORIZONTAL_MIRROR) or \ + (pixel_format == GxPixelFormatEntry.BAYER_RG8 and mirror_mode == DxImageMirrorMode.VERTICAL_MIRROR): + return GxPixelFormatEntry.BAYER_GB8 + + return -1 + + def convert(self, mode, flip=False, valid_bits=DxValidBit.BIT4_11, + convert_type=DxBayerConvertType.NEIGHBOUR, channel_order=DxRGBChannelOrder.ORDER_RGB): + """ + :brief Image format convert + :param mode: "RAW8": convert raw16 RAWImage object to raw8 RAWImage object + "RGB": convert raw8 RAWImage object to RGBImage object + :param flip: Output image flip flag + True: turn the image upside down + False: do not flip + :param valid_bits: Data valid digit, See detail in DxValidBit, raw8 don't this param + :param convert_type: Bayer convert type, See detail in DxBayerConvertType + :param channel_order: RGB channel order of output image + :return: return image object according to mode parameter + """ + if self.frame_data.status != GxFrameStatusList.SUCCESS: + print("RawImage.convert: This is a incomplete image") + return None + + if not isinstance(flip, bool): + raise ParameterTypeError("RawImage.convert: " + "Expected flip type is bool, not %s" % type(flip)) + + if not isinstance(convert_type, INT_TYPE): + raise ParameterTypeError("RawImage.convert: " + "Expected convert_type type is int, not %s" % type(convert_type)) + + if not isinstance(channel_order, INT_TYPE): + raise ParameterTypeError("RawImage.convert: " + "Expected channel_order type is int, not %s" % type(channel_order)) + + if not isinstance(valid_bits, INT_TYPE): + raise ParameterTypeError("RawImage.convert: " + "Expected valid_bits type is int, not %s" % type(valid_bits)) + + if not isinstance(mode, str): + raise ParameterTypeError("RawImage.convert: " + "Expected mode type is str, not %s" % type(mode)) + + convert_type_dict = dict((name, getattr(DxBayerConvertType, name)) + for name in dir(DxBayerConvertType) if not name.startswith('__')) + if convert_type not in convert_type_dict.values(): + print("RawImage.convert: convert_type out of bounds, %s" % convert_type_dict.__str__()) + return None + + valid_bits_dict = dict((name, getattr(DxValidBit, name)) + for name in dir(DxValidBit) if not name.startswith('__')) + if valid_bits not in valid_bits_dict.values(): + print("RawImage.convert: valid_bits out of bounds, %s" % valid_bits_dict.__str__()) + return None + + pixel_bit_depth = _InterUtility.get_bit_depth(self.frame_data.pixel_format) + pixel_color_filter = _InterUtility.get_pixel_color_filter(self.frame_data.pixel_format) + + if pixel_bit_depth < GxPixelSizeEntry.BPP8 or \ + pixel_bit_depth > GxPixelSizeEntry.BPP12: + print("RawImage.convert: This pixel format is not support") + return None + + if mode == "RAW8": + if flip is True: + print('''RawImage.convert: mode="RAW8" don't support flip=True''') + return None + + if pixel_bit_depth in (GxPixelSizeEntry.BPP10, GxPixelSizeEntry.BPP12): + image_raw8 = self.__raw16_to_raw8(pixel_bit_depth, valid_bits) + return image_raw8 + else: + print('RawImage.convert: mode="RAW8" only support 10bit and 12bit') + elif mode == "RGB": + if pixel_bit_depth in (GxPixelSizeEntry.BPP10, GxPixelSizeEntry.BPP12): + image_raw8 = self.__raw16_to_raw8(pixel_bit_depth, valid_bits) + else: + image_raw8 = self + + return self.__raw8_to_rgb_ex(image_raw8, convert_type, pixel_color_filter, flip, channel_order) + else: + print('''RawImage.convert: mode="%s", isn't support''' % mode) + return None + + def defective_pixel_correct(self): + """ + :brief Auto raw defective pixel correct,Support image from Raw8 to Raw16, the bit number is actual + bit number, when it is more than 8, the actual bit can be every number between 9 to 16. + And if image format is packed, you need convert it to Raw16. + This function should be used in each frame. + :return: None + """ + pixel_bit_depth = _InterUtility.get_bit_depth(self.frame_data.pixel_format) + status = dx_auto_raw_defective_pixel_correct(self.frame_data.image_buf, self.frame_data.width, + self.frame_data.height, pixel_bit_depth) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.defective_pixel_correct: failed, error code:%s" % hex(status).__str__()) + + def raw8_rotate_90_cw(self): + """ + :brief To rotate the 8-bit image clockwise by 90 degrees + :return RAWImage object + """ + if self.frame_data.pixel_format & PIXEL_BIT_MASK != GX_PIXEL_8BIT: + raise InvalidParameter("RawImage.raw8_rotate_90_cw only support 8bit image") + + frame_data = GxFrameData() + frame_data.status = self.frame_data.status + frame_data.width = self.frame_data.height + frame_data.height = self.frame_data.width + frame_data.pixel_format = self.__raw8_pixel_format_rotate_90(self.frame_data.pixel_format, 90) + if frame_data.pixel_format == -1: + raise UnexpectedError("Rotate pixel format %s failed" % hex(self.frame_data.pixel_format).__str__()) + + frame_data.image_size = self.frame_data.image_size + frame_data.frame_id = self.frame_data.frame_id + frame_data.timestamp = self.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + rotate_image = RawImage(frame_data) + + status = dx_raw8_rotate_90_cw(self.frame_data.image_buf, rotate_image.frame_data.image_buf, + self.frame_data.width, self.frame_data.height) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.raw8_rotate_90_cw: failed, error code:%s" % hex(status).__str__()) + + return rotate_image + + def raw8_rotate_90_ccw(self): + """ + :brief To rotate the 8-bit image clockwise by -90 degrees + :return RAWImage object + """ + if self.frame_data.pixel_format & PIXEL_BIT_MASK != GX_PIXEL_8BIT: + raise InvalidParameter("RawImage.raw8_rotate_90_ccw only support 8bit image") + + frame_data = GxFrameData() + frame_data.status = self.frame_data.status + frame_data.width = self.frame_data.height + frame_data.height = self.frame_data.width + frame_data.pixel_format = self.__raw8_pixel_format_rotate_90(self.frame_data.pixel_format, -90) + if frame_data.pixel_format == -1: + raise UnexpectedError("Rotate pixel format %s failed" % hex(self.frame_data.pixel_format).__str__()) + + frame_data.image_size = self.frame_data.image_size + frame_data.frame_id = self.frame_data.frame_id + frame_data.timestamp = self.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + rotate_image = RawImage(frame_data) + + status = dx_raw8_rotate_90_ccw(self.frame_data.image_buf, rotate_image.frame_data.image_buf, + self.frame_data.width, self.frame_data.height) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.raw8_rotate_90_ccw: failed, error code:%s" % hex(status).__str__()) + + return rotate_image + + def brightness(self, factor): + """ + :brief Brightness adjustment (mono8) + :param factor: factor, range(-150 ~ 150) + :return: None + """ + if not isinstance(factor, INT_TYPE): + raise ParameterTypeError("RawImage.brightness: " + "Expected factor type is int, not %s" % type(factor)) + + if self.frame_data.pixel_format != GxPixelFormatEntry.MONO8: + raise InvalidParameter("RawImage.brightness only support mono8 image") + + status = dx_brightness(self.frame_data.image_buf, self.frame_data.image_buf, self.frame_data.image_size, factor) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.brightness: failed, error code:%s" % hex(status).__str__()) + + def contrast(self, factor): + """ + :brief Contrast adjustment (mono8) + :param factor: factor, range(-50 ~ 100) + :return: None + """ + if not isinstance(factor, INT_TYPE): + raise ParameterTypeError("RawImage.contrast: " + "Expected factor type is int, not %s" % type(factor)) + + if self.frame_data.pixel_format != GxPixelFormatEntry.MONO8: + raise InvalidParameter("RawImage.contrast only support mono8 image") + + status = dx_contrast(self.frame_data.image_buf, self.frame_data.image_buf, self.frame_data.image_size, factor) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.contrast: failed, error code:%s" % hex(status).__str__()) + + def mirror(self, mirror_mode): + """ + :brief Image mirror(Raw8 or 8bit image) + :param mirror_mode: mirror mode [reference DxImageMirrorMode] + :return RAWImage object + """ + if not isinstance(mirror_mode, INT_TYPE): + raise ParameterTypeError("RawImage.mirror: " + "Expected mirror_mode type is int, not %s" % type(mirror_mode)) + + if self.frame_data.pixel_format & PIXEL_BIT_MASK != GX_PIXEL_8BIT: + raise InvalidParameter("RawImage.mirror only support raw8 or mono8") + + frame_data = GxFrameData() + frame_data.status = self.frame_data.status + frame_data.width = self.frame_data.width + frame_data.height = self.frame_data.height + frame_data.pixel_format = self.__raw8_pixel_format_mirror(self.frame_data.pixel_format, mirror_mode) + if frame_data.pixel_format == -1: + raise UnexpectedError("Rotate pixel format %s failed" % hex(self.frame_data.pixel_format).__str__()) + + frame_data.image_size = self.frame_data.image_size + frame_data.frame_id = self.frame_data.frame_id + frame_data.timestamp = self.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + mirror_image = RawImage(frame_data) + + status = dx_image_mirror(self.frame_data.image_buf, mirror_image.frame_data.image_buf, self.frame_data.width, + self.frame_data.height, mirror_mode) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.mirror: failed, error code:%s" % hex(status).__str__()) + + return mirror_image + + ''' + def raw8_image_process(self, color_img_process_param): + """ + :brief Raw8 image process + :param color_img_process_param: image process param, refer to DxColorImgProcess + :return img_rgb + """ + if self.frame_data.pixel_format & PIXEL_BIT_MASK != GX_PIXEL_8BIT or \ + self.frame_data.pixel_format == GxPixelFormatEntry.MONO8: + raise ParameterTypeError("RawImage.raw8_image_process only support bayer raw8") + + if not isinstance(color_img_process_param, DxColorImgProcess): + raise ParameterTypeError("RawImage.raw8_image_process img_process_param must be DxColorImgProcess type") + + color_img_process_param.check_param_type() + + frame_data = GxFrameData() + frame_data.status = self.frame_data.status + frame_data.width = self.frame_data.width + frame_data.height = self.frame_data.height + frame_data.pixel_format = GxPixelFormatEntry.RGB8_PLANAR + frame_data.image_size = self.frame_data.image_size * 3 + frame_data.frame_id = self.frame_data.frame_id + frame_data.timestamp = self.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + image_rgb = RGBImage(frame_data) + + status = dx_raw8_image_process(self.frame_data.image_buf, image_rgb.frame_data.image_buf, + self.frame_data.width, self.frame_data.height, color_img_process_param) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.raw8_image_process: failed, error code:%s" % hex(status).__str__()) + + return image_rgb + + def mono8_image_process(self, mono_img_process_param): + """ + :brief mono8 image process + :param mono_img_process_param: image process param, refer to DxMonoImgProcess + :return img_mono + """ + if self.frame_data.pixel_format != GxPixelFormatEntry.MONO8: + raise ParameterTypeError("RawImage.mono8_image_process only support mono8") + + if not isinstance(mono_img_process_param, DxMonoImgProcess): + raise ParameterTypeError("RawImage.mono8_image_process img_process_param must be DxMonoImgProcess type") + + mono_img_process_param.check_param_type() + + frame_data = GxFrameData() + frame_data.status = self.frame_data.status + frame_data.width = self.frame_data.width + frame_data.height = self.frame_data.height + frame_data.pixel_format = self.frame_data.pixel_format + frame_data.image_size = self.frame_data.image_size + frame_data.frame_id = self.frame_data.frame_id + frame_data.timestamp = self.frame_data.timestamp + # frame_data.buf_id = self.frame_data.buf_id + frame_data.image_buf = None + image_mono = RawImage(frame_data) + + status = dx_mono8_image_process(self.frame_data.image_buf, image_mono.frame_data.image_buf, + self.frame_data.width, self.frame_data.height, mono_img_process_param) + + if status != DxStatus.OK: + raise UnexpectedError("RawImage.mono8_image_process: failed, error code:%s" % hex(status).__str__()) + + return image_mono + ''' + + def get_ffc_coefficients(self, dark_img=None, target_value=None): + """ + :brief Get Flat Field Correction Coefficients + (only support raw8 raw10 raw12) + :param dark_img: dark image, type should be RawImage + :param target_value: correction target Value + :return ffc_coefficients: flat field correction coefficients Buffer + """ + if dark_img is not None: + _InterUtility.check_type(dark_img, RawImage, "dark_img", "Utility", "get_ffc_coefficients") + + if target_value is not None: + _InterUtility.check_type(target_value, INT_TYPE, "target_value", "Utility", "get_ffc_coefficients") + + actual_bits = _InterUtility.get_bit_depth(self.frame_data.pixel_format) + if actual_bits not in (GxPixelSizeEntry.BPP8, GxPixelSizeEntry.BPP10, GxPixelSizeEntry.BPP12): + raise InvalidParameter("Utility.get_ffc_coefficients only support raw8, raw10, raw12") + + if dark_img is None: + status, ffc_coefficients, _ = dx_get_ffc_coefficients(self.frame_data.image_buf, + None, + actual_bits, + _InterUtility.get_pixel_color_filter( + self.frame_data.pixel_format), + self.frame_data.width, self.frame_data.height, + target_value) + else: + if self.frame_data.width != dark_img.get_width() or \ + self.frame_data.height != dark_img.get_height() or \ + self.frame_data.pixel_format != dark_img.get_pixel_format(): + raise InvalidParameter("Utility.get_ffc_coefficients, the width/height/format of raw image and dark " + "image is different") + + status, ffc_coefficients, _ = dx_get_ffc_coefficients(self.frame_data.image_buf, + dark_img.frame_data.image_buf, + actual_bits, + _InterUtility.get_pixel_color_filter( + self.frame_data.pixel_format), + self.frame_data.width, self.frame_data.height, + target_value) + + if status != DxStatus.OK: + raise UnexpectedError("Utility.get_ffc_coefficients failure, Error code:%s" % hex(status).__str__()) + + return Buffer(ffc_coefficients) + + def flat_field_correction(self, ffc_coefficients): + """ + :brief Flat Field Correction Process + :param ffc_coefficients: Flat field correction coefficients + :return: None + """ + actual_bits = _InterUtility.get_bit_depth(self.frame_data.pixel_format) + if actual_bits not in (GxPixelSizeEntry.BPP8, GxPixelSizeEntry.BPP10, GxPixelSizeEntry.BPP12): + raise InvalidParameter("Utility.get_ffc_coefficients only support raw8, raw10, raw12") + _InterUtility.check_type(ffc_coefficients, Buffer, "ffc_coefficients", "RawImage", "flat_field_correction") + status = dx_flat_field_correction(self.frame_data.image_buf, self.frame_data.image_buf, actual_bits, + self.frame_data.width, self.frame_data.height, ffc_coefficients) + if status != DxStatus.OK: + raise UnexpectedError("Utility.flat_field_correction failure, Error code:%s" % hex(status).__str__()) + + def get_numpy_array(self): + """ + :brief Return data as a numpy.Array type with dimension Image.height * Image.width + :return: numpy.Array objects + """ + if self.frame_data.status != GxFrameStatusList.SUCCESS: + print("RawImage.get_numpy_array: This is a incomplete image") + return None + + image_size = self.frame_data.width * self.frame_data.height + + if self.frame_data.pixel_format & PIXEL_BIT_MASK == GX_PIXEL_8BIT: + image_np = numpy.frombuffer(self.__image_array, dtype=numpy.ubyte, count=image_size).\ + reshape(self.frame_data.height, self.frame_data.width) + elif self.frame_data.pixel_format & PIXEL_BIT_MASK == GX_PIXEL_16BIT: + image_np = numpy.frombuffer(self.__image_array, dtype=numpy.uint16, count=image_size).\ + reshape(self.frame_data.height, self.frame_data.width) + else: + image_np = None + + return image_np + + def get_data(self): + """ + :brief get Raw data + :return: raw data[string] + """ + image_str = string_at(self.__image_array, self.frame_data.image_size) + return image_str + + def save_raw(self, file_path): + """ + :brief save raw data + :param file_path: file path + :return: None + """ + if not isinstance(file_path, str): + raise ParameterTypeError("RawImage.save_raw: " + "Expected file_path type is str, not %s" % type(file_path)) + + try: + fp = open(file_path, "wb") + fp.write(self.__image_array) + fp.close() + except Exception as error: + raise UnexpectedError("RawImage.save_raw:%s" % error) + + def get_status(self): + """ + :brief get raw data status + :return: status + """ + return self.frame_data.status + + def get_width(self): + """ + :brief get width of raw data + :return: width + """ + return self.frame_data.width + + def get_height(self): + """ + :brief get height of raw data + :return: + """ + return self.frame_data.height + + def get_pixel_format(self): + """ + :brief Get image pixel format + :return: pixel format + """ + return self.frame_data.pixel_format + + def get_image_size(self): + """ + :brief Get raw data size + :return: size + """ + return self.frame_data.image_size + + def get_frame_id(self): + """ + :brief Get frame id of raw data + :return: frame id + """ + return self.frame_data.frame_id + + def get_timestamp(self): + """ + :brief Get timestamp of raw data + :return: timestamp + """ + return self.frame_data.timestamp + + +class Utility: + def __init__(self): + pass + + @staticmethod + def get_gamma_lut(gamma=1): + """ + :brief Calculating gamma lookup table (RGB24) + :param gamma: gamma param,range(0.1 ~ 10) + :return: gamma_lut buffer + """ + if not (isinstance(gamma, (INT_TYPE, float))): + raise ParameterTypeError("Utility.get_gamma_lut: " + "Expected gamma type is float, not %s" % type(gamma)) + + if (gamma < GAMMA_MIN) or (gamma > GAMMA_MAX): + print("Utility.get_gamma_lut: gamma out of bounds, range:[0.1, 10.0]") + return None + + status, gamma_lut, gamma_lut_len = dx_get_gamma_lut(gamma) + if status != DxStatus.OK: + print("Utility.get_gamma_lut: get gamma lut failure, Error code:%s" % hex(status).__str__()) + return None + + return Buffer(gamma_lut) + + @staticmethod + def get_contrast_lut(contrast=0): + """ + :brief Calculating contrast lookup table (RGB24) + :param contrast: contrast param,range(-50 ~ 100) + :return: contrast_lut buffer + """ + if not (isinstance(contrast, INT_TYPE)): + raise ParameterTypeError("Utility.get_contrast_lut: " + "Expected contrast type is int, not %s" % type(contrast)) + + if (contrast < CONTRAST_MIN) or (contrast > CONTRAST_MAX): + print("Utility.get_contrast_lut: contrast out of bounds, range:[-50, 100]") + return None + + status, contrast_lut, contrast_lut_len = dx_get_contrast_lut(contrast) + if status != DxStatus.OK: + print("Utility.get_contrast_lut: get contrast lut failure, Error code:%s" % hex(status).__str__()) + return None + + return Buffer(contrast_lut) + + @staticmethod + def get_lut(contrast=0, gamma=1, lightness=0): + """ + :brief Calculating lookup table of 8bit image + :param contrast: contrast param, range(-50 ~ 100) + :param gamma: gamma param, range(0.1 ~ 10) + :param lightness: lightness param, range(-150 ~ 150) + :return: lut buffer + """ + if not (isinstance(contrast, INT_TYPE)): + raise ParameterTypeError("Utility.get_lut: " + "Expected contrast type is int, not %s" % type(contrast)) + + if not (isinstance(gamma, (INT_TYPE, float))): + raise ParameterTypeError("Utility.get_lut: " + "Expected gamma type is float, not %s" % type(gamma)) + + if not (isinstance(lightness, INT_TYPE)): + raise ParameterTypeError("Utility.get_lut: " + "Expected lightness type is int, not %s" % type(lightness)) + + status, lut, lut_length = dx_get_lut(contrast, gamma, lightness) + if status != DxStatus.OK: + print("Utility.get_lut: get lut failure, Error code:%s" % hex(status).__str__()) + return None + + return Buffer(lut) + + @staticmethod + def calc_cc_param(color_correction_param, saturation=64): + """ + :brief calculating array of image processing color adjustment + :param color_correction_param: color correction param address(get from camera) + :param saturation: saturation factor,Range(0~128) + :return: cc param buffer + """ + if not (isinstance(color_correction_param, INT_TYPE)): + raise ParameterTypeError("Utility.calc_cc_param: Expected color_correction_param " + "type is int, not %s" % type(color_correction_param)) + + if not (isinstance(saturation, INT_TYPE)): + raise ParameterTypeError("Utility.calc_cc_param: " + "Expected saturation type is int, not %s" % type(saturation)) + + status, cc_param = dx_calc_cc_param(color_correction_param, saturation) + if status != DxStatus.OK: + print("Utility.calc_cc_param: calc correction param failure, Error code:%s" % hex(status).__str__()) + return None + + return Buffer(cc_param) + + @staticmethod + def calc_user_set_cc_param(color_transform_factor, saturation=64): + """ + :brief calculating array of image processing color adjustment + :param color_transform_factor: color correction param address(user set), + type should be list or tuple, size = 3*3=9 + :param saturation: saturation factor,Range(0~128) + :return: cc param buffer + """ + _InterUtility.check_type(color_transform_factor, (list, tuple), "color_transform_factor", + "Utility", "calc_user_set_cc_param") + if len(color_transform_factor) != COLOR_TRANSFORM_MATRIX_SIZE: + raise InvalidParameter("Utility.calc_user_set_cc_param " + "color_transform_factor should be list or tuple, length = 9") + + status, cc_param = dx_calc_user_set_cc_param(color_transform_factor, saturation) + if status != DxStatus.OK: + print("Utility.calc_user_set_cc_param: calc correction param failure, " + "Error code:%s" % hex(status).__str__()) + return None + + return Buffer(cc_param) + + +class _InterUtility: + def __init__(self): + pass + + @staticmethod + def check_type(var, var_type, var_name="", class_name="", func_name=""): + """ + :chief check type + """ + if not isinstance(var, var_type): + if not isinstance(var_type, tuple): + raise ParameterTypeError("{} {}: Expected {} type is {}, not {}".format(class_name, + func_name, var_name, + var_type.__name__, + type(var).__name__)) + else: + type_name = "" + for i, name in enumerate(var_type): + type_name = type_name + name.__name__ + if i != len(var_type) - 1: + type_name = type_name + ", " + raise ParameterTypeError("{} {}: Expected {} type is ({}), not {}".format(class_name, + func_name, var_name, + type_name, + type(var).__name__)) + + @staticmethod + def get_pixel_color_filter(pixel_format): + """ + :brief Calculate pixel color filter based on pixel format + :param pixel_format + :return: pixel color filter + """ + gr_tup = (GxPixelFormatEntry.BAYER_GR8, GxPixelFormatEntry.BAYER_GR10, + GxPixelFormatEntry.BAYER_GR12, GxPixelFormatEntry.BAYER_GR16) + rg_tup = (GxPixelFormatEntry.BAYER_RG8, GxPixelFormatEntry.BAYER_RG10, + GxPixelFormatEntry.BAYER_RG12, GxPixelFormatEntry.BAYER_RG16) + gb_tup = (GxPixelFormatEntry.BAYER_GB8, GxPixelFormatEntry.BAYER_GB10, + GxPixelFormatEntry.BAYER_GB12, GxPixelFormatEntry.BAYER_GB16) + bg_tup = (GxPixelFormatEntry.BAYER_BG8, GxPixelFormatEntry.BAYER_BG10, + GxPixelFormatEntry.BAYER_BG12, GxPixelFormatEntry.BAYER_BG16) + mono_tup = (GxPixelFormatEntry.MONO8, GxPixelFormatEntry.MONO8_SIGNED, + GxPixelFormatEntry.MONO10, GxPixelFormatEntry.MONO12, + GxPixelFormatEntry.MONO14, GxPixelFormatEntry.MONO16) + + if pixel_format in gr_tup: + return DxPixelColorFilter.GR + elif pixel_format in rg_tup: + return DxPixelColorFilter.RG + elif pixel_format in gb_tup: + return DxPixelColorFilter.GB + elif pixel_format in bg_tup: + return DxPixelColorFilter.BG + elif pixel_format in mono_tup: + return DxPixelColorFilter.NONE + else: + return -1 + + @staticmethod + def get_bit_depth(pixel_format): + """ + :brief Calculate pixel depth based on pixel format + :param pixel_format + :return: pixel depth + """ + bpp10_tup = (GxPixelFormatEntry.MONO10, GxPixelFormatEntry.BAYER_GR10, GxPixelFormatEntry.BAYER_RG10, + GxPixelFormatEntry.BAYER_GB10, GxPixelFormatEntry.BAYER_BG10) + + bpp12_tup = (GxPixelFormatEntry.MONO12, GxPixelFormatEntry.BAYER_GR12, GxPixelFormatEntry.BAYER_RG12, + GxPixelFormatEntry.BAYER_GB12, GxPixelFormatEntry.BAYER_BG12) + + bpp16_tup = (GxPixelFormatEntry.MONO16, GxPixelFormatEntry.BAYER_GR16, GxPixelFormatEntry.BAYER_RG16, + GxPixelFormatEntry.BAYER_GB16, GxPixelFormatEntry.BAYER_BG16) + + if (pixel_format & PIXEL_BIT_MASK) == GX_PIXEL_8BIT: + return GxPixelSizeEntry.BPP8 + elif pixel_format in bpp10_tup: + return GxPixelSizeEntry.BPP10 + elif pixel_format in bpp12_tup: + return GxPixelSizeEntry.BPP12 + elif pixel_format == GxPixelFormatEntry.MONO14: + return GxPixelSizeEntry.BPP14 + elif pixel_format in bpp16_tup: + return GxPixelSizeEntry.BPP16 + elif (pixel_format & PIXEL_BIT_MASK) == GX_PIXEL_24BIT: + return GxPixelSizeEntry.BPP24 + elif (pixel_format & PIXEL_BIT_MASK) == GX_PIXEL_48BIT: + return GxPixelSizeEntry.BPP48 + else: + return -1 diff --git a/src/components/gxipy/gxidef.py b/src/components/gxipy/gxidef.py new file mode 100644 index 0000000..62a1ef4 --- /dev/null +++ b/src/components/gxipy/gxidef.py @@ -0,0 +1,654 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- +# -*-mode:python ; tab-width:4 -*- ex:set tabstop=4 shiftwidth=4 expandtab: -*- +# + +GAMMA_MIN = 0.1 +GAMMA_MAX = 10.0 +CONTRAST_MIN = -50 +CONTRAST_MAX = 100 +UNSIGNED_INT_MAX = 0xFFFFFFFF +UNSIGNED_LONG_LONG_MAX = 0xFFFFFFFFFFFFFFFF + + +# frame state code +class GxFrameStatusList: + SUCCESS = 0 # Normal frame + INCOMPLETE = -1 # Incomplete frame + INVALID_IMAGE_INFO = -2 # invalid image info + + def __init__(self): + pass + + +# Device type code +class GxDeviceClassList: + UNKNOWN = 0 # Unknown device type + USB2 = 1 # USB2.0 vision device + GEV = 2 # Gige vision device + U3V = 3 # USB3.0 vision device + SMART = 4 # Smart device + + def __init__(self): + pass + + +class GxAccessMode: + READONLY = 2 # Open the device in read-only mode + CONTROL = 3 # Open the device in controlled mode + EXCLUSIVE = 4 # Open the device in exclusive mode + + def __init__(self): + pass + + +class GxAccessStatus: + UNKNOWN = 0 # The device's current status is unknown + READWRITE = 1 # The device currently supports reading and writing + READONLY = 2 # The device currently only supports reading + NOACCESS = 3 # The device currently does neither support reading nor support writing + + def __init__(self): + pass + + +class GxIPConfigureModeList: + DHCP = 0x6 # Enable the DHCP mode to allocate the IP address by the DHCP server + LLA = 0x4 # Enable the LLA mode to allocate the IP addresses + STATIC_IP = 0x5 # Enable the static IP mode to configure the IP address + DEFAULT = 0x7 # Enable the default mode to configure the IP address + + def __init__(self): + pass + + +class GxDeviceTemperatureSelectorEntry: + SENSOR = 1 + MAINBOARD = 2 + + def __init__(self): + pass + + +class GxPixelSizeEntry: + BPP8 = 8 + BPP10 = 10 + BPP12 = 12 + BPP14 = 14 + BPP16 = 16 + BPP24 = 24 + BPP30 = 30 + BPP32 = 32 + BPP36 = 36 + BPP48 = 48 + BPP64 = 64 + + def __init__(self): + pass + + +class GxPixelColorFilterEntry: + NONE = 0 + BAYER_RG = 1 + BAYER_GB = 2 + BAYER_GR = 3 + BAYER_BG = 4 + + def __init__(self): + pass + + +GX_PIXEL_MONO = 0x01000000 +GX_PIXEL_COLOR = 0x02000000 +GX_PIXEL_8BIT = 0x00080000 +GX_PIXEL_10BIT = 0x000A0000 +GX_PIXEL_12BIT = 0x000C0000 +GX_PIXEL_16BIT = 0x00100000 +GX_PIXEL_24BIT = 0x00180000 +GX_PIXEL_30BIT = 0x001E0000 +GX_PIXEL_32BIT = 0x00200000 +GX_PIXEL_36BIT = 0x00240000 +GX_PIXEL_48BIT = 0x00300000 +GX_PIXEL_64BIT = 0x00400000 + + +class GxPixelFormatEntry: + UNDEFINED = 0 + MONO8 = (GX_PIXEL_MONO | GX_PIXEL_8BIT | 0x0001) # 0x1080001 + MONO8_SIGNED = (GX_PIXEL_MONO | GX_PIXEL_8BIT | 0x0002) # 0x1080002 + MONO10 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0003) # 0x1100003 + MONO12 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0005) # 0x1100005 + MONO14 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0025) # 0x1100025 + MONO16 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0007) # 0x1100007 + BAYER_GR8 = (GX_PIXEL_MONO | GX_PIXEL_8BIT | 0x0008) # 0x1080008 + BAYER_RG8 = (GX_PIXEL_MONO | GX_PIXEL_8BIT | 0x0009) # 0x1080009 + BAYER_GB8 = (GX_PIXEL_MONO | GX_PIXEL_8BIT | 0x000A) # 0x108000A + BAYER_BG8 = (GX_PIXEL_MONO | GX_PIXEL_8BIT | 0x000B) # 0x108000B + BAYER_GR10 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x000C) # 0x110000C + BAYER_RG10 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x000D) # 0x110000D + BAYER_GB10 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x000E) # 0x110000E + BAYER_BG10 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x000F) # 0x110000F + BAYER_GR12 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0010) # 0x1100010 + BAYER_RG12 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0011) # 0x1100011 + BAYER_GB12 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0012) # 0x1100012 + BAYER_BG12 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0013) # 0x1100013 + BAYER_GR16 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x002E) # 0x110002E + BAYER_RG16 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x002F) # 0x110002F + BAYER_GB16 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0030) # 0x1100030 + BAYER_BG16 = (GX_PIXEL_MONO | GX_PIXEL_16BIT | 0x0031) # 0x1100031 + RGB8_PLANAR = (GX_PIXEL_COLOR | GX_PIXEL_24BIT | 0x0021) # 0x2180021 + RGB10_PLANAR = (GX_PIXEL_COLOR | GX_PIXEL_48BIT | 0x0022) # 0x2300022 + RGB12_PLANAR = (GX_PIXEL_COLOR | GX_PIXEL_48BIT | 0x0023) # 0x2300023 + RGB16_PLANAR = (GX_PIXEL_COLOR | GX_PIXEL_48BIT | 0x0024) # 0x2300024 + + def __init__(self): + pass + + +class GxTestPatternEntry: + OFF = 0 + GRAY_FRAME_RAMP_MOVING = 1 + SLANT_LINE_MOVING = 2 + VERTICAL_LINE_MOVING = 3 + HORIZONTAL_LINE_MOVING = 4 + GREY_VERTICAL_RAMP = 5 + SLANT_LINE = 6 + + def __init__(self): + pass + + +class GxTestPatternGeneratorSelectorEntry: + SENSOR = 0 # Sensor test pattern + REGION0 = 1 # FPGA test pattern + + def __init__(self): + pass + + +class GxRegionSendModeEntry: + SINGLE_ROI = 0 + MULTI_ROI = 1 + + def __init__(self): + pass + + +class GxRegionSelectorEntry: + REGION0 = 0 + REGION1 = 1 + REGION2 = 2 + REGION3 = 3 + REGION4 = 4 + REGION5 = 5 + REGION6 = 6 + REGION7 = 7 + + def __init__(self): + pass + + +class GxBinningHorizontalModeEntry: + SUM = 0 + AVERAGE = 1 + + def __init__(self): + pass + + +class GxBinningVerticalModeEntry: + SUM = 0 + AVERAGE = 1 + + def __init__(self): + pass + + +class GxSensorShutterModeEntry: + GLOBAL = 0 # All pixels are exposed simultaneously with same exposure time + ROLLING = 1 # All pixels have the same exposure time, but exposure start at different time + GLOBALRESET = 2 # All pixels start exposure at same time, but exposure time are different + + def __init__(self): + pass + + +class GxAcquisitionModeEntry: + SINGLE_FRAME = 0 + MULITI_FRAME = 1 + CONTINUOUS = 2 + + def __init__(self): + pass + + +class GxTriggerActivationEntry: + FALLINGEDGE = 0 + RISINGEDGE = 1 + + def __init__(self): + pass + + +class GxTriggerSourceEntry: + SOFTWARE = 0 + LINE0 = 1 + LINE1 = 2 + LINE2 = 3 + LINE3 = 4 + COUNTER2END = 5 + + def __init__(self): + pass + + +class GxExposureModeEntry: + TIMED = 1 + TRIGGER_WIDTH = 2 + + def __init__(self): + pass + + +class GxTriggerSelectorEntry: + FRAME_START = 1 + FRAME_BURST_START = 2 + + def __init__(self): + pass + + +class GxTransferControlModeEntry: + BASIC = 0 + USER_CONTROLED = 1 + + def __init__(self): + pass + + +class GxTransferOperationModeEntry: + MULTI_BLOCK = 0 + + def __init__(self): + pass + + +class GxAcquisitionStatusSelectorEntry: + ACQUISITION_TRIGGER_WAIT = 0 + FRAME_TRIGGER_WAIT = 1 + + def __init__(self): + pass + + +class GxExposureTimeModeEntry: + ULTRASHORT = 0 + STANDARD = 1 + + def __init__(self): + pass + + +class GxUserOutputSelectorEntry: + OUTPUT0 = 1 + OUTPUT1 = 2 + OUTPUT2 = 4 + + def __init__(self): + pass + + +class GxUserOutputModeEntry: + STROBE = 0 + USER_DEFINED = 1 + + def __init__(self): + pass + + +class GxLineSelectorEntry: + LINE0 = 0 + LINE1 = 1 + LINE2 = 2 + LINE3 = 3 + LINE4 = 4 + LINE5 = 5 + LINE6 = 6 + LINE7 = 7 + LINE8 = 8 + LINE9 = 9 + LINE10 = 10 + LINE_STROBE = 11 + + def __init__(self): + pass + + +class GxLineModeEntry: + INPUT = 0 + OUTPUT = 1 + + def __init__(self): + pass + + +class GxLineSourceEntry: + OFF = 0 + STROBE = 1 + USER_OUTPUT0 = 2 + USER_OUTPUT1 = 3 + USER_OUTPUT2 = 4 + EXPOSURE_ACTIVE = 5 + FRAME_TRIGGER_WAIT = 6 + ACQUISITION_TRIGGER_WAIT = 7 + TIMER1_ACTIVE = 8 + USER_OUTPUT3 = 9 + USER_OUTPUT4 = 10 + USER_OUTPUT5 = 11 + USER_OUTPUT6 = 12 + + def __init__(self): + pass + + +class GxGainSelectorEntry: + ALL = 0 + RED = 1 + GREEN = 2 + BLUE = 3 + + def __init__(self): + pass + + +class GxBlackLevelSelectEntry: + ALL = 0 + RED = 1 + GREEN = 2 + BLUE = 3 + + def __init__(self): + pass + + +class GxBalanceRatioSelectorEntry: + RED = 0 + GREEN = 1 + BLUE = 2 + + def __init__(self): + pass + + +class GxGammaModeEntry: + SRGB = 0 + USER = 1 + + def __init__(self): + pass + + +class GxLightSourcePresetEntry: + OFF = 0 + CUSTOM = 1 + DAYLIGHT_6500K = 2 + DAYLIGHT_5000K = 3 + COOL_WHITE_FLUORESCENCE = 4 + INCA = 5 + + def __init__(self): + pass + + +class GxAALightEnvironmentEntry: + NATURE_LIGHT = 0 + AC50HZ = 1 + AC60HZ = 2 + + def __init__(self): + pass + + +class GxAWBLampHouseEntry: + ADAPTIVE = 0 + D65 = 1 + FLUORESCENCE = 2 + INCANDESCENT = 3 + D75 = 4 + D50 = 5 + U30 = 6 + + def __init__(self): + pass + + +class GxUserDataFieldSelectorEntry: + FIELD_0 = 0 + FIELD_1 = 1 + FIELD_2 = 2 + FIELD_3 = 3 + + def __init__(self): + pass + + +class GxUserSetEntry: + DEFAULT = 0 + USER_SET0 = 1 + + def __init__(self): + pass + + +class GxEventSelectorEntry: + EXPOSURE_END = 0x0004 + BLOCK_DISCARD = 0x9000 + EVENT_OVERRUN = 0x9001 + FRAME_START_OVER_TRIGGER = 0x9002 + BLOCK_NOT_EMPTY = 0x9003 + INTERNAL_ERROR = 0x9004 + FRAME_BURST_START_OVERTRIGGER = 0x9005 + FRAME_START_WAIT = 0x9006 + FRAME_BURST_START_WAIT = 0x9007 + + def __init__(self): + pass + + +class GxLutSelectorEntry: + LUMINANCE = 0 + + def __init__(self): + pass + + +class GxChunkSelectorEntry: + FRAME_ID = 1 + TIME_STAMP = 2 + COUNTER_VALUE = 3 + + def __init__(self): + pass + + +class GxColorTransformationModeEntry: + RGB_TO_RGB = 0 + USER = 1 + + def __init__(self): + pass + + +class GxColorTransformationValueSelectorEntry: + GAIN00 = 0 + GAIN01 = 1 + GAIN02 = 2 + GAIN10 = 3 + GAIN11 = 4 + GAIN12 = 5 + GAIN20 = 6 + GAIN21 = 7 + GAIN22 = 8 + + def __init__(self): + pass + + +class GxResetDeviceModeEntry: + RECONNECT = 1 + RESET = 2 + + def __init__(self): + pass + + +class GxTimerSelectorEntry: + TIMER1 = 1 + + def __init__(self): + pass + + +class GxTimerTriggerSourceEntry: + EXPOSURE_START = 1 + LINE10 = 10 + STROBE = 16 + + def __init__(self): + pass + + +class GxCounterSelectorEntry: + COUNTER1 = 1 + COUNTER2 = 2 + + def __init__(self): + pass + + +class GxCounterEventSourceEntry: + FRAME_START = 1 + FRAME_TRIGGER = 2 + ACQUISITION_TRIGGER = 3 + OFF = 4 + SOFTWARE = 5 + LINE0 = 6 + LINE1 = 7 + LINE2 = 8 + LINE3 = 9 + + def __init__(self): + pass + + +class GxCounterResetSourceEntry: + OFF = 0 + SOFTWARE = 1 + LINE0 = 2 + LINE1 = 3 + LINE2 = 4 + LINE3 = 5 + COUNTER2END = 6 + + def __init__(self): + pass + + +class GxCounterResetActivationEntry: + RISINGEDGE = 1 + + def __init__(self): + pass + + +class GxCounterTriggerSourceEntry: + OFF = 0 + SOFTWARE = 1 + LINE0 = 2 + LINE1 = 3 + LINE2 = 4 + LINE3 = 5 + + def __init__(self): + pass + + +class GxTimerTriggerActivationEntry: + RISINGEDGE = 0 + + def __init__(self): + pass + + +class GxStopAcquisitionModeEntry: + GENERAL = 0 + LIGHT = 1 + + def __init__(self): + pass + + +class GxDSStreamBufferHandlingModeEntry: + OLDEST_FIRST = 1 + OLDEST_FIRST_OVERWRITE = 2 + NEWEST_ONLY = 3 + + def __init__(self): + pass + + +class GxAutoEntry: + OFF = 0 + CONTINUOUS = 1 + ONCE = 2 + + def __init__(self): + pass + + +class GxSwitchEntry: + OFF = 0 + ON = 1 + + def __init__(self): + pass + + +# image interpolation method +class DxBayerConvertType: + NEIGHBOUR = 0 # Neighborhood average interpolation algorithm + ADAPTIVE = 1 # Edge adaptive interpolation algorithm + NEIGHBOUR3 = 2 # The neighborhood average interpolation algorithm for a larger region + + def __init__(self): + pass + + +# image valid bit +class DxValidBit: + BIT0_7 = 0 # bit 0~7 + BIT1_8 = 1 # bit 1~8 + BIT2_9 = 2 # bit 2~9 + BIT3_10 = 3 # bit 3~10 + BIT4_11 = 4 # bit 4~11 + + def __init__(self): + pass + + +# image mirror method +class DxImageMirrorMode: + HORIZONTAL_MIRROR = 0 # Horizontal mirror + VERTICAL_MIRROR = 1 # Vertical mirror + + def __init__(self): + pass + + +# RGB channel order +class DxRGBChannelOrder: + ORDER_RGB = 0 + ORDER_BGR = 1 + + def __init__(self): + pass diff --git a/src/components/gxipy/gxwrapper.py b/src/components/gxipy/gxwrapper.py new file mode 100644 index 0000000..291fa48 --- /dev/null +++ b/src/components/gxipy/gxwrapper.py @@ -0,0 +1,1795 @@ +#!/usr/bin/python +# -*-mode:python ; tab-width:4 -*- ex:set tabstop=4 shiftwidth=4 expandtab: -*- +# -*- coding:utf-8 -*- + +from ctypes import * +import sys + + +if sys.platform == 'linux2' or sys.platform == 'linux': + try: + dll = CDLL('/usr/lib/libgxiapi.so') + except OSError: + print("Cannot find libgxiapi.so.") +else: + try: + if (sys.version_info.major == 3 and sys.version_info.minor >= 8) or (sys.version_info.major > 3): + dll = WinDLL('GxIAPI.dll', winmode=0) + else: + dll = WinDLL('GxIAPI.dll') + except OSError: + print('Cannot find GxIAPI.dll.') + + +# Error code +class GxStatusList: + SUCCESS = 0 # Success + ERROR = -1 # There is a unspecified internal error that is not expected to occur + NOT_FOUND_TL = -2 # The TL library cannot be found + NOT_FOUND_DEVICE = -3 # The device is not found + OFFLINE = -4 # The current device is in a offline state + INVALID_PARAMETER = -5 # Invalid parameter, Generally the pointer is NULL or the input IP and + # Other parameter formats are invalid + INVALID_HANDLE = -6 # Invalid handle + INVALID_CALL = -7 # The interface is invalid, which refers to software interface logic error + INVALID_ACCESS = -8 # The function is currently inaccessible or the device access mode is incorrect + NEED_MORE_BUFFER = -9 # The user request buffer is insufficient: the user input buffersize during + # the read operation is less than the actual need + ERROR_TYPE = -10 # The type of FeatureID used by the user is incorrect, + # such as an integer interface using a floating-point function code + OUT_OF_RANGE = -11 # The value written by the user is crossed + NOT_IMPLEMENTED = -12 # This function is not currently supported + NOT_INIT_API = -13 # There is no call to initialize the interface + TIMEOUT = -14 # Timeout error + REPEAT_OPENED = -1004 # The device has been opened + + def __init__(self): + pass + + +class GxOpenMode: + SN = 0 # Opens the device via a serial number + IP = 1 # Opens the device via an IP address + MAC = 2 # Opens the device via a MAC address + INDEX = 3 # Opens the device via a serial number(Start from 1) + USER_ID = 4 # Opens the device via user defined ID + + def __init__(self): + pass + + +class GxFrameMask: + TYPE_MASK = 0xF0000000 + LEVEL_MASK = 0x0F000000 + + def __init__(self): + pass + + +class GxFeatureType: + INT = 0x10000000 # Integer type + FLOAT = 0X20000000 # Floating point type + ENUM = 0x30000000 # Enum type + BOOL = 0x40000000 # Boolean type + STRING = 0x50000000 # String type + BUFFER = 0x60000000 # Block data type + COMMAND = 0x70000000 # Command type + + def __init__(self): + pass + + +class GxFeatureLevel: + REMOTE_DEV = 0x00000000 # RemoteDevice Layer + TL = 0x01000000 # TL Layer + IF = 0x02000000 # Interface Layer + DEV = 0x03000000 # Device Layer + DS = 0x04000000 # DataStream Layer + + def __init__(self): + pass + + +class GxFeatureID: + # ---------------Device Information Section--------------------------- + STRING_DEVICE_VENDOR_NAME = 0x50000000 # The name of the device's vendor + STRING_DEVICE_MODEL_NAME = 0x50000001 # The model name of the device + STRING_DEVICE_FIRMWARE_VERSION = 0x50000002 # The version of the device's firmware and software + STRING_DEVICE_VERSION = 0x50000003 # The version of the device + STRING_DEVICE_SERIAL_NUMBER = 0x50000004 # A serial number for device + STRING_FACTORY_SETTING_VERSION = 0x50000006 # The version of the device's Factory Setting + STRING_DEVICE_USER_ID = 0x50000007 # A user programmable string + INT_DEVICE_LINK_SELECTOR = 0x10000008 # Selects which Link of the device to control + ENUM_DEVICE_LINK_THROUGHPUT_LIMIT_MODE = 0x30000009 # DeviceLinkThroughputLimit switch + INT_DEVICE_LINK_THROUGHPUT_LIMIT = 0x1000000a # Limits the maximum bandwidth of the data + INT_DEVICE_LINK_CURRENT_THROUGHPUT = 0x1000000b # Current bandwidth of the data + COMMAND_DEVICE_RESET = 0x7000000c # Device reset + INT_TIMESTAMP_TICK_FREQUENCY = 0x1000000d # Timestamp tick frequency + COMMAND_TIMESTAMP_LATCH = 0x7000000e # Timestamp latch + COMMAND_TIMESTAMP_RESET = 0x7000000f # Timestamp reset + COMMAND_TIMESTAMP_LATCH_RESET = 0x70000010 # Timestamp latch reset + INT_TIMESTAMP_LATCH_VALUE = 0x10000011 # The value of timestamp latch + STRING_DEVICE_PHY_VERSION = 0x50000012 # Device network chip version + ENUM_DEVICE_TEMPERATURE_SELECTOR = 0x30000013 # Device temperature selection, reference GxDeviceTemperatureSelectorEntry + FLOAT_DEVICE_TEMPERATURE = 0x20000014 # Device temperature + + # ---------------ImageFormat Section---------------------------------- + INT_SENSOR_WIDTH = 0x100003e8 # The actual width of the camera's sensor in pixels + INT_SENSOR_HEIGHT = 0x100003e9 # The actual height of the camera's sensor in pixels + INT_WIDTH_MAX = 0x100003ea # Width max[read_only] + INT_HEIGHT_MAX = 0x100003eb # Height max[read_only] + INT_OFFSET_X = 0x100003ec # The X offset for the area of interest + INT_OFFSET_Y = 0x100003ed # The Y offset for the area of interest + INT_WIDTH = 0x100003ee # the width of the area of interest in pixels + INT_HEIGHT = 0x100003ef # the height of the area of interest in pixels + INT_BINNING_HORIZONTAL = 0x100003f0 # Horizontal pixel Binning + INT_BINNING_VERTICAL = 0x100003f1 # Vertical pixel Binning + INT_DECIMATION_HORIZONTAL = 0x100003f2 # Horizontal pixel sampling + INT_DECIMATION_VERTICAL = 0x100003f3 # Vertical pixel sampling + ENUM_PIXEL_SIZE = 0x300003f4 # Pixel depth, Reference GxPixelSizeEntry + ENUM_PIXEL_COLOR_FILTER = 0x300003f5 # Bayer format, Reference GxPixelColorFilterEntry + ENUM_PIXEL_FORMAT = 0x300003f6 # Pixel format, Reference GxPixelFormatEntry + BOOL_REVERSE_X = 0x400003f7 # Horizontal flipping + BOOL_REVERSE_Y = 0x400003f8 # Vertical flipping + ENUM_TEST_PATTERN = 0x300003f9 # Test pattern, Reference GxTestPatternEntry + ENUM_TEST_PATTERN_GENERATOR_SELECTOR = 0x300003fa # The source of test pattern, reference GxTestPatternGeneratorSelectorEntry + ENUM_REGION_SEND_MODE = 0x300003fb # ROI region output mode, reference GxRegionSendModeEntry + ENUM_REGION_MODE = 0x300003fc # ROI region output switch + ENUM_REGION_SELECTOR = 0x300003fd # ROI region select, reference GxRegionSelectorEntry + INT_CENTER_WIDTH = 0x100003fe # Window width + INT_CENTER_HEIGHT = 0x100003ff # Window height + ENUM_BINNING_HORIZONTAL_MODE = 0x30000400 # Binning horizontal mode, reference GxBinningHorizontalModeEntry + ENUM_BINNING_VERTICAL_MODE = 0x30000401 # Binning vertical mode, reference GxBinningVerticalModeEntry + ENUM_SENSOR_SHUTTER_MODE = 0x30000402 # Sensor shutter mode, reference GxSensorShutterModeEntry + + # ---------------TransportLayer Section------------------------------- + INT_PAYLOAD_SIZE = 0x100007d0 # Size of images in byte + BOOL_GEV_CURRENT_IP_CONFIGURATION_LLA = 0x400007d1 # (Only GEVDevice)IP configuration by LLA. + BOOL_GEV_CURRENT_IP_CONFIGURATION_DHCP = 0x400007d2 # (Only GEVDevice)IP configuration by DHCP + BOOL_GEV_CURRENT_IP_CONFIGURATION_PERSISTENT_IP = 0x400007d3 # (Only GEVDevice)IP configuration by PersistentIP + INT_ESTIMATED_BANDWIDTH = 0x100007d4 # (Only GEVDevice)Estimated Bandwidth in Bps + INT_GEV_HEARTBEAT_TIMEOUT = 0x100007d5 # (Only GEVDevice)The heartbeat timeout in milliseconds + INT_GEV_PACKET_SIZE = 0x100007d6 # (Only GEVDevice)The packet size in bytes for each packet + INT_GEV_PACKET_DELAY = 0x100007d7 # (Only GEVDevice)A delay between the transmission of each packet + INT_GEV_LINK_SPEED = 0x100007d8 # (Only GEVDevice)The connection speed in Mbps + + # ---------------AcquisitionTrigger Section--------------------------- + ENUM_ACQUISITION_MODE = 0x30000bb8 # The mode of acquisition, reference GxAcquisitionModeEntry + COMMAND_ACQUISITION_START = 0x70000bb9 # The command for starts the acquisition of images + COMMAND_ACQUISITION_STOP = 0x70000bba # The command for stop the acquisition of images + INT_ACQUISITION_SPEED_LEVEL = 0x10000bbb # (Only U2Device)The level for acquisition speed + INT_ACQUISITION_FRAME_COUNT = 0x10000bbc # (Only U2Device)Number of frames to acquire in MultiFrame Acquisition mode. + ENUM_TRIGGER_MODE = 0x30000bbd # Trigger mode switch + COMMAND_TRIGGER_SOFTWARE = 0x70000bbe # The command for generates a software trigger signal + ENUM_TRIGGER_ACTIVATION = 0x30000bbf # Trigger polarity, Reference GxTriggerActivationEntry + ENUM_TRIGGER_SWITCH = 0x30000bc0 # (Only U2Device)The switch of External trigger + FLOAT_EXPOSURE_TIME = 0x20000bc1 # Exposure time + ENUM_EXPOSURE_AUTO = 0x30000bc2 # Exposure auto + FLOAT_TRIGGER_FILTER_RAISING = 0x20000bc3 # The Value of rising edge triggered filter + FLOAT_TRIGGER_FILTER_FALLING = 0x20000bc4 # The Value of falling edge triggered filter + ENUM_TRIGGER_SOURCE = 0x30000bc5 # Trigger source, Reference GxTriggerSourceEntry + ENUM_EXPOSURE_MODE = 0x30000bc6 # Exposure mode, Reference GxExposureModeEntry + ENUM_TRIGGER_SELECTOR = 0x30000bc7 # Trigger type, Reference GxTriggerSelectorEntry + FLOAT_TRIGGER_DELAY = 0x20000bc8 # The trigger delay in microsecond + ENUM_TRANSFER_CONTROL_MODE = 0x30000bc9 # The control method for the transfers, Reference GxTransferControlModeEntry + ENUM_TRANSFER_OPERATION_MODE = 0x30000bca # The operation method for the transfers, Reference GxTransferOperationModeEntry + COMMAND_TRANSFER_START = 0x70000bcb # Starts the streaming of data blocks out of the device + INT_TRANSFER_BLOCK_COUNT = 0x10000bcc # The number of data Blocks that the device should stream before stopping + BOOL_FRAMESTORE_COVER_ACTIVE = 0x40000bcd # The switch for frame cover + ENUM_ACQUISITION_FRAME_RATE_MODE = 0x30000bce # The switch for Control frame rate + FLOAT_ACQUISITION_FRAME_RATE = 0x20000bcf # The value for Control frame rate + FLOAT_CURRENT_ACQUISITION_FRAME_RATE = 0x20000bd0 # The maximum allowed frame acquisition rate + ENUM_FIXED_PATTERN_NOISE_CORRECT_MODE = 0x30000bd1 # The switch of fixed pattern noise correct + INT_ACQUISITION_BURST_FRAME_COUNT = 0x10000bd6 # The acquisition burst frame count + ENUM_ACQUISITION_STATUS_SELECTOR = 0x30000bd7 # The selector of acquisition status, reference GxAcquisitionStatusSelectorEntry + BOOL_ACQUISITION_STATUS = 0x40000bd8 # The acquisition status + FLOAT_EXPOSURE_DELAY = 0x2000765c # The exposure delay + FLOAT_EXPOSURE_OVERLAP_TIME_MAX = 0x2000765d # Maximum overlap exposure time + ENUM_EXPOSURE_TIME_MODE = 0x3000765e # Exposure time mode, reference GxExposureTimeModeEntry + + # ----------------DigitalIO Section----------------------------------- + ENUM_USER_OUTPUT_SELECTOR = 0x30000fa0 # selects user settable output signal, Reference GxUserOutputSelectorEntry + BOOL_USER_OUTPUT_VALUE = 0x40000fa1 # The state of the output signal + ENUM_USER_OUTPUT_MODE = 0x30000fa2 # (Only U2Device)UserIO output mode, Reference GxUserOutputModeEntry + ENUM_STROBE_SWITCH = 0x30000fa3 # (Only U2Device)Strobe switch + ENUM_LINE_SELECTOR = 0x30000fa4 # Line selector, Reference GxLineSelectorEntry + ENUM_LINE_MODE = 0x30000fa5 # Line mode, Reference GxLineModeEntry + BOOL_LINE_INVERTER = 0x40000fa6 # Pin level reversal + ENUM_LINE_SOURCE = 0x30000fa7 # line source, Reference GxLineSourceEntry + BOOL_LINE_STATUS = 0x40000fa8 # line status + INT_LINE_STATUS_ALL = 0x10000fa9 # all line status + FLOAT_PULSE_WIDTH = 0x20000faa # IO pulse width + + # ----------------AnalogControls Section------------------------------ + ENUM_GAIN_AUTO = 0x30001388 # gain auto, Reference GxAutoEntry + ENUM_GAIN_SELECTOR = 0x30001389 # selects gain channel, Reference GxGainSelectorEntry + ENUM_BLACK_LEVEL_AUTO = 0x3000138b # Black level auto, Reference GxAutoEntry + ENUM_BLACK_LEVEL_SELECTOR = 0x3000138c # Black level channel, Reference GxBlackLevelSelectEntry + ENUM_BALANCE_WHITE_AUTO = 0x3000138e # Balance white auto, Reference GxAutoEntry + ENUM_BALANCE_RATIO_SELECTOR = 0x3000138f # selects Balance white channel, Reference GxBalanceRatioSelectorEntry + FLOAT_BALANCE_RATIO = 0x20001390 # Balance white channel ratio + ENUM_COLOR_CORRECT = 0x30001391 # Color correct switch + ENUM_DEAD_PIXEL_CORRECT = 0x30001392 # Pixel correct switch + FLOAT_GAIN = 0x20001393 # gain value + FLOAT_BLACK_LEVEL = 0x20001394 # Black level value + BOOL_GAMMA_ENABLE = 0x40001395 # Gamma enable bit + ENUM_GAMMA_MODE = 0x30001396 # Gamma mode, reference GxGammaModeEntry + FLOAT_GAMMA = 0x20001397 # The value of Gamma + INT_DIGITAL_SHIFT = 0x10001398 # bit select + ENUM_LIGHT_SOURCE_PRESET = 0x30001399 # Light source preset, Reference GxLightSourcePresetEntry + + # ---------------CustomFeature Section-------------------------------- + INT_ADC_LEVEL = 0x10001770 # (Only U2Device)AD conversion level + INT_H_BLANKING = 0x10001771 # (Only U2Device)Horizontal blanking + INT_V_BLANKING = 0x10001772 # (Only U2Device)Vertical blanking + STRING_USER_PASSWORD = 0x50001773 # (Only U2Device)User encrypted zone cipher + STRING_VERIFY_PASSWORD = 0x50001774 # (Only U2Device)User encrypted zone check cipher + BUFFER_USER_DATA = 0x60001775 # (Only U2Device)User encrypted area content + INT_GRAY_VALUE = 0x10001776 # Expected gray value + ENUM_AA_LIGHT_ENVIRONMENT = 0x30001777 # (Only U2Device)Gain auto, Exposure auto, Light environment type, + # Reference GxAALightEnvironmentEntry + INT_AAROI_OFFSETX = 0x10001778 # The X offset for the rect of interest in pixels for 2A + INT_AAROI_OFFSETY = 0x10001779 # The Y offset for the rect of interest in pixels for 2A + INT_AAROI_WIDTH = 0x1000177a # The width offset for the rect of interest in pixels for 2A + INT_AAROI_HEIGHT = 0x1000177b # The height offset for the rect of interest in pixels for 2A + FLOAT_AUTO_GAIN_MIN = 0x2000177c # Automatic gain minimum + FLOAT_AUTO_GAIN_MAX = 0x2000177d # Automatic gain maximum + FLOAT_AUTO_EXPOSURE_TIME_MIN = 0x2000177e # Automatic exposure minimum + FLOAT_AUTO_EXPOSURE_TIME_MAX = 0x2000177f # Automatic exposure maximum + BUFFER_FRAME_INFORMATION = 0x60001780 # (Only U2Device)Image frame information + INT_CONTRAST_PARAM = 0x10001781 # Contrast parameter + FLOAT_GAMMA_PARAM = 0x20001782 # Gamma parameter + INT_COLOR_CORRECTION_PARAM = 0x10001783 # Color correction param + ENUM_IMAGE_GRAY_RAISE_SWITCH = 0x30001784 # (Only U2Device)Image gray raise switch + ENUM_AWB_LAMP_HOUSE = 0x30001785 # Automatic white balance light source + # Reference GxAWBLampHouseEntry + INT_AWBROI_OFFSETX = 0x10001786 # Offset_X of automatic white balance region + INT_AWBROI_OFFSETY = 0x10001787 # Offset_Y of automatic white balance region + INT_AWBROI_WIDTH = 0x10001788 # Width of automatic white balance region + INT_AWBROI_HEIGHT = 0x10001789 # Height of automatic white balance region + ENUM_SHARPNESS_MODE = 0x3000178a # Sharpness switch + FLOAT_SHARPNESS = 0x2000178b # Sharpness value + ENUM_USER_DATA_FIELD_SELECTOR = 0x3000178c # User selects the flash data field + # Reference GxUserDataFieldSelectorEntry for area selection + BUFFER_USER_DATA_FIELD_VALUE = 0x6000178d # User data field content + ENUM_FLAT_FIELD_CORRECTION = 0x3000178e # Flat field correction switch + ENUM_NOISE_REDUCTION_MODE = 0x3000178f # Noise reduction switch + FLOAT_NOISE_REDUCTION = 0x20001790 # Noise reduction value + BUFFER_FFCLOAD = 0x60001791 # Get flat field correction parameters + BUFFER_FFCSAVE = 0x60001792 # Set flat field correction parameters + ENUM_STATIC_DEFECT_CORRECTION = 0x30001793 # Static dead pixel correction switch + + # ---------------UserSetControl Section------------------------------- + ENUM_USER_SET_SELECTOR = 0x30001b58 # Parameter group selection, Reference GxUserSetEntry + COMMAND_USER_SET_LOAD = 0x70001b59 # Load parameter group + COMMAND_USER_SET_SAVE = 0x70001b5a # Save parameter group + ENUM_USER_SET_DEFAULT = 0x30001b5b # Startup parameter group, Reference GxUserSetEntry + + # ---------------Event Section---------------------------------------- + ENUM_EVENT_SELECTOR = 0x30001f40 # Event source select, Reference GxEventSelectorEntry + ENUM_EVENT_NOTIFICATION = 0x30001f41 # Switch of the notification to the host application of the occurrence of the selected Event. + INT_EVENT_EXPOSURE_END = 0x10001f42 # Exposure end event + INT_EVENT_EXPOSURE_END_TIMESTAMP = 0x10001f43 # The timestamp of Exposure end event + INT_EVENT_EXPOSURE_END_FRAME_ID = 0x10001f44 # The frame id of Exposure end event + INT_EVENT_BLOCK_DISCARD = 0x10001f45 # Block discard event + INT_EVENT_BLOCK_DISCARD_TIMESTAMP = 0x10001f46 # The timestamp of Block discard event + INT_EVENT_OVERRUN = 0x10001f47 # Event queue overflow event + INT_EVENT_OVERRUN_TIMESTAMP = 0x10001f48 # The timestamp of event queue overflow event + INT_EVENT_FRAME_START_OVER_TRIGGER = 0x10001f49 # Trigger signal shield event + INT_EVENT_FRAME_START_OVER_TRIGGER_TIMESTAMP = 0x10001f4a # The timestamp of trigger signal shield event + INT_EVENT_BLOCK_NOT_EMPTY = 0x10001f4b # Frame memory not empty event + INT_EVENT_BLOCK_NOT_EMPTY_TIMESTAMP = 0x10001f4c # The timestamp of frame memory not empty event + INT_EVENT_INTERNAL_ERROR = 0x10001f4d # Internal erroneous event + INT_EVENT_INTERNAL_ERROR_TIMESTAMP = 0x10001f4e # The timestamp of internal erroneous event + INT_EVENT_FRAMEBURSTSTART_OVERTRIGGER = 0x10001f4f # Frame burst start overtrigger event ID + INT_EVENT_FRAMEBURSTSTART_OVERTRIGGER_FRAMEID = 0x10001f50 # Frame burst start overtrigger event frame ID + INT_EVENT_FRAMEBURSTSTART_OVERTRIGGER_TIMESTAMP = 0x10001f51 # Frame burst start overtrigger event timestamp + INT_EVENT_FRAMESTART_WAIT = 0x10001f52 # Frame start wait event ID + INT_EVENT_FRAMESTART_WAIT_TIMESTAMP = 0x10001f53 # Frame start wait event timestamp + INT_EVENT_FRAMEBURSTSTART_WAIT = 0x10001f54 # Frame burst start wait event ID + INT_EVENT_FRAMEBURSTSTART_WAIT_TIMESTAMP = 0x10001f55 # Frame burst start wait event timestamp + INT_EVENT_BLOCK_DISCARD_FRAMEID= 0x10001f56 # Data block discard event frame ID + INT_EVENT_FRAMESTART_OVERTRIGGER_FRAMEID = 0x10001f57 # Frame start wait overtrigger event frame ID + INT_EVENT_BLOCK_NOT_EMPTY_FRAMEID = 0x10001f58 # Data block not empty event frame ID + INT_EVENT_FRAMESTART_WAIT_FRAMEID = 0x10001f59 # Frame start wait event frame ID + INT_EVENT_FRAMEBURSTSTART_WAIT_FRAMEID = 0x10001f5a # Frame burst start wait event frame ID + + # ---------------LUT Section------------------------------------------ + ENUM_LUT_SELECTOR = 0x30002328 # Select lut, Reference GxLutSelectorEntry + BUFFER_LUT_VALUE_ALL = 0x60002329 # Lut data + BOOL_LUT_ENABLE = 0x4000232a # Lut enable bit + INT_LUT_INDEX = 0x1000232b # Lut index + INT_LUT_VALUE = 0x1000232c # Lut value + + # ---------------ChunkData Section------------------------------------ + BOOL_CHUNK_MODE_ACTIVE = 0x40002711 # Enable frame information + ENUM_CHUNK_SELECTOR = 0x30002712 # Select frame information channel, Reference GxChunkSelectorEntry + BOOL_CHUNK_ENABLE = 0x40002713 # Enable single frame information channel + + # ---------------Color Transformation Control------------------------- + ENUM_COLOR_TRANSFORMATION_MODE = 0x30002af8 # Color transformation mode, Reference GxColorTransformationModeEntry + BOOL_COLOR_TRANSFORMATION_ENABLE = 0x40002af9 # Color transformation enable bit + ENUM_COLOR_TRANSFORMATION_VALUE_SELECTOR = 0x30002afa # The selector of color transformation value, Reference GxColorTransformationValueSelectorEntry + FLOAT_COLOR_TRANSFORMATION_VALUE = 0x20002afb # The value of color transformation + ENUM_SATURATION_MODE = 0x30002afc # Saturation switch + INT_SATURATION = 0x10002afd # Saturation value + + # ---------------CounterAndTimerControl Section----------------------- + ENUM_TIMER_SELECTOR = 0x30002ee0 # Selects which Counter to configure, Refer to GxTimerSelectorEntry + FLOAT_TIMER_DURATION = 0x20002ee1 # Sets the duration (in microseconds) of the Timer pulse. + FLOAT_TIMER_DELAY = 0x20002ee2 # Sets the duration (in microseconds) of the delay to apply at the reception of a trigger before starting the Timer. + ENUM_TIMER_TRIGGER_SOURCE = 0x30002ee3 # Selects the source of the trigger to start the Timer, Refer to GxTimerTriggerSourceEntry + ENUM_COUNTER_SELECTOR = 0x30002ee4 # Selects which Counter to configure, Refer to GxCounterSelectorEntry + ENUM_COUNTER_EVENT_SOURCE = 0x30002ee5 # Select the events that will be the source to increment the Counter, Refer to GxCounterEventSourceEntry + ENUM_COUNTER_RESET_SOURCE = 0x30002ee6 # Selects the signals that will be the source to reset the Counter, Refer to GxCounterResetSourceEntry + ENUM_COUNTER_RESET_ACTIVATION = 0x30002ee7 # Selects the Activation mode of the Counter Reset Source signal, Refer to GxCounterResetActivationEntry + COMMAND_COUNTER_RESET = 0x70002ee8 # Does a software reset of the selected Counter and starts it. + ENUM_COUNTER_TRIGGER_SOURCE = 0x30002ee9 # Counter trigger source, Reference GxCounterTriggerSourceEntry + INT_COUNTER_DURATION = 0x10002eea # Counter duration value + ENUM_TIMER_TRIGGER_ACTIVATION = 0x30002eeb # Timer Trigger Activation, reference GxTimerTriggerActivationEntry + + # ---------------RemoveParameterLimitControl Section------------------ + ENUM_REMOVE_PARAMETER_LIMIT = 0x300032c8 # Remove paremeter range restriction switch + + # ---------------Device Feature--------------------------------------- + INT_COMMAND_TIMEOUT = 0x13000000 # (Only GEVDevice)The time of command timeout + INT_COMMAND_RETRY_COUNT = 0x13000001 # (Only GEVDevice)Command retry times + + # ---------------DataStream Feature----------------------------------- + INT_ANNOUNCED_BUFFER_COUNT = 0x14000000 # The number of Buffer declarations + INT_DELIVERED_FRAME_COUNT = 0x14000001 # Number of received frames (including remnant frames) + INT_LOST_FRAME_COUNT = 0x14000002 # Number of lost frames caused by buffer deficiency + INT_INCOMPLETE_FRAME_COUNT = 0x14000003 # Number of residual frames received + INT_DELIVERED_PACKET_COUNT = 0x14000004 # The number of packets received + INT_RESEND_PACKET_COUNT = 0x14000005 # (Only GEVDevice)Number of retransmission packages + INT_RESCUED_PACKET_COUNT = 0x14000006 # (Only GEVDevice)Retransmission success package number + INT_RESEND_COMMAND_COUNT = 0x14000007 # (Only GEVDevice)Retransmission command times + INT_UNEXPECTED_PACKET_COUNT = 0x14000008 # (Only GEVDevice)Exception packet number + INT_MAX_PACKET_COUNT_IN_ONE_BLOCK = 0x14000009 # (Only GEVDevice)Data block maximum retransmission number + INT_MAX_PACKET_COUNT_IN_ONE_COMMAND = 0x1400000a # (Only GEVDevice)The maximum number of packets contained in one command + INT_RESEND_TIMEOUT = 0x1400000b # (Only GEVDevice)Retransmission timeout time + INT_MAX_WAIT_PACKET_COUNT = 0x1400000c # (Only GEVDevice)Maximum waiting packet number + ENUM_RESEND_MODE = 0x3400000d # (Only GEVDevice)Retransmission mode switch + INT_MISSING_BLOCK_ID_COUNT = 0x1400000e # (Only GEVDevice)BlockID lost number + INT_BLOCK_TIMEOUT = 0x1400000f # (Only GEVDevice)Data block timeout time + INT_STREAM_TRANSFER_SIZE = 0x14000010 # (Only U3VDevice)Data block size + INT_STREAM_TRANSFER_NUMBER_URB = 0x14000011 # (Only U3VDevice)Number of data blocks + INT_MAX_NUM_QUEUE_BUFFER = 0x14000012 # (Only GEVDevice)The maximum Buffer number of the collection queue + INT_PACKET_TIMEOUT = 0x14000013 # (Only GEVDevice)Packet timeout time + INT_SOCKET_BUFFER_SIZE = 0x14000014 # (Only GEVDevice)Socket buffer size in kilobytes + ENUM_STOP_ACQUISITION_MODE = 0x34000015 # (Only U3VDevice)Stop acquisition mode Reference GxStopAcquisitionModeEntry + ENUM_STREAM_BUFFER_HANDLING_MODE = 0x34000016 # Buffer handling mode Reference GxDSStreamBufferHandlingModeEntry + + def __init__(self): + pass + + +class GxDeviceIPInfo(Structure): + _fields_ = [ + ('device_id', c_char * 68), # The unique identifier of the device. + ('mac', c_char * 32), # MAC address + ('ip', c_char * 32), # IP address + ('subnet_mask', c_char * 32), # Subnet mask + ('gateway', c_char * 32), # Gateway + ('nic_mac', c_char * 32), # The MAC address of the corresponding NIC(Network Interface Card). + ('nic_ip', c_char * 32), # The IP of the corresponding NIC + ('nic_subnet_mask', c_char * 32), # The subnet mask of the corresponding NIC + ('nic_gateWay', c_char * 32), # The Gateway of the corresponding NIC + ('nic_description', c_char * 132), # The description of the corresponding NIC + ('reserved', c_char * 512), # Reserved 512 bytes + ] + + def __str__(self): + return "GxDeviceIPInfo\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +class GxDeviceBaseInfo(Structure): + _fields_ = [ + ('vendor_name', c_char*32), # Vendor name + ('model_name', c_char*32), # TModel name + ('serial_number', c_char*32), # Serial number + ('display_name', c_char*132), # Display name + ('device_id', c_char*68), # The unique identifier of the device. + ('user_id', c_char*68), # User's custom name + ('access_status', c_int), # Access status that is currently supported by the device + # Refer to GxAccessStatus + ('device_class', c_int), # Device type. Such as USB2.0, GEV. + ('reserved', c_char*300), # Reserved 300 bytes + ] + + def __str__(self): + return "GxDeviceBaseInfo\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +class GxOpenParam(Structure): + _fields_ = [ + ('content', c_char_p), + ('open_mode', c_uint), + ('access_mode', c_uint), + ] + + def __str__(self): + return "GxOpenParam\n%s" % "\n".join( "%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +class GxFrameCallbackParam(Structure): + _fields_ = [ + ('user_param_index', c_void_p), # User private data + ('status', c_int), # The return state of the image + ('image_buf', c_void_p), # Image buff address + ('image_size', c_int), # Image data size, Including frame information + ('width', c_int), # Image width + ('height', c_int), # Image height + ('pixel_format', c_int), # Image PixFormat + ('frame_id', c_ulonglong), # The frame id of the image + ('timestamp', c_ulonglong), # Time stamp of image + ('reserved', c_int), # Reserved + ] + + def __str__(self): + return "GxFrameCallbackParam\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +class GxFrameData(Structure): + _fields_ = [ + ('status', c_int), # The return state of the image + ('image_buf', c_void_p), # Image buff address + ('width', c_int), # Image width + ('height', c_int), # Image height + ('pixel_format', c_int), # Image PixFormat + ('image_size', c_int), # Image data size, Including frame information + ('frame_id', c_ulonglong), # The frame id of the image + ('timestamp', c_ulonglong), # Time stamp of image + ('buf_id', c_ulonglong), # Image buff ID + ('reserved', c_int), # Reserved + ] + + def __str__(self): + return "GxFrameData\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +class GxIntRange(Structure): + _fields_ = [ + ('min', c_ulonglong), + ('max', c_ulonglong), + ('inc', c_ulonglong), + ('reserved', c_int * 8), + ] + + def __str__(self): + return "GxIntRange\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +class GxFloatRange(Structure): + _fields_ = [ + ('min', c_double), + ('max', c_double), + ('inc', c_double), + ('unit', c_char * 8), + ('inc_is_valid', c_bool), + ('reserved', c_char * 31), + ] + + def __str__(self): + return "GxFloatRange\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +class GxEnumDescription(Structure): + _fields_ = [ + ('value', c_longlong), # Enum value + ('symbolic', c_char * 64), # Character description + ('reserved', c_int * 8), + ] + + def __str__(self): + return "GxEnumDescription\n%s" % "\n".join("%s:\t%s" % (n, getattr(self, n[0])) for n in self._fields_) + + +if hasattr(dll, 'GXInitLib'): + def gx_init_lib(): + """ + :brief Initialize the device library for some resource application operations + :return: None + """ + return dll.GXInitLib() + + +if hasattr(dll, 'GXCloseLib'): + def gx_close_lib(): + """ + :brief Close the device library to release resources. + :return: None + """ + return dll.GXCloseLib() + + +if hasattr(dll, 'GXGetLastError'): + def gx_get_last_error(size=1024): + """ + :brief To get the latest error descriptions information of the program + :param size: string buff length(size=1024) + Type: Int, Minnum: 0 + :return: status: State return value, See detail in GxStatusList + err_code: Return the last error code + err_content: the latest error descriptions information of the program + """ + err_code = c_int() + err_content_buff = create_string_buffer(size) + + content_size = c_size_t() + content_size.value = size + + status = dll.GXGetLastError(byref(err_code), byref(err_content_buff), byref(content_size)) + err_content = string_at(err_content_buff, content_size.value-1) + + return status, err_code.value, string_decoding(err_content) + + +if hasattr(dll, 'GXUpdateDeviceList'): + def gx_update_device_list(time_out=200): + """ + :brief Enumerating currently all available devices in subnet and gets the number of devices. + :param time_out: The timeout time of enumeration (unit: ms). + Type: Int, Minimum:0 + :return: status: State return value, See detail in GxStatusList + device_num: The number of devices + """ + time_out_c = c_uint() + time_out_c.value = time_out + + device_num = c_uint() + status = dll.GXUpdateDeviceList(byref(device_num), time_out_c) + return status, device_num.value + + +if hasattr(dll, 'GXUpdateAllDeviceList'): + def gx_update_all_device_list(time_out=200): + """ + :brief Enumerating currently all available devices in entire network and gets the number of devices + :param time_out: The timeout time of enumeration (unit: ms). + Type: Int, Minimum: 0 + :return: status: State return value, See detail in GxStatusList + device_num: The number of devices + """ + time_out_c = c_uint() + time_out_c.value = time_out + + device_num = c_uint() + status = dll.GXUpdateAllDeviceList(byref(device_num), time_out_c) + return status, device_num.value + + +if hasattr(dll, 'GXGetAllDeviceBaseInfo'): + def gx_get_all_device_base_info(devices_num): + """ + :brief To get the basic information of all the devices + :param devices_num: The number of devices + Type: Int, Minimum: 0 + :return: status: State return value, See detail in GxStatusList + device_ip_info: The structure pointer of the device information(GxDeviceIPInfo) + """ + devices_info = (GxDeviceBaseInfo * devices_num)() + + buf_size_c = c_size_t() + buf_size_c.value = sizeof(GxDeviceBaseInfo) * devices_num + + status = dll.GXGetAllDeviceBaseInfo(byref(devices_info), byref(buf_size_c)) + return status, devices_info + + +if hasattr(dll, 'GXGetDeviceIPInfo'): + def gx_get_device_ip_info(index): + """ + :brief To get the network information of the device. + :param index: Device index + Type: Int, Minimum: 1 + :return: status: State return value, See detail in GxStatusList + device_ip_info: The structure pointer of the device information(GxDeviceIPInfo) + """ + index_c = c_uint() + index_c.value = index + + device_ip_info = GxDeviceIPInfo() + status = dll.GXGetDeviceIPInfo(index_c, byref(device_ip_info)) + + return status, device_ip_info + + +if hasattr(dll, 'GXOpenDeviceByIndex'): + def gx_open_device_by_index(index): + """ + :brief Open the device by a specific Index(1, 2, 3, ...) + :param index: Device index + Type: Int, Minimum: 1 + :return: status: State return value, See detail in GxStatusList + handle: The device handle returned by the interface + """ + index_c = c_uint() + index_c.value = index + + handle_c = c_void_p() + status = dll.GXOpenDeviceByIndex(index_c, byref(handle_c)) + return status, handle_c.value + + +if hasattr(dll, 'GXOpenDevice'): + def gx_open_device(open_param): + """ + :brief Open the device by a specific unique identification, such as: SN, IP, MAC, Index etc. + :param open_param: The open device parameter which is configurated by the user. + Type: GxOpenParam + :return: status: State return value, See detail in GxStatusList + handle: The device handle returned by the interface + """ + handle = c_void_p() + status = dll.GXOpenDevice(byref(open_param), byref(handle)) + return status, handle.value + + +if hasattr(dll, 'GXCloseDevice'): + def gx_close_device(handle): + """ + :brief Specify the device handle to close the device + :param handle: The device handle that the user specified to close. + Type: Long, Greater than 0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXCloseDevice(handle_c) + return status + +''' +if hasattr(dll, 'GXGetDevicePersistentIpAddress'): + def gx_get_device_persistent_ip_address(handle, ip_length=16, subnet_mask_length=16, default_gateway_length=16): + """ + :brief Get the persistent IP information of the device + :param handle: The handle of the device + :param ip_length: The character string length of the device persistent IP address. + :param subnet_mask_length: The character string length of the device persistent subnet mask. + :param default_gateway_length: The character string length of the device persistent gateway + :return: status: State return value, See detail in GxStatusList + ip: The device persistent IP address(str) + subnet_mask: The device persistent subnet mask(str) + default_gateway: The device persistent gateway + """ + handle_c = c_void_p() + handle_c.value = handle + + ip_length_c = c_uint() + ip_length_c.value = ip_length + ip_c = create_string_buffer(ip_length) + + subnet_mask_length_c = c_uint() + subnet_mask_length_c.value = subnet_mask_length + subnet_mask_c = create_string_buffer(subnet_mask_length) + + default_gateway_length_c = c_uint() + default_gateway_length_c.value = default_gateway_length + default_gateway_c = create_string_buffer(default_gateway_length) + + status = dll.GXGetDevicePersistentIpAddress(handle_c, byref(ip_c), byref(ip_length_c), + byref(subnet_mask_c), byref(subnet_mask_length_c), + byref(default_gateway_c), byref(default_gateway_length_c)) + + ip = string_at(ip_c, ip_length_c.value-1) + subnet_mask = string_at(subnet_mask_c, subnet_mask_length_c.value-1) + default_gateway = string_at(default_gateway_c, default_gateway_length_c.value-1) + + return status, string_decoding(ip), string_decoding(subnet_mask), string_decoding(default_gateway) + +if hasattr(dll, 'GXSetDevicePersistentIpAddress'): + def gx_set_device_persistent_ip_address(handle, ip, subnet_mask, default_gate_way): + """ + :brief Set the persistent IP information of the device + :param handle: The handle of the device + :param ip: The persistent IP character string of the device(str) + :param subnet_mask: The persistent subnet mask character string of the device(str) + :param default_gate_way: The persistent gateway character string of the device(str) + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + ip_c = create_string_buffer(string_encoding(ip)) + subnet_mask_c = create_string_buffer(string_encoding(subnet_mask)) + default_gate_way_c = create_string_buffer(string_encoding(default_gate_way)) + + status = dll.GXSetDevicePersistentIpAddress(handle_c, byref(ip_c), byref(subnet_mask_c), + byref(default_gate_way_c)) + return status +''' + +if hasattr(dll, 'GXGetFeatureName'): + def gx_get_feature_name(handle, feature_id): + """ + :brief Get the string description for the feature code + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: Int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + name: The string description for the feature code + """ + handle_c = c_void_p() + handle_c.value = handle + feature_id_c = c_int() + feature_id_c.value = feature_id + + size_c = c_size_t() + status = dll.GXGetFeatureName(handle_c, feature_id_c, None, byref(size_c)) + + name_buff = create_string_buffer(size_c.value) + status = dll.GXGetFeatureName(handle_c, feature_id_c, byref(name_buff), byref(size_c)) + + name = string_at(name_buff, size_c.value-1) + return status, string_decoding(name) + + +if hasattr(dll, 'GXIsImplemented'): + def gx_is_implemented(handle, feature_id): + """ + :brief Inquire the current camera whether support a special feature. + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + is_implemented: To return the result whether is support this feature + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + is_implemented = c_bool() + status = dll.GXIsImplemented(handle_c, feature_id_c, byref(is_implemented)) + return status, is_implemented.value + + +if hasattr(dll, 'GXIsReadable'): + def gx_is_readable(handle, feature_id): + """ + :brief Inquire if a feature code is currently readable + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + is_readable: To return the result whether the feature code ID is readable + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + is_readable = c_bool() + status = dll.GXIsReadable(handle_c, feature_id_c, byref(is_readable)) + return status, is_readable.value + + +if hasattr(dll, 'GXIsWritable'): + def gx_is_writable(handle, feature_id): + """ + :brief Inquire if a feature code is currently writable + :param handle: The handle of the device. + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + is_writeable: To return the result whether the feature code ID is writable(Bool) + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + is_writeable = c_bool() + status = dll.GXIsWritable(handle_c, feature_id_c, byref(is_writeable)) + return status, is_writeable.value + + +if hasattr(dll, 'GXGetIntRange'): + def gx_get_int_range(handle, feature_id): + """ + :brief To get the minimum value, maximum value and steps of the int type + :param handle: The handle of the device. + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + int_range: The structure of range description(GxIntRange) + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + int_range = GxIntRange() + status = dll.GXGetIntRange(handle_c, feature_id_c, byref(int_range)) + return status, int_range + + +if hasattr(dll, 'GXGetInt'): + def gx_get_int(handle, feature_id): + """ + :brief Get the current value of the int type. + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + int_value: Get the current value of the int type + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + int_value = c_int64() + status = dll.GXGetInt(handle_c, feature_id_c, byref(int_value)) + return status, int_value.value + + +if hasattr(dll, 'GXSetInt'): + def gx_set_int(handle, feature_id, int_value): + """ + :brief Set the value of int type + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID. + Type: int, Greater than 0 + :param int_value: The value that the user will set + Type: long, minnum:0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + value_c = c_int64() + value_c.value = int_value + + status = dll.GXSetInt(handle_c, feature_id_c, value_c) + return status + + +if hasattr(dll, 'GXGetFloatRange'): + def gx_get_float_range(handle, feature_id): + """ + :brief To get the minimum value, maximum value, stepsand unit of the float type + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + float_range: The description structure(GxFloatRange) + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + float_range = GxFloatRange() + status = dll.GXGetFloatRange(handle_c, feature_id_c, byref(float_range)) + return status, float_range + + +if hasattr(dll, 'GXSetFloat'): + def gx_set_float(handle, feature_id, float_value): + """ + :brief Set the value of float type + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :param float_value: The float value that the user will set + Type: double + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + value_c = c_double() + value_c.value = float_value + + status = dll.GXSetFloat(handle_c, feature_id_c, value_c) + return status + + +if hasattr(dll, 'GXGetFloat'): + def gx_get_float(handle, feature_id): + """ + :brief Get the value of float type + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + float_value = c_double() + status = dll.GXGetFloat(handle_c, feature_id_c, byref(float_value)) + + return status, float_value.value + + +if hasattr(dll, 'GXGetEnumEntryNums'): + def gx_get_enum_entry_nums(handle, feature_id): + """ + :brief Get the number of the options for the enumeration item + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + enum_num: The number of the options for the enumeration item + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + enum_nums = c_uint() + status = dll.GXGetEnumEntryNums(handle_c, feature_id_c, byref(enum_nums)) + return status, enum_nums.value + + +if hasattr(dll, 'GXGetEnumDescription'): + def gx_get_enum_description(handle, feature_id, enum_num): + """ + :brief To get the description information of the enumerated type values + the number of enumerated items and the value and descriptions of each item + please reference GxEnumDescription. + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :param enum_num: The number of enumerated information + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + enum_description: Enumerated information array(GxEnumDescription) + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + buf_size_c = c_size_t() + buf_size_c.value = sizeof(GxEnumDescription) * enum_num + + enum_description = (GxEnumDescription * enum_num)() + status = dll.GXGetEnumDescription(handle_c, feature_id_c, byref(enum_description), byref(buf_size_c)) + return status, enum_description + + +if hasattr(dll, 'GXGetEnum'): + def gx_get_enum(handle, feature_id): + """ + :brief To get the current enumeration value + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + enum_value: Get the current enumeration value + """ + handle_c = c_void_p() + handle_c.value = handle + feature_id_c = c_int() + feature_id_c.value = feature_id + + enum_value = c_int64() + status = dll.GXGetEnum(handle_c, feature_id_c, byref(enum_value)) + + return status, enum_value.value + + +if hasattr(dll, 'GXSetEnum'): + def gx_set_enum(handle, feature_id, enum_value): + """ + :brief Set the enumeration value + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :param enum_value: Set the enumeration value + Type: int + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + value_c = c_int64() + value_c.value = enum_value + + status = dll.GXSetEnum(handle_c, feature_id_c, value_c) + return status + + +if hasattr(dll, 'GXGetBool'): + def gx_get_bool(handle, feature_id): + """ + :brief Get the value of bool type + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + boot_value: the value of bool type + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + boot_value = c_bool() + status = dll.GXGetBool(handle_c, feature_id_c, byref(boot_value)) + return status, boot_value.value + + +if hasattr(dll, 'GXSetBool'): + def gx_set_bool(handle, feature_id, bool_value): + """ + :brief Set the value of bool type + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :param bool_value: The bool value that the user will set + Type: Bool + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + value_c = c_bool() + value_c.value = bool_value + + status = dll.GXSetBool(handle_c, feature_id_c, value_c) + return status + + +if hasattr(dll, 'GXGetStringLength'): + def gx_get_string_length(handle, feature_id): + """ + :brief Get the current value length of the character string type. Unit: byte + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + string_length: the current value length of the character string type + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + string_length = c_size_t() + status = dll.GXGetStringLength(handle_c, feature_id_c, byref(string_length)) + + return status, string_length.value - 1 + + +if hasattr(dll, 'GXGetStringMaxLength'): + def gx_get_string_max_length(handle, feature_id): + """ + :brief Get the maximum length of the string type value, Unit: byte + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + string_max_length: the maximum length of the string type value + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + string_max_length = c_size_t() + status = dll.GXGetStringMaxLength(handle_c, feature_id, byref(string_max_length)) + + return status, string_max_length.value - 1 + + +if hasattr(dll, 'GXGetString'): + def gx_get_string(handle, feature_id): + """ + :brief Get the content of the string type value + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + size_c = c_size_t() + status = dll.GXGetString(handle_c, feature_id_c, None, byref(size_c)) + + content_c = create_string_buffer(size_c.value) + status = dll.GXGetString(handle_c, feature_id_c, byref(content_c), byref(size_c)) + + content = string_at(content_c, size_c.value-1) + return status, string_decoding(content) + + +if hasattr(dll, 'GXSetString'): + def gx_set_string(handle, feature_id, content): + """ + :brief Set the content of the string value + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :param content: The string will be setting(str) + Type: str + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + content_c = create_string_buffer(string_encoding(content)) + + status = dll.GXSetString(handle_c, feature_id_c, byref(content_c)) + return status + + +if hasattr(dll, 'GXGetBufferLength'): + def gx_get_buffer_length(handle, feature_id): + """ + :brief Get the length of the chunk data and the unit is byte, + the user can apply the buffer based on the length obtained, + and then call the gx_get_buffer to get the chunk data. + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + buff_length: Buff length, Unit: byte + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + buff_length = c_size_t() + status = dll.GXGetBufferLength(handle_c, feature_id_c, byref(buff_length)) + return status, buff_length.value + + +if hasattr(dll, 'GXGetBuffer'): + def gx_get_buffer(handle, feature_id): + """ + :brief Get the chunk data + :param handle: The handle of the device + Type: Long, Greater than 0 + :param feature_id: The feature code ID + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + buff: chunk data + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + buff_length_c = c_size_t() + status = dll.GXGetBuffer(handle_c, feature_id_c, None, byref(buff_length_c)) + + buff_c = (c_ubyte * buff_length_c.value)() + status = dll.GXGetBuffer(handle_c, feature_id_c, byref(buff_c), byref(buff_length_c)) + return status, buff_c + + +if hasattr(dll, 'GXSetBuffer'): + def gx_set_buffer(handle, feature_id, buff, buff_size): + """ + :brief Set the chunk data + :param handle: The handle of the device + :param feature_id: The feature code ID + Type: long, Greater than 0 + :param buff: chunk data buff + Type: Ctype array + :param buff_size: chunk data buff size + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + """ + + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + buff_size_c = c_size_t() + buff_size_c.value = buff_size + + status = dll.GXSetBuffer(handle_c, feature_id_c, buff, buff_size_c) + return status + + +if hasattr(dll, 'GXSendCommand'): + def gx_send_command(handle, feature_id): + """ + :brief Send the command + :param handle: The handle of the device + Type: long, Greater than 0 + :param feature_id: The feature code ID. + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + status = dll.GXSendCommand(handle_c, feature_id_c) + return status + + +CAP_CALL = CFUNCTYPE(None, POINTER(GxFrameCallbackParam)) +if hasattr(dll, 'GXRegisterCaptureCallback'): + def gx_register_capture_callback(handle, cap_call): + """ + :brief Register the capture callback function + :param handle: The handle of the device + :param cap_call: The callback function that the user will register(@ CAP_CALL) + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXRegisterCaptureCallback(handle_c, None, cap_call) + return status + + +if hasattr(dll, 'GXUnregisterCaptureCallback'): + def gx_unregister_capture_callback(handle): + """ + :brief Unregister the capture callback function + :param handle: The handle of the device + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXUnregisterCaptureCallback(handle_c) + return status + + +if hasattr(dll, 'GXGetImage'): + def gx_get_image(handle, frame_data, time_out=200): + """ + :brief After starting acquisition, you can call this function to get images directly. + Noting that the interface can not be mixed with the callback capture mode. + :param handle: The handle of the device + Type: Long, Greater than 0 + :param frame_data: [out]User introduced to receive the image data + Type: GxFrameData + :param time_out: The timeout time of capture image.(unit: ms) + Type: int, minnum: 0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + time_out_c = c_uint() + time_out_c.value = time_out + + status = dll.GXGetImage(handle_c, byref(frame_data), time_out_c) + return status + + +if hasattr(dll, 'GXFlushQueue'): + def gx_flush_queue(handle): + """ + :brief Empty the cache image in the image output queue. + :param handle: The handle of the device + Type: Long, Greater than 0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXFlushQueue(handle_c) + return status + + +OFF_LINE_CALL = CFUNCTYPE(None, c_void_p) +if hasattr(dll, 'GXRegisterDeviceOfflineCallback'): + def gx_register_device_offline_callback(handle, call_back): + """ + :brief At present, the mercury GIGE camera provides the device offline notification event mechanism, + the user can call this interface to register the event handle callback function + :param handle: The handle of the device + :param call_back: The user event handle callback function(@ OFF_LINE_CALL) + :return: status: State return value, See detail in GxStatusList + call_back_handle: The handle of offline callback function + the handle is used for unregistering the callback function + """ + handle_c = c_void_p() + handle_c.value = handle + + call_back_handle = c_void_p() + + status = dll.GXRegisterDeviceOfflineCallback(handle_c, None, call_back, byref(call_back_handle)) + return status, call_back_handle.value + + +if hasattr(dll, 'GXUnregisterDeviceOfflineCallback'): + def gx_unregister_device_offline_callback(handle, call_back_handle): + """ + :brief Unregister event handle callback function + :param handle: The handle of the device + :param call_back_handle: The handle of device offline callback function + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + call_back_handle_c = c_void_p() + call_back_handle_c.value = call_back_handle + + status = dll.GXUnregisterDeviceOfflineCallback(handle, call_back_handle_c) + return status + + +''' +if hasattr(dll, 'GXFlushEvent'): + def gx_flush_event(handle): + """ + :brief Empty the device event, such as the frame exposure to end the event data queue + :param handle: The handle of the device + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXFlushEvent(handle_c) + return status + + +if hasattr(dll, 'GXGetEventNumInQueue'): + def gx_get_event_num_in_queue(handle): + """ + :brief Get the number of the events in the current remote device event queue cache. + :param handle: The handle of the device + :return: status: State return value, See detail in GxStatusList + event_num: event number. + """ + handle_c = c_void_p() + handle_c.value = handle + + event_num = c_uint() + + status = dll.GXGetEventNumInQueue(handle_c, byref(event_num)) + return status, event_num.value + + +FEATURE_CALL = CFUNCTYPE(None, c_uint, c_void_p) +if hasattr(dll, 'GXRegisterFeatureCallback'): + def gx_register_feature_callback(handle, call_back, feature_id): + """ + :brief Register device attribute update callback function. + When the current value of the device property has updated, or the accessible property is changed, + call this callback function. + :param handle: The handle of the device + :param call_back: The user event handle callback function(@ FEATURE_CALL) + :param feature_id: The feature code ID + :return: status: State return value, See detail in GxStatusList + call_back_handle: The handle of property update callback function, + to unregister the callback function. + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + call_back_handle = c_void_p() + status = dll.GXRegisterFeatureCallback(handle_c, None, call_back, feature_id_c, byref(call_back_handle)) + + return status, call_back_handle.value + + +if hasattr(dll, 'GXUnregisterFeatureCallback'): + """ + """ + def gx_unregister_feature_callback(handle, feature_id, call_back_handle): + """ + :brief Unregister device attribute update callback function + :param handle: The handle of the device + :param feature_id: The feature code ID + :param call_back_handle: Handle of property update callback function + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + feature_id_c = c_int() + feature_id_c.value = feature_id + + call_back_handle_c = c_void_p() + call_back_handle_c.value = call_back_handle + + status = dll.GXUnregisterFeatureCallback(handle_c, feature_id_c, call_back_handle_c) + return status +''' + +if hasattr(dll, 'GXExportConfigFile'): + def gx_export_config_file(handle, file_path): + """ + :brief Export the current parameter of the camera to the configuration file. + :param handle: The handle of the device + Type: Long, Greater than 0 + :param file_path: The path of the configuration file that to be generated + Type: str + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + file_path_c = create_string_buffer(string_encoding(file_path)) + status = dll.GXExportConfigFile(handle_c, byref(file_path_c)) + + return status + + +if hasattr(dll, 'GXImportConfigFile'): + def gx_import_config_file(handle, file_path, verify): + """ + :brief Import the configuration file for the camera + :param handle: The handle of the device + Type: Long, Greater than 0 + :param file_path: The path of the configuration file(str) + Type: str + :param verify: If this value is true, all imported values will be read out + to check whether they are consistent. + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + verify_c = c_bool() + verify_c.value = verify + + file_path_c = create_string_buffer(string_encoding(file_path)) + status = dll.GXImportConfigFile(handle_c, byref(file_path_c), verify_c) + return status + + +if hasattr(dll, 'GXReadRemoteDevicePort'): + def gx_read_remote_device_port(handle, address, buff, size): + """ + :brief Read data for user specified register. + :param handle: The handle of the device + :param address: Register address + :param buff: Output data buff + :param size: Buff size + :return: status: State return value, See detail in GxStatusList + size: Returns the length of the actual read register + """ + handle_c = c_void_p() + handle_c.value = handle + + address_c = c_ulonglong() + address_c.value = address + + size_c = c_uint() + size_c.value = size + + status = dll.GXReadRemoteDevicePort(handle_c, address_c, byref(buff), byref(size_c)) + return status, buff + + +if hasattr(dll, 'GXWriteRemoteDevicePort'): + def gx_write_remote_device_port(handle, address, buff, size): + """ + :brief Writes user specified data to a user specified register. + :param handle: The handle of the device + :param address: Register address + :param buff: User data + :param size: User data size + :return: status: State return value, See detail in GxStatusList + size: Returns the length of the actual write register + """ + handle_c = c_void_p() + handle_c.value = handle + + address_c = c_ulonglong() + address_c.value = address + + size_c = c_uint() + size_c.value = size + + buff_c = c_int() + buff_c.value = buff + + status = dll.GXWriteRemoteDevicePort(handle_c, address_c, byref(buff_c), byref(size_c)) + return status, size_c.value + +''' +if hasattr(dll, 'GXGigEIpConfiguration'): + def gx_gige_ip_configuration(mac_address, ipconfig_flag, ip_address, subnet_mask, default_gateway, user_id): + """ + "brief Configure the static IP address of the camera + :param mac_address: The MAC address of the device(str) + :param ipconfig_flag: IP Configuration mode(GxIPConfigureModeList) + :param ip_address: The IP address to be set(str) + :param subnet_mask: The subnet mask to be set(str) + :param default_gateway: The default gateway to be set(str) + :param user_id: The user-defined name to be set(str) + :return: status: State return value, See detail in GxStatusList + """ + mac_address_c = create_string_buffer(string_encoding(mac_address)) + ip_address_c = create_string_buffer(string_encoding(ip_address)) + subnet_mask_c = create_string_buffer(string_encoding(subnet_mask)) + default_gateway_c = create_string_buffer(string_encoding(default_gateway)) + user_id_c = create_string_buffer(string_encoding(user_id)) + + status = dll.GXGigEIpConfiguration(mac_address_c, ipconfig_flag, + ip_address_c, subnet_mask_c, + default_gateway_c, user_id_c) + return status + + +if hasattr(dll, 'GXGigEForceIp'): + def gx_gige_force_ip(mac_address, ip_address, subnet_mask, default_gate_way): + """ + :brief Execute the Force IP + :param mac_address: The MAC address of the device(str) + :param ip_address: The IP address to be set(str) + :param subnet_mask: The subnet mask to be set(str) + :param default_gate_way: The default gateway to be set(str) + :return: status: State return value, See detail in GxStatusList + """ + mac_address_c = create_string_buffer(string_encoding(mac_address)) + ip_address_c = create_string_buffer(string_encoding(ip_address)) + subnet_mask_c = create_string_buffer(string_encoding(subnet_mask)) + default_gate_way_c = create_string_buffer(string_encoding(default_gate_way)) + + status = dll.GXGigEForceIp(mac_address_c, ip_address_c, subnet_mask_c, default_gate_way_c) + return status +''' + +if hasattr(dll, 'GXGigEResetDevice'): + def gx_gige_reset_device(mac_address, reset_device_mode): + """ + :brief Reconnection/Reset + :param mac_address: The MAC address of the device(str) + :param reset_device_mode: Reconnection mode, refer to GxResetDeviceModeEntry + :return: status: State return value, See detail in GxStatusList + """ + mac_address_c = create_string_buffer(string_encoding(mac_address)) + reset_device_mode_c = c_uint() + reset_device_mode_c.value = reset_device_mode + + status = dll.GXGigEResetDevice(mac_address_c, reset_device_mode_c) + return status + + +if hasattr(dll, 'GXSetAcqusitionBufferNumber'): + def gx_set_acquisition_buffer_number(handle, buffer_num): + """ + :brief Users Set Acquisition buffer Number + :param handle: The handle of the device + Type: Long, Greater than 0 + :param buffer_num: Acquisition buffer Number + Type: int, Greater than 0 + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + buffer_num_c = c_uint64() + buffer_num_c.value = buffer_num + + status = dll.GXSetAcqusitionBufferNumber(handle_c, buffer_num_c) + return status + +''' +if hasattr(dll, 'GXStreamOn'): + def gx_stream_on(handle): + """ + :brief Start acquisition + :param handle: The handle of the device + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXStreamOn(handle_c) + return status + + +if hasattr(dll, 'GXDQBuf'): + def gx_dequeue_buf(handle, time_out): + """ + :brief Get a image + After the image processing is completed, the gx_queue_buf interface needs to be called + otherwise the collection will not be able to continue. + :param handle: The handle of the device + :param time_out: The timeout time of capture image.(unit: ms) + :return: status: State return value, See detail in GxStatusList + frame_data: Image data + frame_data_p: Image buff address + """ + handle_c = c_void_p() + handle_c.value = handle + + time_out_c = c_uint() + time_out_c.value = time_out + + frame_data_p = c_void_p() + status = dll.GXDQBuf(handle_c, byref(frame_data_p), time_out_c) + + frame_data = GxFrameData() + memmove(addressof(frame_data), frame_data_p.value, sizeof(frame_data)) + return status, frame_data, frame_data_p.value + + +if hasattr(dll, 'GXQBuf'): + def gx_queue_buf(handle, frame_data_p): + """ + :brief Put an image Buff back to the GxIAPI library and continue to be used for collection. + :param handle: The handle of the device + :param frame_data_p: Image buff address + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + frame_data_p_p = c_void_p() + frame_data_p_p.value = frame_data_p + + status = dll.GXQBuf(handle_c, frame_data_p_p) + return status + + +if hasattr(dll, 'GXDQAllBufs'): + def gx_dequeue_all_bufs(handle, buff_num, time_out): + """ + :brief Get images + After the image processing is completed, the gx_queue_all_bufs interface needs to be called + otherwise the collection will not be able to continue. + :param handle: The handle of the device + :param buff_num: The number of images expected to be obtained + :param time_out: The timeout time of capture image.(unit: ms) + :return: status: State return value, See detail in GxStatusList + frame_data: Image data arrays + frame_count: The number of images that are actually returned + """ + handle_c = c_void_p() + handle_c.value = handle + + time_out_c = c_uint() + time_out_c.value = time_out + + frame_data_p = (c_void_p * buff_num)() + frame_count_c = c_uint() + + status = dll.GXDQAllBufs(handle_c, frame_data_p, buff_num, byref(frame_count_c), time_out_c) + frame_data = (GxFrameData * buff_num)() + + for i in range(buff_num): + memmove(addressof(frame_data[i]), frame_data_p[i], sizeof(GxFrameData)) + + return status, frame_data, frame_count_c.value + + +if hasattr(dll, 'GXQAllBufs'): + def gx_queue_all_bufs(handle): + """ + :brief The image data Buf is returned to the GxIAPI library and used for collection. + :param handle: The handle of the device + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXQAllBufs(handle_c) + return status + + +if hasattr(dll, 'GXStreamOff'): + def gx_stream_off(handle): + """ + :brief Stop acquisition + :param handle: The handle of the device + :return: status: State return value, See detail in GxStatusList + """ + handle_c = c_void_p() + handle_c.value = handle + + status = dll.GXStreamOff(handle_c) + return status +''' + + +def string_encoding(string): + """ + :breif Python3.X: String encoded as bytes + :param string + :return: + """ + if sys.version_info.major == 3: + string = string.encode() + return string + + +def string_decoding(string): + """ + :brief Python3.X: bytes decoded as string + :param string + :return: + """ + if sys.platform == 'linux2' or sys.platform == 'linux': + try: + string = string.decode() + except UnicodeDecodeError: + string = string.decode("gbk") + else: + try: + string = string.decode("gbk") + except UnicodeDecodeError: + string = string.decode() + return string + + +def range_check(value, min_value, max_value, inc_value=0): + """ + :brief Determine if the input parameter is within range + :param value: input value + :param min_value: max value + :param max_value: min value + :param inc_value: step size, default=0 + :return: True/False + """ + if value < min_value: + return False + elif value > max_value: + return False + elif (inc_value != 0) and (value != int(value / inc_value) * inc_value): + return False + return True diff --git a/src/test/camera.py b/src/test/camera.py deleted file mode 100644 index 0065ae9..0000000 --- a/src/test/camera.py +++ /dev/null @@ -1,461 +0,0 @@ -# version:1.0.1905.9051 -import faulthandler -import signal -import sys -from typing import Optional, Union - -import cv2 -import numpy -# from PIL import Image -from PyQt5 import QtGui, QtWidgets, uic -from PyQt5.QtCore import QObject, Qt, QThread, pyqtSignal -from PyQt5.QtGui import QColor, QImage, QPixmap -from PyQt5.QtWidgets import * - -import qimage2ndarray -import src.test.vision_test.libvision as libvision -import src.test.vision_test.object_detection.utils.visualization_utils as vis_util -from src.lib.watcher import Watcher -from src.test.vision_test.libvision import * - -TMP_DIR = "/tmp/vt40b" - -faulthandler.enable() -signal.signal(signal.SIGINT, lambda a, b: quit()) - -if "--sim-camera" in sys.argv: - simulate = True -else: - simulate = False - -if "--cpu" in sys.argv: - os.environ["CUDA_VISIBLE_DEVICES"] = "" - -if simulate: - from galaxy_camera_dummy import * -else: - from galaxy_camera import * - -light_red = QColor(255, 230, 230) -light_green = QColor(230, 255, 230) - - -class MainWindow(QtWidgets.QMainWindow): - keyPressed = QtCore.pyqtSignal(QtCore.QEvent) - new_frame_for_detect_signal = pyqtSignal(numpy.ndarray) - new_frame_for_render_signal = pyqtSignal(numpy.ndarray) - - def __init__(self): - super().__init__() - self.video_frames = {} - self.ui = uic.loadUi("src/test/camera_test/camera_test.ui", self) - - self.ICON_OK = QtGui.QPixmap("data/icons/ok.png") - self.ICON_KO = QtGui.QPixmap("data/icons/ko.png") - self.ICON_WARNING = QtGui.QPixmap("data/icons/warning.png") - - # INIT WATCHER - self.watcher = Watcher(self.watch_table) - self.vision_test = libvision() - - # INIT DETECTIONS TABLE - self.table_detections.setColumnCount(5) - self.table_detections.setColumnWidth(0, 50) - self.table_detections.setColumnWidth(1, 100) - self.table_detections.setColumnWidth(2, 50) - self.table_detections.setColumnWidth(3, 100) - self.table_detections.horizontalHeader().setStretchLastSection(True) - self.table_detections.setHorizontalHeaderLabels(["Zone", "Class", "Score", "Expected", "Result"]) - self.table_detections.setRowCount(len(self.vision_test.wires_zones) + len(self.vision_test.terminals_zones)) - self.table_detections.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) - self.table_detections.verticalHeader().setDefaultSectionSize(20) - - # DETECTION TABLE SETUP - i = 0 - for zone in self.vision_test.wires_zones.keys(): - self.table_detections.setItem(i, 0, QTableWidgetItem(zone)) - i += 1 - for zone in self.vision_test.terminals_zones.keys(): - self.table_detections.setItem(i, 0, QTableWidgetItem(zone)) - i += 1 - - self.wires_output_dict = None - self.terminals_output_dict = None - self.current_global_test_result = "UNDEF" - self.label_global_test_result.setScaledContents(True) - self.datamatrix = None - self.flag_detect_wires_on = False - self.flag_detect_terminals_on = False - self.flag_detect_datamatrix_on = False - self.flag_save_video_on = False - self.raw_image = gx.RawImage - self.qt_image = QImage - self.CameraThread = QThread() - self.DetectThread = QThread() - self.RenderThread = QThread() - self.CameraClass = CameraClass(self) - self.DetectClass = DetectClass(self) - self.RenderClass = RenderClass(self) - self.RenderClass.color_correction_param = self.CameraClass.color_correction_param - self.RenderClass.contrast_lut = self.CameraClass.contrast_lut - self.RenderClass.gamma_lut = self.CameraClass.gamma_lut - self.CameraClass.moveToThread(self.CameraThread) - self.DetectClass.moveToThread(self.DetectThread) - self.RenderClass.moveToThread(self.RenderThread) - self.CameraThread.started.connect(self.CameraClass.start) - self.DetectThread.started.connect(self.DetectClass.start) - self.RenderThread.started.connect(self.RenderClass.start) - self.CameraThread.start() - self.RenderThread.start() - self.DetectThread.start() - self.keyPressed.connect(self.on_key) - self.new_frame_for_detect_signal.connect(self.DetectClass.detect) - self.new_frame_for_render_signal.connect(self.RenderClass.render) - self.wires_slider.valueChanged.connect(self.wires_threshold_set) - self.terminals_slider.valueChanged.connect(self.terminals_threshold_set) - self.slider_red.valueChanged.connect(self.change_balance_red) - self.slider_green.valueChanged.connect(self.change_balance_green) - self.slider_blue.valueChanged.connect(self.change_balance_blue) - self.slider_red.setValue(int(self.CameraClass.balance_red * 100)) - self.slider_green.setValue(int(self.CameraClass.balance_green * 100)) - self.slider_blue.setValue(int(self.CameraClass.balance_blue * 100)) - self.checkBox_wires.stateChanged.connect(self.enable_wires) - self.checkBox_terminals.stateChanged.connect(self.enable_terminals) - self.checkBox_datamatrix.stateChanged.connect(self.enable_datamatrix) - self.btn_save_image.clicked.connect(self.save_frame_masked) - self.label_red.setText("{:.2f}".format(self.CameraClass.balance_red)) - self.label_green.setText("{:.2f}".format(self.CameraClass.balance_green)) - self.label_blue.setText("{:.2f}".format(self.CameraClass.balance_blue)) - self.combo_vision_recipe.addItems(self.vision_test.recipes.keys()) - self.change_recipe() - self.combo_vision_recipe.currentIndexChanged.connect(self.change_recipe) - self.slider_zoom.valueChanged.connect(self.change_zoom) - - def change_zoom(self, zoom): - self.RenderClass.render_mutex.lock() - self.DetectClass.detect_mutex.lock() - self.vision_test.update_scale(zoom) - self.label_zoom.setText("{:2d}%".format(zoom)) - self.image.setFixedSize(self.vision_test.image_height_scaled, self.vision_test.image_width_scaled) - self.RenderClass.render_mutex.unlock() - self.DetectClass.detect_mutex.unlock() - - def update_global_test_result(self): - global_test_result = self.vision_test.global_test_result() - if global_test_result != self.current_global_test_result: - self.current_global_test_result = global_test_result - if global_test_result == "OK": - self.label_global_test_result.setPixmap(QtGui.QPixmap(self.ICON_OK)) - else: - self.label_global_test_result.setPixmap(QtGui.QPixmap(self.ICON_KO)) - - def change_recipe(self): - self.vision_test.current_recipe = str(self.combo_vision_recipe.currentText()) - i = 0 - for zone in self.vision_test.wires_zones.keys(): - self.table_detections.setItem(i, 3, QTableWidgetItem( - self.vision_test.recipes[self.vision_test.current_recipe]["wires"][zone])) - i += 1 - for zone in self.vision_test.terminals_zones.keys(): - self.table_detections.setItem(i, 3, QTableWidgetItem( - self.vision_test.recipes[self.vision_test.current_recipe]["terminals"][zone])) - i += 1 - - def enable_wires(self, val): - self.flag_detect_wires_on = val - - def enable_terminals(self, val): - self.flag_detect_terminals_on = val - - def enable_datamatrix(self, val): - self.flag_detect_datamatrix_on = val - - def change_balance_red(self, val): - self.label_red.setText("{:.2f}".format(val / 100)) - self.CameraClass.set_balance_red(val / 100) - - def change_balance_green(self, val): - self.label_green.setText("{:.2f}".format(val / 100)) - self.CameraClass.set_balance_green(val / 100) - - def change_balance_blue(self, val): - self.label_blue.setText("{:.2f}".format(val / 100)) - self.CameraClass.set_balance_blue(val / 100) - - def wires_threshold_set(self, val): - self.vision_test.wires_threshold = val / 100 - - def terminals_threshold_set(self, val): - self.vision_test.terminals_threshold = val / 100 - - def keyPressEvent(self, event): - super(MainWindow, self).keyPressEvent(event) - self.keyPressed.emit(event) - - def on_key(self, event): - if event.key() == QtCore.Qt.Key_Space: - self.save_frame() - if event.key() == QtCore.Qt.Key_V: - self.flag_save_video_on = not self.flag_save_video_on - if self.flag_save_video_on: - self.video_frames.clear() - else: - self.save_video() - - elif event.key() == QtCore.Qt.Key_Q: - self.ui.close() - - @QtCore.pyqtSlot(QImage) - def update_image(self, img_camera): - self.image.setPixmap(QPixmap.fromImage(img_camera)) - self.update_global_test_result() - - @QtCore.pyqtSlot(gx.RawImage) - @QtCore.pyqtSlot(np.ndarray) - def dispatch_new_frame(self, gxframe): - if simulate: - self.numpy_image_rot = gxframe - t1 = t2 = t3 = t4 = time.time() - else: - t1 = time.time() - rgb_image = gxframe.convert("RGB") # 0.021 - t2 = time.time() - rgb_image.image_improvement(self.CameraClass.color_correction_param, self.CameraClass.contrast_lut, - self.CameraClass.gamma_lut) - t3 = time.time() - numpy_image = rgb_image.get_numpy_array() # 0.000 - self.numpy_image_rot = numpy.rot90(numpy_image, k=-1) # 0.077 - # self.numpy_image_rot = numpy_image - - t4 = time.time() - - if self.flag_save_video_on: - self.buffer_frame(self.numpy_image_rot) - - if self.DetectClass.detect_mutex.tryLock(): - self.new_frame_for_detect_signal.emit(self.numpy_image_rot) - self.DetectClass.detect_mutex.unlock() - else: - print("detect signal skip") - - if self.RenderClass.render_mutex.tryLock(): - self.new_frame_for_render_signal.emit(self.numpy_image_rot) - self.RenderClass.render_mutex.unlock() - else: - print("render signal skip") - - self.watcher.watch("DISPATCH convert", "{:.3f}".format(t2 - t1)) - self.watcher.watch("DISPATCH improve", "{:.3f}".format(t3 - t2)) - self.watcher.watch("DISPATCH np_rot", "{:.3f}".format(t4 - t3)) - - # print("DISPATCH conv={:.3f} improv={:.3f} np_rot={:.3f} ".format(t2 - t1, t3 - t2,t4-t3)) - - def save_frame(self): - - if not os.path.exists(TMP_DIR): - os.mkdir(TMP_DIR) - filename = TMP_DIR + "/{:.1f}.png".format(time.time()) - print("saving " + filename) - image_np_bgr = cv2.cvtColor(self.numpy_image_rot, cv2.COLOR_RGB2BGR) - cv2.imwrite(filename, image_np_bgr) - - def save_frame_masked(self): - - if not os.path.exists(TMP_DIR): - os.mkdir(TMP_DIR) - filename = TMP_DIR + "/{:.1f}.png".format(time.time()) - print("saving " + filename) - image_np_bgr = cv2.cvtColor(self.numpy_image_rot, cv2.COLOR_RGB2BGR) - image_np_bgr[self.vision_test.img_save_mask] = self.vision_test.img_solid_black_mask[ - self.vision_test.img_save_mask] - cv2.imwrite(filename, image_np_bgr) - - def save_video(self): - if not os.path.exists(TMP_DIR): - os.mkdir(TMP_DIR) - video_dir = TMP_DIR + "/video" - if not os.path.exists(video_dir): - os.mkdir(video_dir) - for filename, frame in self.video_frames.items(): - filepath = video_dir + "/" + filename - print("saving " + filepath) - image_np_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) - cv2.imwrite(filepath, image_np_bgr) - self.video_frames.clear() - - def buffer_frame(self, frame): - filename = "{:.1f}.png".format(time.time()) - self.video_frames[filename] = copy.deepcopy(frame) - - -class DetectClass(QObject): - new_detection_signal = pyqtSignal() - - def __init__(self, parent): - super().__init__() - self.detect_mutex = QtCore.QMutex() - self.parent = parent - - print("Init detect thread") - - @QtCore.pyqtSlot(numpy.ndarray) - def detect(self, numpy_image_rot): - if self.detect_mutex.tryLock(): - - # WIRES - t4 = time.time() - if self.parent.flag_detect_wires_on: - wires_img = numpy_image_rot[ - self.parent.vision_test.wires_crop["ymin"]:self.parent.vision_test.wires_crop["ymax"], - self.parent.vision_test.wires_crop["xmin"]:self.parent.vision_test.wires_crop["xmax"]] - self.parent.wires_output_dict = self.parent.vision_test.check_wires(wires_img) - # time.sleep(1) #simulate slowness - t5 = time.time() - # self.parent.wires_keypoints = self.parent.vision_test.find_wires_keypoints(self.parent.wires_output_dict) - t6 = time.time() - - # TERMINALS - if self.parent.flag_detect_terminals_on: - terminals_img = numpy_image_rot[ - self.parent.vision_test.terminals_crop["ymin"]:self.parent.vision_test.terminals_crop[ - "ymax"], - self.parent.vision_test.terminals_crop["xmin"]:self.parent.vision_test.terminals_crop[ - "xmax"]] - self.parent.terminals_output_dict = self.parent.vision_test.check_terminals(terminals_img) - t7 = time.time() - - # DATAMATRIX - if self.parent.flag_detect_datamatrix_on: - datamatrix_img = numpy_image_rot[self.parent.vision_test.datamatrix_crop["ymin"]: - self.parent.vision_test.datamatrix_crop["ymax"], - self.parent.vision_test.datamatrix_crop["xmin"]: - self.parent.vision_test.datamatrix_crop["xmax"]] - self.parent.datamatrix = self.parent.vision_test.read_datamatrix(datamatrix_img) - t8 = time.time() - - self.parent.watcher.watch("DETECT wires", "{:.3f}".format(t5 - t4)) - self.parent.watcher.watch("DETECT w. keypoints", "{:.3f}".format(t6 - t5)) - self.parent.watcher.watch("DETECT terminals", "{:.3f}".format(t7 - t6)) - self.parent.watcher.watch("DETECT datamatrix", "{:.3f}".format(t8 - t7)) - - # print("DETECT wires={:.3f} keyp={:.3f} term={:.3f} dmx={:.3f}".format( t5 - t4,t6-t5,t7-t6,t8-t7)) - self.new_detection_signal.emit() - self.detect_mutex.unlock() - else: - print("DETECT Mutex skip") - - def start(self): - print("Init detect slot") - - -class RenderClass(QObject): - update_gui = pyqtSignal(QImage) - contrast_lut: Optional[Buffer] - color_correction_param: int - cam: Union[None, U3VDevice, U2Device, GEVDevice] - gamma_lut: Optional[Buffer] - - def __init__(self, parent): - super().__init__() - self.img_out = numpy.array([]) - self.render_mutex = QtCore.QMutex() - self.app = None - self.image_in = gx.RawImage - self.flag_new_cycle = False - self.parent = parent - - print("Init render thread") - - def start(self): - self.update_gui.connect(self.parent.update_image) - print("Init render slot") - - @QtCore.pyqtSlot(numpy.ndarray) - def render(self, numpy_image_rot): - if self.render_mutex.tryLock(): - - wires_dict = self.parent.wires_output_dict - terminals_dict = self.parent.terminals_output_dict - - t1 = time.time() - image_qt = qimage2ndarray.array2qimage(numpy_image_rot) - # image_qt = QImage(numpy_image_rot, numpy_image_rot.shape[1], numpy_image_rot.shape[0], QImage.Format_RGB888) - out_qt = image_qt.scaled(self.parent.vision_test.image_height_scaled, - self.parent.vision_test.image_width_scaled, Qt.KeepAspectRatio) - - vis_util.visualize_zones(out_qt, - [self.parent.vision_test.wires_crop_qt, self.parent.vision_test.terminals_crop_qt, - self.parent.vision_test.datamatrix_crop_qt]) - vis_util.visualize_subzones(out_qt, self.parent.vision_test.terminals_zones, - self.parent.vision_test.image_scale) - t2 = time.time() - if self.parent.flag_detect_wires_on: - if wires_dict is not None: - vis_util.visualize_wires_qt(out_qt, wires_dict, self.parent.vision_test.wires_category_index, - crop=self.parent.vision_test.wires_crop_qt, - min_score_thresh=self.parent.vision_test.wires_threshold) - # update GUI table - current_recipe = self.parent.vision_test.recipes[self.parent.combo_vision_recipe.currentText()] - i = 0 - for name, zone in self.parent.vision_test.wires_zones.items(): - if zone["detection"] is not None: - self.parent.table_detections.setItem(i, 1, QTableWidgetItem(zone["detection"]["class"])) - self.parent.table_detections.setItem(i, 2, QTableWidgetItem( - "{:.3f}".format(zone["detection"]["score"]))) - else: - self.parent.table_detections.setItem(i, 1, QTableWidgetItem("no detection")) - self.parent.table_detections.setItem(i, 2, QTableWidgetItem("-")) - self.parent.table_detections.setItem(i, 4, QTableWidgetItem(zone["result"])) - if zone["result"] == "OK": - self.parent.table_detections.item(i, 4).setBackground(light_green) - else: - self.parent.table_detections.item(i, 4).setBackground(light_red) - i += 1 - - if self.parent.flag_detect_terminals_on: - if terminals_dict is not None: - vis_util.visualize_terminals_qt(out_qt, terminals_dict, - self.parent.vision_test.terminals_category_index, - crop=self.parent.vision_test.terminals_crop_qt, - min_score_thresh=self.parent.vision_test.terminals_threshold) - # update GUI table - i = len(self.parent.vision_test.wires_zones) - for name, zone in self.parent.vision_test.terminals_zones.items(): - if zone["detection"] is not None: - self.parent.table_detections.setItem(i, 1, QTableWidgetItem(zone["detection"]["class"])) - self.parent.table_detections.setItem(i, 2, QTableWidgetItem( - "{:.3f}".format(zone["detection"]["score"]))) - else: - self.parent.table_detections.setItem(i, 1, QTableWidgetItem("no detection")) - self.parent.table_detections.setItem(i, 2, QTableWidgetItem("-")) - self.parent.table_detections.setItem(i, 4, QTableWidgetItem(zone["result"])) - if zone["result"] == "OK": - self.parent.table_detections.item(i, 4).setBackground(light_green) - else: - self.parent.table_detections.item(i, 4).setBackground(light_red) - i += 1 - - if self.parent.flag_detect_datamatrix_on: - vis_util.visualize_datamatrix_qt(out_qt, self.parent.datamatrix, - crop=self.parent.vision_test.datamatrix_crop_qt, - scale=self.parent.vision_test.image_scale) - - self.update_gui.emit(out_qt) - - t3 = time.time() - self.parent.watcher.watch("RENDER scaling", "{:.3f}".format(t2 - t1)) - self.parent.watcher.watch("RENDER visualize", "{:.3f}".format(t3 - t3)) - # print("RENDER scale={:.3f} render={:.3f}".format(t2 - t1, t3 - t2)) - if self.app is not None: - self.app.processEvents() - self.render_mutex.unlock() - else: - print("RENDER Mutex skip") - - -if __name__ == "__main__": - app = QApplication(sys.argv) - mainWindow = MainWindow() - mainWindow.show() - mainWindow.RenderClass.app = app - sys.exit(app.exec_()) diff --git a/src/test/camera_test.ui b/src/test/camera_test.ui deleted file mode 100755 index 41c6f5a..0000000 --- a/src/test/camera_test.ui +++ /dev/null @@ -1,563 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1211 - 976 - - - - MainWindow - - - - - - 790 - 40 - 151 - 21 - - - - 100 - - - 50 - - - Qt::Horizontal - - - - - - 790 - 70 - 151 - 31 - - - - 100 - - - 50 - - - Qt::Horizontal - - - - - - 710 - 80 - 59 - 15 - - - - Terminals - - - - - - 710 - 40 - 59 - 15 - - - - Wires - - - - - - 710 - 120 - 59 - 15 - - - - Red - - - - - - 790 - 110 - 151 - 31 - - - - 300 - - - 50 - - - Qt::Horizontal - - - - - - 710 - 160 - 59 - 15 - - - - Green - - - - - - 790 - 150 - 151 - 31 - - - - 300 - - - 50 - - - Qt::Horizontal - - - - - - 710 - 200 - 59 - 15 - - - - Blue - - - - - - 790 - 190 - 151 - 31 - - - - 300 - - - 50 - - - Qt::Horizontal - - - - - - 1060 - 40 - 85 - 21 - - - - Wires - - - - - - 1060 - 60 - 85 - 21 - - - - Terminals - - - - - - 1060 - 80 - 91 - 21 - - - - Datamatrix - - - - - - 950 - 120 - 59 - 15 - - - - 1 - - - - - - 950 - 160 - 59 - 15 - - - - 1 - - - - - - 950 - 200 - 59 - 15 - - - - 1 - - - - - - 700 - 270 - 441 - 661 - - - - 0 - - - - Watches - - - - - 10 - 10 - 421 - 611 - - - - - - - Detections - - - - - 10 - 10 - 421 - 611 - - - - - - - - - 1060 - 120 - 80 - 23 - - - - Save image - - - - - - 800 - 230 - 131 - 23 - - - - - - - 710 - 230 - 81 - 16 - - - - Vision recipe - - - - - - 790 - 10 - 151 - 21 - - - - 20 - - - 100 - - - 20 - - - Qt::Horizontal - - - - - - 710 - 10 - 59 - 15 - - - - Zoom - - - - - - 950 - 10 - 59 - 15 - - - - 20% - - - - - - 10 - 10 - 681 - 921 - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 679 - 919 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 500 - 500 - - - - - 5000 - 5000 - - - - border: 1px solid black - - - image - - - - - - - - - - 980 - 180 - 161 - 91 - - - - - 0 - 0 - - - - QFrame::Box - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 120 - 20 - - - - GLOBAL TEST RESULT - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 50 - 50 - - - - - 50 - 50 - - - - QFrame::NoFrame - - - - - - Qt::AlignCenter - - - - - - - - - - - 0 - 0 - 1211 - 20 - - - - - Menu - - - - - - - - Exit - - - - - - \ No newline at end of file diff --git a/src/test/camera_windows.py b/src/test/camera_windows.py new file mode 100644 index 0000000..c04f441 --- /dev/null +++ b/src/test/camera_windows.py @@ -0,0 +1,93 @@ +# version:1.0.1905.9051 +import time + +from src.components import gxipy as gx +from PIL import Image + + +def main(): + print("Initializing......") + + # create a device manager + device_manager = gx.DeviceManager() + dev_num, dev_info_list = device_manager.update_device_list() + if dev_num is 0: + print("Number of enumerated devices is 0") + return + + # open the first device + cam = device_manager.open_device_by_index(1) + + # exit when the camera is a mono camera + if cam.PixelColorFilter.is_implemented() is False: + print("This sample does not support mono camera.") + cam.close_device() + return + + # set continuous acquisition + cam.TriggerMode.set(gx.GxSwitchEntry.OFF) + + # set exposure + cam.ExposureTime.set(10000.0) + + # set gain + cam.Gain.set(10.0) + + # get param of improving image quality + if cam.GammaParam.is_readable(): + gamma_value = cam.GammaParam.get() + gamma_lut = gx.Utility.get_gamma_lut(gamma_value) + else: + gamma_lut = None + if cam.ContrastParam.is_readable(): + contrast_value = cam.ContrastParam.get() + contrast_lut = gx.Utility.get_contrast_lut(contrast_value) + else: + contrast_lut = None + if cam.ColorCorrectionParam.is_readable(): + color_correction_param = cam.ColorCorrectionParam.get() + else: + color_correction_param = 0 + + # start data acquisition + cam.stream_on() + time.sleep(0.1) + # acquisition image: num is the image number + num = 1 + for i in range(num): + # get raw image + raw_image = cam.data_stream[0].get_image() + time.sleep(0.1) + if raw_image is None: + print("Getting image failed.") + continue + + # get RGB image from raw image + rgb_image = raw_image.convert("RGB") + if rgb_image is None: + continue + + # improve image quality + rgb_image.image_improvement(color_correction_param, contrast_lut, gamma_lut) + + # create numpy array with data from raw image + numpy_image = rgb_image.get_numpy_array() + if numpy_image is None: + continue + + # show acquired image + img = Image.fromarray(numpy_image, 'RGB') + img.show() + + # print height, width, and frame ID of the acquisition image + print("Frame ID: %d Height: %d Width: %d" + % (raw_image.get_frame_id(), raw_image.get_height(), raw_image.get_width())) + + # stop data acquisition + cam.stream_off() + + # close device + cam.close_device() + +if __name__ == "__main__": + main()