首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >IDS摄像机: python包设置曝光参数(is_SetAutoParameter函数)

IDS摄像机: python包设置曝光参数(is_SetAutoParameter函数)
EN

Stack Overflow用户
提问于 2021-07-03 19:32:58
回答 1查看 1.9K关注 0票数 0

我正在使用IDS-3240CP-NIR相机,并使用伴随它们的pyueye包操作它们。由于这些相机是用来计算NDVI从两个不同的相机之间的图像,我需要确保他们有相同的参数,除了曝光,这将是自动调整照明条件和调整在后处理。问题是,我不知道如何设置自动曝光在pyueye,以产生良好的结果。当我使用IDS软件并打开自动曝光时,事情看起来很棒。但是当我尝试在软件中做这件事时,图像暴露得太明显了。

从文档中可以看出,设置自动曝光的方法有两种: pyueye.Is_SetAutoParameter函数(https://en.ids-imaging.com/manuals/ids-software-suite/ueye-manual/4.93/en/is_setautoparameter.html?q=set+auto+parameter)和pyueye.Is_AutoParameter函数(https://en.ids-imaging.com/manuals/ids-software-suite/ueye-manual/4.93/en/is_autoparameterautoexposure.html?q=aes)。Is_AutoParameter函数可能是基于文档如何讨论它的更好的方法,但是我还没有弄清楚如何使用这个函数(我相信我发送了错误类型的pval's)。相反,我一直在通过Is_SetAutoParameter设置自动快门速度,但结果仍然曝光过度。

下面是我正在运行的一些代码:

代码语言:javascript
运行
复制
    hCam = ueye.HIDS(1)
    sInfo = ueye.SENSORINFO()
    cInfo = ueye.CAMINFO()
    pcImageMemory = ueye.c_mem_p()
    MemID = ueye.int()
    rectAOI = ueye.IS_RECT()
    pitch = ueye.INT()
    nBitsPerPixel = ueye.INT(32)
    channels = 4
    m_nColorMode = ueye.IS_CM_RGBY8_PACKED
    bytes_per_pixel = int(nBitsPerPixel / 8)

    # Camera Init
    nRet = ueye.is_InitCamera(hCam, None)
    if nRet != ueye.IS_SUCCESS:
        print("is_InitCamera1 ERROR")

    # Get Sensor Info
    nRet = ueye.is_GetSensorInfo(hCam, sInfo)
    if nRet != ueye.IS_SUCCESS:
        print("is_GetSensorInfo ERROR")
    print(sInfo.strSensorName)

    # Set Display Mode
    nRet = ueye.is_SetDisplayMode(hCam, ueye.IS_SET_DM_DIB)

    # Set Color mode
    nRet = ueye.is_SetColorMode(hCam, ueye.IS_CM_RGBY8_PACKED)

    # Area of Interest
    print("rectAOI type:")
    print(type(rectAOI))
    nRet = ueye.is_AOI(hCam, ueye.IS_AOI_IMAGE_GET_AOI, rectAOI, ueye.sizeof(rectAOI))
    if nRet != ueye.IS_SUCCESS:
        print("is_AOI ERROR")

    # Define Width and Height
    width = rectAOI.s32Width
    height = rectAOI.s32Height

    # Prints out some information about the camera and the sensor
    print("Camera 1")
    print("Camera model:\t\t", sInfo.strSensorName.decode('utf-8'))
    print("Camera serial no.:\t", cInfo.SerNo.decode('utf-8'))
    print("Maximum image width:\t", width)
    print("Maximum image height:\t", height)
    print()

    # Allocate Image Memory
    nRet = ueye.is_AllocImageMem(hCam, width, height, nBitsPerPixel, pcImageMemory, MemID)
    if nRet != ueye.IS_SUCCESS:
        print("is_AllocImageMem ERROR")

    # Add to Sequence
    nRet = ueye.is_AddToSequence(hCam, pcImageMemory, MemID)
    if nRet != ueye.IS_SUCCESS:
        print("is_AddToSequence ERROR")

    # Capture Video
    nRet = ueye.is_CaptureVideo(hCam, ueye.IS_DONT_WAIT)
    if nRet != ueye.IS_SUCCESS:
        print("is_CaptureVideo ERROR")

    # Inquire Image Memory
    nRet = ueye.is_InquireImageMem(hCam, pcImageMemory, MemID, width, height, nBitsPerPixel, pitch)
    if nRet != ueye.IS_SUCCESS:
        print("is_InquireImageMem ERROR")

    # Image Display
    array = [0]

    # Generate Image File Name
    timestr = str(datetime.now().strftime('%Y-%m-%d_%H:%M:%S'))
    image_name = "/home/pi/LakeWheelerTurf/TurfImages/turfcam1_" + timestr + ".bmp"

    pval1 = ctypes.c_double(1)
    pval2 = ctypes.c_double(0)
    
    nRet = ueye.is_SetAutoParameter(hCam, ueye.IS_SET_ENABLE_AUTO_SHUTTER, pval1, pval2)

    # Continuous image display
    photo_counter = 0
    while (nRet == ueye.IS_SUCCESS):
        pval1 = ctypes.c_double(1)
        pval2 = ctypes.c_double(0)
        nRet = ueye.is_SetAutoParameter(hCam, ueye.IS_SET_ENABLE_AUTO_SHUTTER, pval1, pval2)
        nRet = ueye.is_SetAutoParameter(hCam, ueye.IS_GET_ENABLE_AUTO_SHUTTER, pval3, pval2)
        print(pval3.value)

        #Below is my attempt to get the is_AutoParameter function to work (unsuccessful)
        #pval1 = ctypes.c_void_p(1)
        #pval2 = ctypes.sizeof(pval1)
        #nRet = ueye.is_AutoParameter(hCam, ueye.IS_AES_CMD_SET_ENABLE, pval1, pval_sz)
        #if nRet != ueye.IS_SUCCESS:
        #    print("AES ERROR")

        while array[0] == 0:
            array = ueye.get_data(pcImageMemory, width.value, height.value, nBitsPerPixel.value, pitch.value,
                                  copy=False)

        frame = np.reshape(array, (height.value, width.value, bytes_per_pixel))
        photo_counter += 1
        time.sleep(1)
        if photo_counter >= 10:
            break

    matplotlib.pyplot.imsave(image_name, frame)
    ueye.is_FreeImageMem(hCam, pcImageMemory, MemID)
    ueye.is_ExitCamera(hCam)
    return image_name

如果有人能帮我解决这个问题,我会非常感激的,我已经花了很长时间来研究这个问题,但没有结果。下面是一些图像的样本,我可以从GUI和pyueye中获得。谢谢!

EN

回答 1

Stack Overflow用户

发布于 2022-04-12 09:40:23

Python移植缺少一个is_SetExposureTime实现,它支持显式和自动暴露控制。我猜是个窃听器。

我在这里为IdsCamera类提供了我自己的实现,其中包含缺少的实现,以及获取和设置暴露的易于使用的方法。

代码语言:javascript
运行
复制
class IdsCamera:
    _is_SetExposureTime = ueye._bind("is_SetExposureTime",
                                     [ueye.ctypes.c_uint, ueye.ctypes.c_double,
                                      ueye.ctypes.POINTER(ueye.ctypes.c_double)], ueye.ctypes.c_int)
    IS_GET_EXPOSURE_TIME = 0x8000

    @staticmethod
    def is_SetExposureTime(hCam, EXP, newEXP):
        """
        Description

        The function is_SetExposureTime() sets the with EXP indicated exposure time in ms. Since this
        is adjustable only in multiples of the time, a line needs, the actually used time can deviate from
        the desired value.

        The actual duration adjusted after the call of this function is readout with the parameter newEXP.
        By changing the window size or the readout timing (pixel clock) the exposure time set before is changed also.
        Therefore is_SetExposureTime() must be called again thereafter.

        Exposure-time interacting functions:
            - is_SetImageSize()
            - is_SetPixelClock()
            - is_SetFrameRate() (only if the new image time will be shorter than the exposure time)

        Which minimum and maximum values are possible and the dependence of the individual
        sensors is explained in detail in the description to the uEye timing.

        Depending on the time of the change of the exposure time this affects only with the recording of
        the next image.

        :param hCam: c_uint (aka c-type: HIDS)
        :param EXP: c_double (aka c-type: DOUBLE) - New desired exposure-time.
        :param newEXP: c_double (aka c-type: double *) - Actual exposure time.
        :returns: IS_SUCCESS, IS_NO_SUCCESS

        Notes for EXP values:

        - IS_GET_EXPOSURE_TIME Returns the actual exposure-time through parameter newEXP.
        - If EXP = 0.0 is passed, an exposure time of (1/frame rate) is used.
        - IS_GET_DEFAULT_EXPOSURE Returns the default exposure time newEXP Actual exposure time
        - IS_SET_ENABLE_AUTO_SHUTTER : activates the AutoExposure functionality.
          Setting a value will deactivate the functionality.
          (see also 4.86 is_SetAutoParameter).
        """
        _hCam = ueye._value_cast(hCam, ueye.ctypes.c_uint)
        _EXP = ueye._value_cast(EXP, ueye.ctypes.c_double)
        ret = IdsCamera._is_SetExposureTime(_hCam, _EXP, ueye.ctypes.byref(newEXP) if newEXP is not None else None)
        return ret

    def __init__(self, selector=''):
        self.hCam = ueye.HIDS(0)  # 0: first available camera;  1-254: The camera with the specified camera ID
        self.sInfo = ueye.SENSORINFO()
        self.cInfo = ueye.CAMINFO()
        self.pcImageMemory = ueye.c_mem_p()
        self.MemID = ueye.INT()
        self.rectAOI = ueye.IS_RECT()
        self.pitch = ueye.INT()
        self.nBitsPerPixel = ueye.INT()
        self.m_nColorMode = ueye.INT()
        self.bytes_per_pixel = 0
        self.width = ueye.INT()
        self.height = ueye.INT()
        self.size = (-1, -1)
        self.ok = False
        self.error_str = ''
        self.last_frame = None

    def _error(self, err_str):
        self.error_str = err_str
        return

    def connect(self):
        self.error_str = ''

        # Starts the driver and establishes the connection to the camera
        rc = ueye.is_InitCamera(self.hCam, None)
        if rc != ueye.IS_SUCCESS:
            return self._error("is_InitCamera ERROR")

        # Reads out the data hard-coded in the non-volatile camera memory
        # and writes it to the data structure that cInfo points to
        rc = ueye.is_GetCameraInfo(self.hCam, self.cInfo)
        if rc != ueye.IS_SUCCESS:
            return self._error("is_GetCameraInfo ERROR")

        # You can query additional information about the sensor type used in the camera
        rc = ueye.is_GetSensorInfo(self.hCam, self.sInfo)
        if rc != ueye.IS_SUCCESS:
            return self._error("is_GetSensorInfo ERROR")

        rc = ueye.is_ResetToDefault(self.hCam)
        if rc != ueye.IS_SUCCESS:
            return self._error("is_ResetToDefault ERROR")

        # Set display mode to DIB
        rc = ueye.is_SetDisplayMode(self.hCam, ueye.IS_SET_DM_DIB)

        # Set the right color mode
        if int.from_bytes(self.sInfo.nColorMode.value, byteorder='big') == ueye.IS_COLORMODE_BAYER:
            # setup the color depth to the current windows setting
            ueye.is_GetColorDepth(self.hCam, self.nBitsPerPixel, self.m_nColorMode)
            self.bytes_per_pixel = int(self.nBitsPerPixel / 8)
            print("IS_COLORMODE_BAYER: ", )

        elif int.from_bytes(self.sInfo.nColorMode.value, byteorder='big') == ueye.IS_COLORMODE_CBYCRY:
            # for color camera models use RGB32 mode
            self.m_nColorMode = ueye.IS_CM_BGRA8_PACKED
            self.nBitsPerPixel = ueye.INT(32)
            self.bytes_per_pixel = int(self.nBitsPerPixel / 8)
            print("IS_COLORMODE_CBYCRY: ", )

        elif int.from_bytes(self.sInfo.nColorMode.value, byteorder='big') == ueye.IS_COLORMODE_MONOCHROME:
            # for color camera models use RGB32 mode
            self.m_nColorMode = ueye.IS_CM_MONO8
            self.nBitsPerPixel = ueye.INT(8)
            self.bytes_per_pixel = int(self.nBitsPerPixel / 8)
            print("IS_COLORMODE_MONOCHROME: ", )

        else:
            # for monochrome camera models use Y8 mode
            self.m_nColorMode = ueye.IS_CM_MONO8
            self.nBitsPerPixel = ueye.INT(8)
            self.bytes_per_pixel = int(self.nBitsPerPixel / 8)
            print("Color mode: not identified")

        print("\tm_nColorMode: \t\t", self.m_nColorMode)
        print("\tnBitsPerPixel: \t\t", self.nBitsPerPixel)
        print("\tbytes_per_pixel: \t\t", self.bytes_per_pixel)
        print()

        # Can be used to set the size and position of an "area of interest"(AOI) within an image
        rc = ueye.is_AOI(self.hCam, ueye.IS_AOI_IMAGE_GET_AOI, self.rectAOI, ueye.sizeof(self.rectAOI))
        if rc != ueye.IS_SUCCESS:
            return self._error("is_AOI ERROR")

        self.width = self.rectAOI.s32Width
        self.height = self.rectAOI.s32Height
        self.size = (self.width.value, self.height.value)

        # Prints out some information about the camera and the sensor
        print("Camera model:\t\t", self.sInfo.strSensorName.decode('utf-8'))
        print("Camera serial no.:\t", self.cInfo.SerNo.decode('utf-8'))
        print("Camera image size:\t", str(self.size))
        print()

        # Allocates an image memory for an image having its dimensions defined by width and height
        # and its color depth defined by nBitsPerPixel
        rc = ueye.is_AllocImageMem(self.hCam, self.width, self.height,
                                   self.nBitsPerPixel, self.pcImageMemory, self.MemID)
        if rc != ueye.IS_SUCCESS:
            return self._error("is_AllocImageMem ERROR")
        else:
            # Makes the specified image memory the active memory
            rc = ueye.is_SetImageMem(self.hCam, self.pcImageMemory, self.MemID)
            if rc != ueye.IS_SUCCESS:
                return self._error("is_SetImageMem ERROR")
            else:
                # Set the desired color mode
                rc = ueye.is_SetColorMode(self.hCam, self.m_nColorMode)

        # Activates the camera's live video mode (free run mode)
        rc = ueye.is_CaptureVideo(self.hCam, ueye.IS_DONT_WAIT)
        if rc != ueye.IS_SUCCESS:
            return self._error("is_CaptureVideo ERROR")

        # Enables the queue mode for existing image memory sequences
        rc = ueye.is_InquireImageMem(self.hCam, self.pcImageMemory, self.MemID,
                                     self.width, self.height, self.nBitsPerPixel, self.pitch)
        if rc != ueye.IS_SUCCESS:
            return self._error("is_InquireImageMem ERROR")
        else:
            print("IDS camera: connection ok")
            self.ok = True

    def grab_image(self):
        if not self.ok:
            return None
        # In order to display the image in an OpenCV window we need to...
        # ...extract the data of our image memory
        array = ueye.get_data(self.pcImageMemory, self.width, self.height, self.nBitsPerPixel, self.pitch, copy=False)
        # ...reshape it in an numpy array...
        frame = np.reshape(array, (self.height.value, self.width.value, self.bytes_per_pixel))

        # ...resize the image by a half
        # frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)
        self.last_frame = frame
        return frame

    def disconnect(self):
        # Releases an image memory that was allocated using is_AllocImageMem() and removes it from the driver management
        ueye.is_FreeImageMem(self.hCam, self.pcImageMemory, self.MemID)

        # Disables the hCam camera handle and releases the data structures and memory areas taken up by the uEye camera
        ueye.is_ExitCamera(self.hCam)

    def set_camera_exposure(self, level_us):
        """
        :param level_us: exposure level in micro-seconds, or zero for auto exposure
        
        note that you can never exceed 1000000/fps, but it is possible to change the fps
        """
        p1 = ueye.DOUBLE()
        if level_us == 0:
            rc = IdsCamera._is_SetExposureTime(self.hCam, ueye.IS_SET_ENABLE_AUTO_SHUTTER, p1)
            print(f'set_camera_exposure: set to auto')
        else:
            ms = ueye.DOUBLE(level_us / 1000)
            rc = IdsCamera._is_SetExposureTime(self.hCam, ms, p1)
            print(f'set_camera_exposure: requested {ms.value}, got {p1.value}')

    def get_camera_exposure(self, force_val=False):
        """
        returns the current exposure time in micro-seconds, or zero if auto exposure is on

        :param force_val: if True, will return level of exposure even if auto exposure is on
        """
        p1 = ueye.DOUBLE()
        p2 = ueye.DOUBLE()
        # we dump both auto-gain and auto exposure states:
        rc = ueye.is_SetAutoParameter(self.hCam, ueye.IS_GET_ENABLE_AUTO_GAIN, p1, p2)
        print(f'IS_GET_ENABLE_AUTO_GAIN={p1.value == 1}')
        rc = ueye.is_SetAutoParameter(self.hCam, ueye.IS_GET_ENABLE_AUTO_SHUTTER, p1, p2)
        print(f'IS_GET_ENABLE_AUTO_SHUTTER={p1.value == 1}')
        if (not force_val) and p1.value == 1:
            return 0  # auto exposure
        rc = IdsCamera._is_SetExposureTime(self.hCam, IdsCamera.IS_GET_EXPOSURE_TIME, p1)
        print(f'IS_GET_EXPOSURE_TIME={p1.value}')
        return p1.value * 1000
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68239400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档