• DepthAI-v2
  • Getting errors when I try to pan image after zooming

Hi I am playing around with the lossless zoom and was looking to incorporate it into the rgb_camera_control.py for a more interactive experience. What do I need to tear down in the pipeline.
I am able to switch to zooms but when I try to pan in the new zoom area I get the following error message

'Couldn't write data to stream: 'config' (X_LINK_ERROR)'

Below is the trace back

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.1\helpers\pydev\pydevd.py", line 1758, in <module>
    main()
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.1\helpers\pydev\pydevd.py", line 1752, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.1\helpers\pydev\pydevd.py", line 1147, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.1\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/work/depthai/depthai-main/examples/rgb_camera_control.py", line 128, in <module>
    configQueue.send(cfg)
RuntimeError: Communication exception - possible device error/misconfiguration. Original message 'Couldn't write data to stream: 'config' (X_LINK_ERROR)'

Thanks

  • erik replied to this.

    Hi erik,
    Thanks for responding. Below is the python code I am running on an OAK-1.
    I modified rgb_camera_control.py from the main python examples and added a 'z' key entry to change the zoom
    That appears to work but when I try to pan the new zoomed configuration it throws an exeception on the configQueue.send(cfg) after setting the Crop Rect for the change (Note first time through when cropX and cropY are zero it does not)
    RuntimeError: Communication exception - possible device error/misconfiguration. Original message 'Couldn't write data to stream: 'config' (X_LINK_ERROR)'

    Thanks again

    ----------------------------- rgb_camera_control_with_zoom.py ------------------------------

    #!/usr/bin/env python3
    
    """
    This example shows usage of Camera Control message as well as ColorCamera configInput to change crop x and y
    Uses 'WASD' controls to move the crop window, 'C' to capture a still image, 'T' to trigger autofocus, 'IOKL,.'
    for manual exposure/focus:
      Control:      key[dec/inc]  min..max
      exposure time:     I   O      1..33000 [us]
      sensitivity iso:   K   L    100..1600
      focus:             ,   .      0..255 [far..near]
    To go back to auto controls:
      'E' - autoexposure
      'F' - autofocus (continuous)
    """
    
    # add zoom option
    
    import depthai as dai
    import cv2
    
    
    # Step size ('W','A','S','D' controls)
    STEP_SIZE = 8
    # Manual exposure/focus set step
    EXP_STEP = 500  # us
    ISO_STEP = 50
    LENS_STEP = 3
    
    
    def clamp(num, v0, v1):
        return max(v0, min(num, v1))
    
    
    # Create pipeline
    pipeline = dai.Pipeline()
    
    # Define sources and outputs
    camRgb = pipeline.createColorCamera()
    camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_12_MP)
    videoEncoder = pipeline.createVideoEncoder()
    stillEncoder = pipeline.createVideoEncoder()
    
    controlIn = pipeline.createXLinkIn()
    configIn = pipeline.createXLinkIn()
    videoMjpegOut = pipeline.createXLinkOut()
    stillMjpegOut = pipeline.createXLinkOut()
    previewOut = pipeline.createXLinkOut()
    
    controlIn.setStreamName('control')
    configIn.setStreamName('config')
    videoMjpegOut.setStreamName('video')
    stillMjpegOut.setStreamName('still')
    previewOut.setStreamName('preview')
    
    # Properties
    camRgb.setVideoSize(1280, 720)
    camRgb.setPreviewSize(300, 300)
    
    videoEncoder.setDefaultProfilePreset(camRgb.getVideoSize(), camRgb.getFps(), dai.VideoEncoderProperties.Profile.MJPEG)
    videoEncoder.setLossless(True)
    stillEncoder.setDefaultProfilePreset(camRgb.getStillSize(), 1, dai.VideoEncoderProperties.Profile.MJPEG)
    stillEncoder.setLossless(True)
    
    # Linking
    camRgb.video.link(videoEncoder.input)
    camRgb.still.link(stillEncoder.input)
    camRgb.preview.link(previewOut.input)
    controlIn.out.link(camRgb.inputControl)
    configIn.out.link(camRgb.inputConfig)
    videoEncoder.bitstream.link(videoMjpegOut.input)
    stillEncoder.bitstream.link(stillMjpegOut.input)
    
    processDevice = True
    while processDevice:
     # Connect to device and start pipeline
        with dai.Device(pipeline) as device:
            device.startPipeline()
            # Get data queues
            controlQueue = device.getInputQueue('control')
            configQueue = device.getInputQueue('config')
            previewQueue = device.getOutputQueue('preview')
            videoQueue = device.getOutputQueue('video')
            stillQueue = device.getOutputQueue('still')
    
            # Max cropX & cropY
            maxCropX = (camRgb.getResolutionWidth() - camRgb.getVideoWidth()) / camRgb.getResolutionWidth()
            maxCropY = (camRgb.getResolutionHeight() - camRgb.getVideoHeight()) / camRgb.getResolutionHeight()
    
            # Default crop
            cropX = 0
            cropY = 0
            sendCamConfig = True
    
            # Defaults and limits for manual focus/exposure controls
            lensPos = 150
            lensMin = 0
            lensMax = 255
    
            expTime = 20000
            expMin = 1
            expMax = 33000
    
            sensIso = 800
            sensMin = 100
            sensMax = 1600
            processVideo = True
            while processVideo:
                previewFrames = previewQueue.tryGetAll()
                for previewFrame in previewFrames:
                    cv2.imshow('preview', previewFrame.getData().reshape(previewFrame.getWidth(), previewFrame.getHeight(), 3))
    
                videoFrames = videoQueue.tryGetAll()
                for videoFrame in videoFrames:
                    # Decode JPEG
                    frame = cv2.imdecode(videoFrame.getData(), cv2.IMREAD_UNCHANGED)
                    # Display
                    cv2.imshow('video', frame)
    
                # Send new cfg to camera
    
                if sendCamConfig:
                    cfg = dai.ImageManipConfig()
                    cfg.setCropRect(cropX, cropY, 0, 0)
                    configQueue.send(cfg)
                    print('Sending new crop - x: ', cropX, ' y: ', cropY)
                    print(cfg.getResizeWidth())
                    print(cfg.getResizeHeight())
                    sendCamConfig = False
    
                stillFrames = stillQueue.tryGetAll()
                for stillFrame in stillFrames:
                    # Decode JPEG
                    frame = cv2.imdecode(stillFrame.getData(), cv2.IMREAD_UNCHANGED)
                    # Display
                    cv2.imshow('still', frame)
    
                # Update screen (1ms pooling rate)
                key = cv2.waitKey(1)
                if key == ord('q'):
                    processDevice = False
                    break
                elif key == ord('c'):
                    print("Still Capture")
                    ctrl = dai.CameraControl()
                    ctrl.setCaptureStill(True)
                    controlQueue.send(ctrl)
                elif key == ord('t'):
                    print("Autofocus trigger (and disable continuous)")
                    ctrl = dai.CameraControl()
                    ctrl.setAutoFocusMode(dai.CameraControl.AutoFocusMode.AUTO)
                    ctrl.setAutoFocusTrigger()
                    controlQueue.send(ctrl)
                elif key == ord('f'):
                    print("Autofocus enable, continuous")
                    ctrl = dai.CameraControl()
                    ctrl.setAutoFocusMode(dai.CameraControl.AutoFocusMode.CONTINUOUS_VIDEO)
                    controlQueue.send(ctrl)
                elif key == ord('e'):
                    print("Autoexposure enable")
                    ctrl = dai.CameraControl()
                    ctrl.setAutoExposureEnable()
                    controlQueue.send(ctrl)
                elif key in [ord(','), ord('.')]:
                    if key == ord(','): lensPos -= LENS_STEP
                    if key == ord('.'): lensPos += LENS_STEP
                    lensPos = clamp(lensPos, lensMin, lensMax)
                    print("Setting manual focus, lens position: ", lensPos)
                    ctrl = dai.CameraControl()
                    ctrl.setManualFocus(lensPos)
                    controlQueue.send(ctrl)
                elif key in [ord('i'), ord('o'), ord('k'), ord('l')]:
                    if key == ord('i'): expTime -= EXP_STEP
                    if key == ord('o'): expTime += EXP_STEP
                    if key == ord('k'): sensIso -= ISO_STEP
                    if key == ord('l'): sensIso += ISO_STEP
                    expTime = clamp(expTime, expMin, expMax)
                    sensIso = clamp(sensIso, sensMin, sensMax)
                    print("Setting manual exposure, time: ", expTime, "iso: ", sensIso)
                    ctrl = dai.CameraControl()
                    ctrl.setManualExposure(expTime, sensIso)
                    controlQueue.send(ctrl)
                elif key in [ord('w'), ord('a'), ord('s'), ord('d')]:
                    if key == ord('a'):
                        cropX = cropX - (maxCropX / camRgb.getResolutionWidth()) * STEP_SIZE
                        if cropX < 0: cropX = maxCropX
                    elif key == ord('d'):
                        cropX = cropX + (maxCropX / camRgb.getResolutionWidth()) * STEP_SIZE
                        if cropX > maxCropX: cropX = 0
                    elif key == ord('w'):
                        cropY = cropY - (maxCropY / camRgb.getResolutionHeight()) * STEP_SIZE
                        if cropY < 0: cropY = maxCropY
                    elif key == ord('s'):
                        cropY = cropY + (maxCropY / camRgb.getResolutionHeight()) * STEP_SIZE
                        if cropY > maxCropY: cropY = 0
                    sendCamConfig = True
                elif key == ord('z'):
                    camRgb.video.unlink(videoEncoder.input)
                    camRgb.still.unlink(stillEncoder.input)
                    camRgb.preview.unlink(previewOut.input)
                    controlIn.out.unlink(camRgb.inputControl)
                    configIn.out.unlink(camRgb.inputConfig)
                    videoEncoder.bitstream.unlink(videoMjpegOut.input)
                    stillEncoder.bitstream.unlink(stillMjpegOut.input)
    
                    camRgb.setVideoSize(640, 360)
                    videoEncoder.setDefaultProfilePreset(camRgb.getVideoSize(), camRgb.getFps(),
                                                         dai.VideoEncoderProperties.Profile.MJPEG)
                    videoEncoder.setLossless(True)
                    stillEncoder.setDefaultProfilePreset(camRgb.getStillSize(), 1, dai.VideoEncoderProperties.Profile.MJPEG)
                    stillEncoder.setLossless(True)
                    camRgb.video.link(videoEncoder.input)
                    camRgb.still.link(stillEncoder.input)
                    camRgb.preview.link(previewOut.input)
                    controlIn.out.link(camRgb.inputControl)
                    configIn.out.link(camRgb.inputConfig)
                    videoEncoder.bitstream.link(videoMjpegOut.input)
                    stillEncoder.bitstream.link(stillMjpegOut.input)
                    processVideo = False
                elif key != -1:
                    print(key)