Integrating HIK Camera in openUC2 ImSwitch with XYZ Microscope

Hey,

thank you so much @benedictdied for all the support already and to everyone involved in upgrading and maintaining this tool!

I am using openUC2 ImSwitch on an ARM64-based Mac to control an openUC2 XYZ microscope, but I am having issues getting our hikrobot camera to work.
Connecting to the camera and retrieving images via the MVS driver software works as expected, and so does the image thumbnail in the layer list window in ImSwitch when I’m starting the Liveview. However, when I’m trying to switch to that layer in the Image Display widget, or try to record frames, I’m receiving the following error stack traces:

ERROR:imswitch:[ExceptionHandler] Traceback (most recent call last):
  File "/Users/franzi/Documents/ImSwitch/imswitch/imcontrol/controller/controllers/ImageController.py", line 80, in update
    self._widget.setImage(detectorName, im, scale)
  File "/Users/franzi/Documents/ImSwitch/imswitch/imcontrol/view/widgets/ImageWidget.py", line 81, in setImage
    self.imgLayers[name].data = np.squeeze(im)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/image/image.py", line 1118, in data
    self._update_dims()
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/base/base.py", line 780, in _update_dims
    self._clear_extent()
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/base/base.py", line 854, in _clear_extent
    self.refresh()
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/base/base.py", line 1297, in refresh
    self.set_view_slice()
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/base/base.py", line 1062, in set_view_slice
    self._set_view_slice()
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/image/image.py", line 1327, in _set_view_slice
    super()._set_view_slice()
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/image/image.py", line 585, in _set_view_slice
    self._transforms['tile2data'].scale = np.ones(self.ndim)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/transforms/transforms.py", line 444, in scale
    if self._is_diagonal:
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/functools.py", line 993, in __get__
    val = self.func(instance)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/transforms/transforms.py", line 653, in _is_diagonal
    return is_diagonal(self.linear_matrix, tol=1e-8)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/transforms/transform_utils.py", line 498, in is_diagonal
    return np.max(np.abs(non_diag)) <= tol
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 2810, in max
    return _wrapreduction(a, np.maximum, 'max', axis, None, out,
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 88, in _wrapreduction
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
ValueError: zero-size array to reduction operation maximum which has no identity
ERROR:imswitch:[ExceptionHandler] Traceback (most recent call last):
  File "/Users/franzi/Documents/ImSwitch/imswitch/imcontrol/controller/controllers/ImageController.py", line 80, in update
    self._widget.setImage(detectorName, im, scale)
  File "/Users/franz/Documents/ImSwitch/imswitch/imcontrol/view/widgets/ImageWidget.py", line 81, in setImage
    self.imgLayers[name].data = np.squeeze(im)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/image/image.py", line 1119, in data
    self.events.data(value=self.data)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/events/event.py", line 763, in __call__
    self._invoke_callback(cb, event if pass_event else None)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/events/event.py", line 801, in _invoke_callback
    _handle_exception(
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/events/event.py", line 790, in _invoke_callback
    cb()
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/components/viewer_model.py", line 431, in _on_layers_change
    ranges = self.layers._ranges
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/functools.py", line 993, in __get__
    val = self.func(instance)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/components/layerlist.py", line 320, in _ranges
    layer_extent_list = [layer.extent for layer in self]
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/components/layerlist.py", line 320, in <listcomp>
    layer_extent_list = [layer.extent for layer in self]
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/functools.py", line 993, in __get__
    val = self.func(instance)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/base/base.py", line 835, in extent
    extent_world = get_extent_world(
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/layers/utils/layer_utils.py", line 731, in get_extent_world
    full_world_extent = data_to_world(full_data_extent)
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/transforms/transforms.py", line 416, in __call__
    padded_linear_matrix = embed_in_identity_matrix(
  File "/opt/miniconda3/envs/imswitchX86/lib/python3.9/site-packages/napari/utils/transforms/transform_utils.py", line 333, in embed_in_identity_matrix
    full_matrix[-matrix.shape[0] :, -matrix.shape[1] :] = matrix
ValueError: could not broadcast input array from shape (2,2) into shape (1,1)

This is how it looks in ImSwitch, the thumbnail working, the Image Display all black:

Happy about any hints on how to solve this :slight_smile:

Best, Franzi

Hey @Franzili! thanks for reaching out! What you see is the result from the configuration of your microscope. It assumes that 2 cameras connected (HIK + Webcam for overview scanning), but it seems the second one does not produce frames that could be displayed by Napari. You can fix this by removing the Observer Camera from the Config file as described here:

I hope this becomes clear :slight_smile:

I’ll try to ensure that in case the camera is not loaded, this error won’t show up.

PS: Would you mind to post your current config ?

Thanks @benedictdied! Removing the second camera actually solved the issue!
Here my config before deleting the observer camera:

{
  "positioners": {
    "ESP32Stage": {
      "managerName": "ESP32StageManager",
      "managerProperties": {
        "rs232device": "ESP32",
        "isEnable": true,
        "enableauto": true,
        "stepsizeX": -0.3125,
        "stepsizeY": -0.3125,
        "stepsizeZ": 0.3125,
        "homeSpeedX": 15000,
        "homeSpeedY": 15000,
        "homeSpeedZ": 15000,
        "isDualaxis": true,
        "homeDirectionX": 1,
        "backlashXOld": 15,
        "backlashYOld": 40,
        "backlashX": 0,
        "backlashY": 0,
        "homeEndstoppolarityY": 0,
        "homeDirectionY": -1,
        "homeDirectionZ": 0,
        "homeXenabled": 1,
        "homeYenabled": 1,
        "homeZenabled": 0,
        "initialSpeed": {
          "X": 15000,
          "Y": 15000,
          "Z": 15000
        }
      },
      "axes": [
        "X",
        "Y",
        "Z"
      ],
      "forScanning": true,
      "forPositioning": true
    }
  },
  "rs232devices": {
    "ESP32": {
      "managerName": "ESP32Manager",
      "managerProperties": {
        "host_": "192.168.43.129",
        "serialport": "COM5",
        "baudrate":500000,
        "debug":1
      }
    }
  },
  "lasers": {
    "LED": {
        "analogChannel": null,
        "digitalLine": null,
        "managerName": "ESP32LEDLaserManager",
        "managerProperties": {
          "rs232device": "ESP32",
          "channel_index": 3
        },
        "wavelength": 0,
        "valueRangeMin": 0,
        "valueRangeMax": 1023
      }
    },
  "detectors": {
    "WidefieldCamera": {
      "analogChannel": null,
      "digitalLine": null,
      "managerName": "HikCamManager",
      "managerProperties": {
        "isRGB": 1,
        "cameraListIndex": 0,
        "cameraEffPixelsize": 0.2257,
        "hikcam": {
          "exposure": 0,
          "gain": 0,
          "blacklevel": 100,
          "image_width": 1000,
          "image_height": 1000
        }
      },
      "forAcquisition": true,
      "forFocusLock": true
    },
    "Observer": {
      "analogChannel": null,
      "digitalLine": null,
      "managerName": "OpenCVCamManager",
      "managerProperties": {
        "cameraListIndex": 1,
        "cameraListIndexWIN": 0,
        "isRGB":1,
        "opencvcam": {
          "exposure": 10
        },
        "hikcam": {
          "exposure": 0,
          "gain": 0,
          "blacklevel": 100,
          "image_width": 1000,
          "image_height": 1000
        }
      },
      "forAcquisition": true,
      "forFocusLock": true
    }
  },
  "autofocus": {
    "camera": "WidefieldCamera",
    "positioner": "ESP32Stage",
    "updateFreq": 10,
    "frameCropx": 780,
    "frameCropy": 400,
    "frameCropw": 500,
    "frameCroph": 100
  },
  "mct": {
    "monitorIdx": 2,
    "width": 1080,
    "height": 1920,
    "wavelength": 0,
    "pixelSize": 0,
    "angleMount": 0,
    "patternsDirWin": "C:\\Users\\wanghaoran\\Documents\\ImSwitchConfig\\imcontrol_slm\\488\\",
    "patternsDir": "/users/franziskaniemeyer/ImSwitchConfig/imcontrol_sim/488"
  },
  "PixelCalibration": {},
  "focusLock": {
    "camera": "WidefieldCamera",
    "positioner": "ESP32StageManager",
    "updateFreq": 4,
    "frameCropx": 0,
    "frameCropy": 0,
    "frameCropw": 0,
    "frameCroph": 0
  },
  "availableWidgets": [
    "Settings",
    "View",
    "Recording",
    "Image",
    "Laser",
    "Positioner",
    "Autofocus",
    "MCT",
    "UC2Config",
    "PixelCalibration",
    "HistoScan",
    "ROIScan"
  ],
  "nonAvailableWidgets": [
    "STORMRecon",
    "DPC",
    "Hypha",
    "FocusLock",
    "FOVLock"
  ]
}

Now we’d only need to actually get the second camera for overview scanning working :smiley:

Best, Franzi

The camera should be there. It’s the one next to the Illumination Source

You can check if it works when you plugin the USB and open your webcamera app (Windows: “Camera” or Mac: “PhotoBooth”)