Using XIMEA cameras and OpenCV with Python

I recently found a decent camera for my behavior experiments. It was very important for me, that the camera supports LabVIEW and Python, ideally via OpenCV. Another important feature was the usage of USB 3 instead of Firewire or GigE, because of ease of use and availability in standart computers. At the same time, OpenCV is a powerful tool to do comprehensive image processing and analysis. And, even more important, it is available thorugh a Python interface, enabling me to develop fast, efficient and cost-effective tools to investigate zebrafish behavior. Here I am describing how to use Python, OpenCV and the XIMEA cam together.

Building OpenCV with enabled XIMEA support

First, the XiQ cameras from XIMEA offer all these aforementioned important features and are small, rather inexpensive and incredible fast. For my purposes, I use the XiQ MQ003MG-CM camera, that offers VGA resolution (648x488px) on a 1/3 inch chip, has a C-mount for objectives and runs at 500 fps. Mentioning briefly LabVIEW: By changing the firmware from native, proprietary XIMEA drivers to USB3 vision standard, LabVIEW is capable to use its own (as well proprietary) drivers to access the XIMEA cam. Using the XIMEA tool XiCOP, it is fairly easy to change the firmware in seconds.

OpenCV comes with XIMEA support, however, it is disabled by default. Thus, one has to built OpenCV from sources, which is not really trivial. In this case, OpenCV has to be built with the same compiler as your Python distribution, which means that you should use Microsoft Visual Studio 2008 (Express) for that (i.e. VS9). By the way, you can check the Build information of OpenCV using this snippet:

import cv2
print cv2.getBuildInformation()

The instructions given on the XIMEA support page are good and should be followed.

For Python, install first OpenCV using pip or the unofficial Windows binaries from Christoph Gohlke (he’s a hero). Then, built the OpenCV sources as “RELEASE” and depending on your python distribution for a x86 or x64 system. Then, copy and replace the cv2.pyd and all the DLLs in your python install folder, e.g. C:\Python27\Lib\site-packages . If you now open a (i)Python shell, type import cv2 and press enter. If the package is imported, everything is fine. If there’s an error stating “DLL is missing”, then ensure that the XIMEA API is installed properly and the API files (dlls for x86 and x64, respectively) are accesible through your PATH environmental variable. It maybe important to restart your computer, then it should work. Fast workround is to copy the API files directly to any PATH folder.

Accessing XIMEA cameras in Python using OpenCV

Now it is literally easy as the following:

import cv2

# All camera parameters available via cv2.VideoCapture
camParameter = {
    0: "CV_CAP_PROP_POS_MSEC = %s\nCurrent position of the video file in milliseconds.",
    1: "CV_CAP_PROP_POS_FRAMES = %s\n0-based index of the frame to be decoded/captured next.",
    2: "CV_CAP_PROP_POS_AVI_RATIO = %s\nRelative position of the video file",
    3: "CV_CAP_PROP_FRAME_WIDTH = %s\nWidth of the frames in the video stream.",
    4: "CV_CAP_PROP_FRAME_HEIGHT = %s\nHeight of the frames in the video stream.",
    5: "CV_CAP_PROP_FPS = %s\nFrame rate.",
    6: "CV_CAP_PROP_FOURCC = %s\n4-character code of codec.",
    7: "CV_CAP_PROP_FRAME_COUNT = %s\nNumber of frames in the video file.",
    8: "CV_CAP_PROP_FORMAT = %s\nFormat of the Mat objects returned by retrieve() .",
    9: "CV_CAP_PROP_MODE = %s\nBackend-specific value indicating the current capture mode.",
    10: "CV_CAP_PROP_BRIGHTNESS = %s\nBrightness of the image (only for cameras).",
    11: "CV_CAP_PROP_CONTRAST = %s\nContrast of the image (only for cameras).",
    12: "CV_CAP_PROP_SATURATION = %s\nSaturation of the image (only for cameras).",
    13: "CV_CAP_PROP_HUE = %s\nHue of the image (only for cameras).",
    14: "CV_CAP_PROP_GAIN = %s\nGain of the image (only for cameras).",
    15: "CV_CAP_PROP_EXPOSURE = %s\nExposure (only for cameras).",
    16: "CV_CAP_PROP_CONVERT_RGB = %s\nBoolean flags indicating whether images should be converted to RGB.",
    17: "CV_CAP_PROP_WHITE_BALANCE = %s\nCurrently unsupported",
    18: "CV_CAP_PROP_RECTIFICATION = %s\nRectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently)"
}

# Initialize camera
cam = cv2.VideoCapture(0)

# Print camera attributes:
for i in range(18):
    print camParameter[i] % cam.get(i), "\n"

while True:
    # Get an image
    flag, im = cam.read()

    # Received image
    if flag:
        # Show the image
        cv2.imshow("XIMEA cam", im)
        if cv2.waitKey(1) == ord('q'):
            break
    
    else:
        break

# Destroy windows and end program
cam.release()
cv2.destroyAllWindows()

An import note here is probably that the camera has an in-built auto-exposure. Thus, depending on your light intensity, the framerate will differ. For my experiments, I am using a 1 A high-power IR LED, which is capable to drive a minimal exposure time to work at theoretical 500 fps. Due to my computer vision algorithms and GUI processing (using Qt and pyqtgraph and showing some frames already processed), I usually have roughly 400 fps, which is quite decent.

One of my milestones is to access the XIMEA camera directly via its API allowing me access to a richer environment and more control over the camera. On github is a little binding available, however, I haven’t tried it to make it work on Windows computers.