This commit is contained in:
germano2239 2022-07-16 17:19:05 +02:00
parent d88adc4588
commit f27fd15543
9 changed files with 6301 additions and 1025 deletions

View File

@ -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

View File

@ -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'

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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_())

View File

@ -1,563 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1211</width>
<height>976</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QSlider" name="wires_slider">
<property name="geometry">
<rect>
<x>790</x>
<y>40</y>
<width>151</width>
<height>21</height>
</rect>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QSlider" name="terminals_slider">
<property name="geometry">
<rect>
<x>790</x>
<y>70</y>
<width>151</width>
<height>31</height>
</rect>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>710</x>
<y>80</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>Terminals</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>710</x>
<y>40</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>Wires</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>710</x>
<y>120</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>Red</string>
</property>
</widget>
<widget class="QSlider" name="slider_red">
<property name="geometry">
<rect>
<x>790</x>
<y>110</y>
<width>151</width>
<height>31</height>
</rect>
</property>
<property name="maximum">
<number>300</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>710</x>
<y>160</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>Green</string>
</property>
</widget>
<widget class="QSlider" name="slider_green">
<property name="geometry">
<rect>
<x>790</x>
<y>150</y>
<width>151</width>
<height>31</height>
</rect>
</property>
<property name="maximum">
<number>300</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>710</x>
<y>200</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>Blue</string>
</property>
</widget>
<widget class="QSlider" name="slider_blue">
<property name="geometry">
<rect>
<x>790</x>
<y>190</y>
<width>151</width>
<height>31</height>
</rect>
</property>
<property name="maximum">
<number>300</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_wires">
<property name="geometry">
<rect>
<x>1060</x>
<y>40</y>
<width>85</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Wires</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_terminals">
<property name="geometry">
<rect>
<x>1060</x>
<y>60</y>
<width>85</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Terminals</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_datamatrix">
<property name="geometry">
<rect>
<x>1060</x>
<y>80</y>
<width>91</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Datamatrix</string>
</property>
</widget>
<widget class="QLabel" name="label_red">
<property name="geometry">
<rect>
<x>950</x>
<y>120</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>1</string>
</property>
</widget>
<widget class="QLabel" name="label_green">
<property name="geometry">
<rect>
<x>950</x>
<y>160</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>1</string>
</property>
</widget>
<widget class="QLabel" name="label_blue">
<property name="geometry">
<rect>
<x>950</x>
<y>200</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>1</string>
</property>
</widget>
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>700</x>
<y>270</y>
<width>441</width>
<height>661</height>
</rect>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_watches">
<attribute name="title">
<string>Watches</string>
</attribute>
<widget class="QTableWidget" name="watch_table">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>421</width>
<height>611</height>
</rect>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab_detections">
<attribute name="title">
<string>Detections</string>
</attribute>
<widget class="QTableWidget" name="table_detections">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>421</width>
<height>611</height>
</rect>
</property>
</widget>
</widget>
</widget>
<widget class="QPushButton" name="btn_save_image">
<property name="geometry">
<rect>
<x>1060</x>
<y>120</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Save image</string>
</property>
</widget>
<widget class="QComboBox" name="combo_vision_recipe">
<property name="geometry">
<rect>
<x>800</x>
<y>230</y>
<width>131</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>710</x>
<y>230</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Vision recipe</string>
</property>
</widget>
<widget class="QSlider" name="slider_zoom">
<property name="geometry">
<rect>
<x>790</x>
<y>10</y>
<width>151</width>
<height>21</height>
</rect>
</property>
<property name="minimum">
<number>20</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>710</x>
<y>10</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>Zoom</string>
</property>
</widget>
<widget class="QLabel" name="label_zoom">
<property name="geometry">
<rect>
<x>950</x>
<y>10</y>
<width>59</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>20%</string>
</property>
</widget>
<widget class="QScrollArea" name="scrollArea">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>681</width>
<height>921</height>
</rect>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>679</width>
<height>919</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="image">
<property name="minimumSize">
<size>
<width>500</width>
<height>500</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>5000</width>
<height>5000</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">border: 1px solid black</string>
</property>
<property name="text">
<string>image</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>980</x>
<y>180</y>
<width>161</width>
<height>91</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>GLOBAL TEST RESULT</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_global_test_result">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1211</width>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuTools">
<property name="title">
<string>Menu</string>
</property>
<addaction name="actionExit"/>
</widget>
<addaction name="menuTools"/>
</widget>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -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()