diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c251333
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+__pycache__/
+.ipynb_checkpoints/
+*test*
+*.pyc
+write_camera_details.py
+camera_details.json
diff --git a/README.md b/README.md
index 5891d50..9791ba8 100644
--- a/README.md
+++ b/README.md
@@ -22,10 +22,10 @@ This software package was written by [Gary Kane](https://github.com/gkane26), po
1. Install the latest driver for your camera. You can find the driver from The Imaging Source website: https://www.theimagingsource.com/products/. **If you add new cameras to an existing system, make sure to update the driver!**
1. Clone this repository. Open command prompt (type "cmd" into the search bar and hit enter), then type:
-``git clone https://github.com/AdaptiveMotorControlLab/camera_control``
+``git clone https://github.com/AdaptiveMotorControlLab/Camera_Control``
2. Open the camera control directory, **right-click 'install1.bat' and select 'Run as administrator'**
-This script will install imaging source libraries, ffmpeg for command prompt, and create a new conda environment 'camera27'. Upon completion, the window will close suddenly.
+This script will install imaging source libraries, ffmpeg for command prompt, and create a new conda environment 'camera36'. Upon completion, the window will close suddenly.
3. Run 'install2.bat'.
This script will finish setting up the conda environment and create a desktop shortcut to open the GUI.
@@ -35,7 +35,7 @@ This script will finish setting up the conda environment and create a desktop sh
- name = camera name
- crop = cropping parameters
- rotate = rotation angle of image
- - exposure = integer exposure values; can edit this in the GUI
+ - exposure = exposure in ms; can edit this in the GUI
- output_dir = default directory to save videos; can edit this in the GUI
- Example:
@@ -43,7 +43,7 @@ This script will finish setting up the conda environment and create a desktop sh
cam_0 = {'name' : 'Cog Rig',
'crop' : {'top' : 150, 'left' : 225, 'height' : 250, 'width' : 300},
'rotate' : 0,
- 'exposure' : -14,
+ 'exposure' : .003,
'output_dir' : 'C:/Users/user1/Desktop/video'}
diff --git a/camera_control_GUI.py b/camera_control_GUI.py
index f05a372..f1ab7e1 100644
--- a/camera_control_GUI.py
+++ b/camera_control_GUI.py
@@ -8,9 +8,7 @@
GUI to record from imaging source cameras during experiments
"""
-from Tkinter import Entry, Label, Button, StringVar, IntVar, Tk, END, Radiobutton
-import tkFileDialog
-import ttk
+from tkinter import Entry, Label, Button, StringVar, IntVar, Tk, END, Radiobutton, filedialog, ttk
import numpy as np
import datetime
import os
@@ -21,7 +19,6 @@
import threading
import json
import nidaqmx
-import write_camera_details
class CamGUI(object):
@@ -43,8 +40,9 @@ def __init__(self):
self.selectCams()
def browse_output(self):
- filepath = tkFileDialog.askdirectory()
- self.output.set(filepath)
+ if len(self.vid_out) == 0:
+ filepath = filedialog.askdirectory()
+ self.output.set(filepath)
def init_cam(self, num):
# create pop up window during setup
@@ -92,7 +90,7 @@ def set_exposure(self, num):
cam_check_window.mainloop()
cam_check_window.destroy()
else:
- self.cam[num].set_exposure(int(self.exposure[num].get()))
+ self.cam[num].set_exposure(float(self.exposure[num].get()))
def lv_interrupt(self, task_handle, signal_type, callback_data):
@@ -247,6 +245,7 @@ def start_record(self):
self.vid_start_time = time.time()
t = []
for i in range(len(self.cam)):
+ self.cam[i].set_frame_rate(int(self.fps.get()))
t.append(threading.Thread(target=self.record_on_thread, args=(i,)))
t[-1].daemon = True
t[-1].start()
@@ -320,6 +319,9 @@ def save_vid(self, compress=False, delete=False):
def close_window(self):
+ if self.record_on.get():
+ return
+
self.end_labview()
if not self.setup:
self.done = True
diff --git a/camera_env.yaml b/camera_env.yaml
deleted file mode 100644
index 7388340..0000000
--- a/camera_env.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: camera27
-channels:
- - defaults
-dependencies:
- - certifi=2018.11.29=py27_0
- - pip=18.1=py27_0
- - python=2.7.15=hcb6e200_5
- - setuptools=40.6.3=py27_0
- - sqlite=3.26.0=h0c8e037_0
- - vc=9=h7299396_1
- - vs2008_runtime=9.00.30729.1=hfaea7d5_1
- - wheel=0.32.3=py27_0
- - wincertstore=0.2=py27hf04cefb_0
- - pip:
- - ffmpy==0.2.2
- - future==0.17.1
- - numpy==1.16.0
- - opencv-python==4.0.0.21
- - nidaqmx
diff --git a/camera_env.yml b/camera_env.yml
new file mode 100644
index 0000000..b3e0a41
--- /dev/null
+++ b/camera_env.yml
@@ -0,0 +1,20 @@
+name: camera36
+channels:
+ - defaults
+dependencies:
+ - certifi=2019.9.11=py36_0
+ - pip=19.2.3=py36_0
+ - python=3.6.9=h5500b2f_0
+ - setuptools=41.2.0=py36_0
+ - sqlite=3.29.0=he774522_0
+ - vc=14.1=h0510ff6_4
+ - vs2015_runtime=14.16.27012=hf0eaf9b_0
+ - wheel=0.33.6=py36_0
+ - wincertstore=0.2=py36h7fe50ca_0
+ - pip:
+ - ffmpy==0.2.2
+ - imutils==0.5.3
+ - nidaqmx==0.5.7
+ - numpy==1.16.0
+ - opencv-python==4.1.1.26
+ - six==1.12.0
diff --git a/ic_camera.py b/ic_camera.py
index b7af7b9..167629d 100644
--- a/ic_camera.py
+++ b/ic_camera.py
@@ -8,20 +8,20 @@
camera class for imaging source cameras - helps load correct settings
"""
-from pyicic.IC_ImagingControl import *
+import tisgrabber as ic
import numpy as np
import os
import json
import cv2
+import ctypes as C
path = os.path.dirname(os.path.realpath(__file__))
dets_file = os.path.normpath(path + '/camera_details.json')
-with open(dets_file) as f:
- cam_details = json.load(f)
+cam_details = json.load(open(dets_file, 'r'))
class ICCam(object):
- def __init__(self, cam_num=0, rotate=None, crop=None, exposure=None, format='Y800 (720x540)'):
+ def __init__(self, cam_num=0, rotate=None, crop=None, exposure=None):
'''
Params
------
@@ -31,65 +31,56 @@ def __init__(self, cam_num=0, rotate=None, crop=None, exposure=None, format='Y80
default = None, uses default parameters specific to camera
'''
- self.ic_ic = IC_ImagingControl()
- self.ic_ic.init_library()
-
self.cam_num = cam_num
self.rotate = rotate if rotate is not None else cam_details[str(self.cam_num)]['rotate']
self.crop = crop if crop is not None else cam_details[str(self.cam_num)]['crop']
self.exposure = exposure if exposure is not None else cam_details[str(self.cam_num)]['exposure']
- self.cam = self.ic_ic.get_device(self.ic_ic.get_unique_device_names()[self.cam_num])
- self.cam.open()
- self.cam.set_video_format(format)
+ self.cam = ic.TIS_CAM()
+ self.cam.open(self.cam.GetDevices()[cam_num].decode())
self.add_filters()
def add_filters(self):
if self.rotate != 0:
- h_r = self.cam.create_frame_filter('Rotate Flip')
- self.cam.add_frame_filter_to_device(h_r)
- self.cam.frame_filter_set_parameter(h_r, 'Rotation Angle', self.rotate)
-
- h_c = self.cam.create_frame_filter('ROI')
- self.cam.add_frame_filter_to_device(h_c)
- self.cam.frame_filter_set_parameter(h_c, 'Top', self.crop['top'])
- self.cam.frame_filter_set_parameter(h_c, 'Left', self.crop['left'])
- self.cam.frame_filter_set_parameter(h_c, 'Height', self.crop['height'])
- self.cam.frame_filter_set_parameter(h_c, 'Width', self.crop['width'])
+ h_r = self.cam.CreateFrameFilter(b'Rotate Flip')
+ self.cam.AddFrameFilter(h_r)
+ self.cam.FilterSetParameter(h_r, b'Rotation Angle', self.rotate)
+
+ h_c = self.cam.CreateFrameFilter(b'ROI')
+ self.cam.AddFrameFilter(h_c)
+ self.cam.FilterSetParameter(h_c, b'Top', self.crop['top'])
+ self.cam.FilterSetParameter(h_c, b'Left', self.crop['left'])
+ self.cam.FilterSetParameter(h_c, b'Height', self.crop['height'])
+ self.cam.FilterSetParameter(h_c, b'Width', self.crop['width'])
self.size = (self.crop['width'], self.crop['height'])
- self.cam.gain.auto = False
- self.cam.exposure.auto = False
- self.cam.exposure.value = self.exposure
-
+ def set_frame_rate(self, fps):
+ self.cam.SetFrameRate(fps)
def set_exposure(self, val):
- try:
- val = int(round(val))
- val = val if val < self.cam.exposure.max-1 else self.cam.exposure.max-1
- val = val if val > self.cam.exposure.min else self.cam.exposure.min
- self.cam.exposure.value = val
- except:
- pass
+ val = 1 if val > 1 else val
+ val = 0 if val < 0 else val
+ self.cam.SetPropertyAbsoluteValue("Exposure", "Value", val)
def get_exposure(self):
- return self.cam.exposure.value
+ exposure = [0]
+ self.cam.GetPropertyAbsoluteValue("Exposure", "Value", exposure)
+ return round(exposure[0], 3)
def get_image(self):
- data, width, height, depth = self.cam.get_image_data()
- frame = np.ndarray(buffer=data,
- dtype=np.uint8,
- shape=(height, width, depth))
+ self.cam.SnapImage()
+ frame = self.cam.GetImageEx()
return cv2.flip(frame,0)
def get_image_dimensions(self):
- _, width, height, _ = self.cam.get_image_data()
+ im = self.get_image()
+ height = im.shape[0]
+ width = im.shape[1]
return (width, height)
- def start(self, show_display=True):
- self.cam.enable_continuous_mode(True)
- self.cam.start_live(show_display=show_display)
+ def start(self, show_display=1):
+ self.cam.SetContinuousMode(0)
+ self.cam.StartLive(show_display)
def close(self):
- self.cam.stop_live()
- self.cam.close()
+ self.cam.StopLive()
diff --git a/install1.bat b/install1.bat
index 81d7088..222e9d4 100644
--- a/install1.bat
+++ b/install1.bat
@@ -31,6 +31,6 @@ powershell [System.Environment]::SetEnvironmentVariable('PATH', '%NEW_PATH%', 'M
echo.
echo.
-echo Create New Conda Environment: camera27
+echo Create New Conda Environment: camera36
call activate.bat
-conda env create -f camera_env.yaml
+conda env create -f camera_env.yml
diff --git a/install2.bat b/install2.bat
index fb6be92..65b0cf9 100644
--- a/install2.bat
+++ b/install2.bat
@@ -1,13 +1,8 @@
echo OFF
-@setlocal enableextensions
-@cd /d "%~dp0"
-
echo.
echo.
-echo Install Imaging Source Python Package
-call activate camera27
-pip install git+https://github.com/morefigs/py-ic-imaging-control
+echo Initialize system setup via write_camera_details.py file
copy write_camera_details_TEMPLATE.py write_camera_details.py
python write_camera_details.py
@@ -16,7 +11,7 @@ echo.
echo.
echo Write Shortcut File to the Desktop
echo call activate.bat > C:%HOMEPATH%\Desktop\cameraGUI.bat
-echo call activate camera27 >> C:%HOMEPATH%\Desktop\cameraGUI.bat
+echo call activate camera36 >> C:%HOMEPATH%\Desktop\cameraGUI.bat
echo cd %cd% >> C:%HOMEPATH%\Desktop\cameraGUI.bat
echo python camera_control_GUI.py >> C:%HOMEPATH%\Desktop\cameraGUI.bat
diff --git a/tisgrabber.py b/tisgrabber.py
new file mode 100644
index 0000000..f1728a3
--- /dev/null
+++ b/tisgrabber.py
@@ -0,0 +1,813 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Nov 21 09:44:40 2016
+
+@author: Daniel Vassmer, Stefan_Geissler
+From: https://github.com/TheImagingSource/IC-Imaging-Control-Samples/tree/master/Python
+
+modified 10/3/2019 by Gary Kane - https://github.com/gkane26
+post-doctoral fellow @ the Adaptive Motor Control Lab
+https://github.com/AdaptiveMotorControlLab
+"""
+
+from enum import Enum
+
+import ctypes as C
+import os
+import sys
+import numpy as np
+
+class SinkFormats(Enum):
+ Y800 = 0
+ RGB24 = 1
+ RGB32 = 2
+ UYVY = 3
+ Y16 = 4
+
+ImageFileTypes = {'BMP':0, 'JPEG':1}
+
+
+class GrabberHandle(C.Structure):
+ pass
+GrabberHandle._fields_ = [('unused', C.c_int)]
+
+##############################################################################
+
+### GK Additions from: https://github.com/morefigs/py-ic-imaging-control
+
+class FilterParameter(C.Structure):
+ pass
+FilterParameter._fields_ = [('Name', C.c_char * 30),
+ ('Type', C.c_int)]
+
+
+class FrameFilterHandle(C.Structure):
+ pass
+FrameFilterHandle._fields_ = [('pFilter', C.c_void_p),
+ ('bHasDialog', C.c_int),
+ ('ParameterCount', C.c_int),
+ ('Parameters', C.POINTER(FilterParameter))]
+
+##############################################################################
+
+class TIS_GrabberDLL(object):
+ if sys.maxsize > 2**32 :
+ __tisgrabber = C.windll.LoadLibrary("tisgrabber_x64.dll")
+ else:
+ __tisgrabber = C.windll.LoadLibrary("tisgrabber.dll")
+
+ def __init__(self, **keyargs):
+ """Initialize the Albatross from the keyword arguments."""
+ self.__dict__.update(keyargs)
+
+
+ GrabberHandlePtr = C.POINTER(GrabberHandle)
+
+####################################
+
+# Initialize the ICImagingControl class library. This function must be called
+# only once before any other functions of this library are called.
+# @param szLicenseKey IC Imaging Control license key or NULL if only a trial version is available.
+# @retval IC_SUCCESS on success.
+# @retval IC_ERROR on wrong license key or other errors.
+# @sa IC_CloseLibrary
+ InitLibrary = __tisgrabber.IC_InitLibrary(None)
+
+# Get the number of the currently available devices. This function creates an
+# internal array of all connected video capture devices. With each call to this
+# function, this array is rebuild. The name and the unique name can be retrieved
+# from the internal array using the functions IC_GetDevice() and IC_GetUniqueNamefromList.
+# They are usefull for retrieving device names for opening devices.
+#
+# @retval >= 0 Success, count of found devices.
+# @retval IC_NO_HANDLE Internal Error.
+#
+# @sa IC_GetDevice
+# @sa IC_GetUniqueNamefromList
+ get_devicecount = __tisgrabber.IC_GetDeviceCount
+ get_devicecount.restype = C.c_int
+ get_devicecount.argtypes = None
+
+# Get unique device name of a device specified by iIndex. The unique device name
+# consist from the device name and its serial number. It allows to differ between
+# more then one device of the same type connected to the computer. The unique device name
+# is passed to the function IC_OpenDevByUniqueName
+#
+# @param iIndex The number of the device whose name is to be returned. It must be
+# in the range from 0 to IC_GetDeviceCount(),
+# @return Returns the string representation of the device on success, NULL
+# otherwise.
+#
+# @sa IC_GetDeviceCount
+# @sa IC_GetUniqueNamefromList
+# @sa IC_OpenDevByUniqueName
+
+ get_unique_name_from_list = __tisgrabber.IC_GetUniqueNamefromList
+ get_unique_name_from_list.restype = C.c_char_p
+ get_unique_name_from_list.argtypes = (C.c_int,)
+
+# Creates a new grabber handle and returns it. A new created grabber should be
+# release with a call to IC_ReleaseGrabber if it is no longer needed.
+# @sa IC_ReleaseGrabber
+ create_grabber = __tisgrabber.IC_CreateGrabber
+ create_grabber.restype = GrabberHandlePtr
+ create_grabber.argtypes = None
+
+# Open a video capture by using its UniqueName. Use IC_GetUniqueName() to
+# retrieve the unique name of a camera.
+#
+# @param hGrabber Handle to a grabber object
+# @param szDisplayName Memory that will take the display name.
+#
+# @sa IC_GetUniqueName
+# @sa IC_ReleaseGrabber
+ open_device_by_unique_name = __tisgrabber.IC_OpenDevByUniqueName
+ open_device_by_unique_name.restype = C.c_int
+ open_device_by_unique_name.argtypes = (GrabberHandlePtr,
+ C.c_char_p)
+
+
+ set_videoformat = __tisgrabber.IC_SetVideoFormat
+ set_videoformat.restype = C.c_int
+ set_videoformat.argtypes = (GrabberHandlePtr,
+ C.c_char_p)
+
+ set_framerate = __tisgrabber.IC_SetFrameRate
+ set_framerate.restype = C.c_int
+ set_framerate.argtypes = (GrabberHandlePtr,
+ C.c_float)
+
+
+# Returns the width of the video format.
+ get_video_format_width = __tisgrabber.IC_GetVideoFormatWidth
+ get_video_format_width.restype = C.c_int
+ get_video_format_width.argtypes = (GrabberHandlePtr,)
+
+# returns the height of the video format.
+ get_video_format_height = __tisgrabber.IC_GetVideoFormatHeight
+ get_video_format_height.restype = C.c_int
+ get_video_format_height.argtypes = (GrabberHandlePtr,)
+
+
+# Get the number of the available video formats for the current device.
+# A video capture device must have been opened before this call.
+#
+# @param hGrabber The handle to the grabber object.
+#
+# @retval >= 0 Success
+# @retval IC_NO_DEVICE No video capture device selected.
+# @retval IC_NO_HANDLE No handle to the grabber object.
+#
+# @sa IC_GetVideoFormat
+ GetVideoFormatCount = __tisgrabber.IC_GetVideoFormatCount
+ GetVideoFormatCount.restype = C.c_int
+ GetVideoFormatCount.argtypes = (GrabberHandlePtr,)
+
+# Get a string representation of the video format specified by iIndex.
+# iIndex must be between 0 and IC_GetVideoFormatCount().
+# IC_GetVideoFormatCount() must have been called before this function,
+# otherwise it will always fail.
+#
+# @param hGrabber The handle to the grabber object.
+# @param iIndex Number of the video format to be used.
+#
+# @retval Nonnull The name of the specified video format.
+# @retval NULL An error occured.
+# @sa IC_GetVideoFormatCount
+ GetVideoFormat = __tisgrabber.IC_GetVideoFormat
+ GetVideoFormat.restype = C.c_char_p
+ GetVideoFormat.argtypes = (GrabberHandlePtr,
+ C.c_int,)
+
+# Get the number of the available input channels for the current device.
+# A video capture device must have been opened before this call.
+#
+# @param hGrabber The handle to the grabber object.
+#
+# @retval >= 0 Success
+# @retval IC_NO_DEVICE No video capture device selected.
+# @retval IC_NO_HANDLE No handle to the grabber object.
+#
+# @sa IC_GetInputChannel
+ GetInputChannelCount = __tisgrabber.IC_GetInputChannelCount
+ GetInputChannelCount.restype = C.c_int
+ GetInputChannelCount.argtypes = (GrabberHandlePtr,)
+
+# Get a string representation of the input channel specified by iIndex.
+# iIndex must be between 0 and IC_GetInputChannelCount().
+# IC_GetInputChannelCount() must have been called before this function,
+# otherwise it will always fail.
+# @param hGrabber The handle to the grabber object.
+# @param iIndex Number of the input channel to be used..
+#
+# @retval Nonnull The name of the specified input channel
+# @retval NULL An error occured.
+# @sa IC_GetInputChannelCount
+ GetInputChannel = __tisgrabber.IC_GetInputChannel
+ GetInputChannel.restype = C.c_char_p
+ GetInputChannel.argtypes = (GrabberHandlePtr,
+ C.c_int,)
+
+
+# Get the number of the available video norms for the current device.
+# A video capture device must have been opened before this call.
+#
+# @param hGrabber The handle to the grabber object.
+#
+# @retval >= 0 Success
+# @retval IC_NO_DEVICE No video capture device selected.
+# @retval IC_NO_HANDLE No handle to the grabber object.
+#
+# @sa IC_GetVideoNorm
+ GetVideoNormCount = __tisgrabber.IC_GetVideoNormCount
+ GetVideoNormCount.restype = C.c_int
+ GetVideoNormCount.argtypes = (GrabberHandlePtr,)
+
+
+# Get a string representation of the video norm specified by iIndex.
+# iIndex must be between 0 and IC_GetVideoNormCount().
+# IC_GetVideoNormCount() must have been called before this function,
+# otherwise it will always fail.
+#
+# @param hGrabber The handle to the grabber object.
+# @param iIndex Number of the video norm to be used.
+#
+# @retval Nonnull The name of the specified video norm.
+# @retval NULL An error occured.
+# @sa IC_GetVideoNormCount
+ GetVideoNorm = __tisgrabber.IC_GetVideoNorm
+ GetVideoNorm.restype = C.c_char_p
+ GetVideoNorm.argtypes = (GrabberHandlePtr,
+ C.c_int,)
+
+
+ SetFormat = __tisgrabber.IC_SetFormat
+ SetFormat.restype = C.c_int
+ SetFormat.argtypes = (GrabberHandlePtr,
+ C.c_int,)
+ GetFormat = __tisgrabber.IC_GetFormat
+ GetFormat.restype = C.c_int
+ GetFormat.argtypes = (GrabberHandlePtr,)
+
+
+# Start the live video.
+# @param hGrabber The handle to the grabber object.
+# @param iShow The parameter indicates: @li 1 : Show the video @li 0 : Do not show the video, but deliver frames. (For callbacks etc.)
+# @retval IC_SUCCESS on success
+# @retval IC_ERROR if something went wrong.
+# @sa IC_StopLive
+
+ StartLive = __tisgrabber.IC_StartLive
+ StartLive.restype = C.c_int
+ StartLive.argtypes = (GrabberHandlePtr,
+ C.c_int,)
+
+ StopLive = __tisgrabber.IC_StopLive
+ StopLive.restype = C.c_int
+ StopLive.argtypes = (GrabberHandlePtr,)
+
+
+ SetHWND = __tisgrabber.IC_SetHWnd
+ SetHWND.restype = C.c_int
+ SetHWND.argtypes = (GrabberHandlePtr,
+ C.c_int,)
+
+
+# Snaps an image. The video capture device must be set to live mode and a
+# sink type has to be set before this call. The format of the snapped images depend on
+# the selected sink type.
+#
+# @param hGrabber The handle to the grabber object.
+# @param iTimeOutMillisek The Timeout time is passed in milli seconds. A value of -1 indicates, that
+# no time out is set.
+#
+#
+# @retval IC_SUCCESS if an image has been snapped
+# @retval IC_ERROR if something went wrong.
+# @retval IC_NOT_IN_LIVEMODE if the live video has not been started.
+#
+# @sa IC_StartLive
+# @sa IC_SetFormat
+
+ SnapImage=__tisgrabber.IC_SnapImage
+ SnapImage.restype = C.c_int
+ SnapImage.argtypes = (GrabberHandlePtr,
+ C.c_int,)
+
+
+# Retrieve the properties of the current video format and sink type
+# @param hGrabber The handle to the grabber object.
+# @param *lWidth This recieves the width of the image buffer.
+# @param *lHeight This recieves the height of the image buffer.
+# @param *iBitsPerPixel This recieves the count of bits per pixel.
+# @param *format This recieves the current color format.
+# @retval IC_SUCCESS on success
+# @retval IC_ERROR if something went wrong.
+
+ GetImageDescription = __tisgrabber.IC_GetImageDescription
+ GetImageDescription.restype = C.c_int
+ GetImageDescription.argtypes = (GrabberHandlePtr,
+ C.POINTER(C.c_long),
+ C.POINTER(C.c_long),
+ C.POINTER(C.c_int),
+ C.POINTER(C.c_int),)
+
+
+
+
+ GetImagePtr = __tisgrabber.IC_GetImagePtr
+ GetImagePtr.restype = C.c_void_p
+ GetImagePtr.argtypes = (GrabberHandlePtr,)
+
+
+# ############################################################################
+ ShowDeviceSelectionDialog = __tisgrabber.IC_ShowDeviceSelectionDialog
+ ShowDeviceSelectionDialog.restype = GrabberHandlePtr
+ ShowDeviceSelectionDialog.argtypes = (GrabberHandlePtr,)
+
+# ############################################################################
+
+ ShowPropertyDialog = __tisgrabber.IC_ShowPropertyDialog
+ ShowPropertyDialog.restype = GrabberHandlePtr
+ ShowPropertyDialog.argtypes = (GrabberHandlePtr,)
+
+# ############################################################################
+ IsDevValid = __tisgrabber.IC_IsDevValid
+ IsDevValid.restype = C.c_int
+ IsDevValid.argtypes = (GrabberHandlePtr,)
+
+# ############################################################################
+
+ LoadDeviceStateFromFile = __tisgrabber.IC_LoadDeviceStateFromFile
+ LoadDeviceStateFromFile.restype = GrabberHandlePtr
+ LoadDeviceStateFromFile.argtypes = (GrabberHandlePtr,C.c_char_p)
+
+# ############################################################################
+ SaveDeviceStateToFile = __tisgrabber.IC_SaveDeviceStateToFile
+ SaveDeviceStateToFile.restype = C.c_int
+ SaveDeviceStateToFile.argtypes = (GrabberHandlePtr,C.c_char_p)
+
+
+ GetCameraProperty = __tisgrabber.IC_GetCameraProperty
+ GetCameraProperty.restype = C.c_int
+ GetCameraProperty.argtypes = (GrabberHandlePtr,
+ C.c_int,
+ C.POINTER(C.c_long),)
+
+ SetCameraProperty = __tisgrabber.IC_SetCameraProperty
+ SetCameraProperty.restype = C.c_int
+ SetCameraProperty.argtypes = (GrabberHandlePtr,
+ C.c_int,
+ C.c_long,)
+
+
+ SetPropertyValue = __tisgrabber.IC_SetPropertyValue
+ SetPropertyValue.restype = C.c_int
+ SetPropertyValue.argtypes = (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p,
+ C.c_int, )
+
+
+ GetPropertyValue = __tisgrabber.IC_GetPropertyValue
+ GetPropertyValue.restype = C.c_int
+ GetPropertyValue.argtypes = (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p,
+ C.POINTER(C.c_long), )
+
+
+# ############################################################################
+ SetPropertySwitch = __tisgrabber.IC_SetPropertySwitch
+ SetPropertySwitch.restype = C.c_int
+ SetPropertySwitch.argtypes= (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p,
+ C.c_int,)
+
+ GetPropertySwitch = __tisgrabber.IC_GetPropertySwitch
+ GetPropertySwitch.restype = C.c_int
+ GetPropertySwitch.argtypes= (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p,
+ C.POINTER(C.c_long),)
+# ############################################################################
+
+ IsPropertyAvailable = __tisgrabber.IC_IsPropertyAvailable
+ IsPropertyAvailable.restype = C.c_int
+ IsPropertyAvailable.argtypes= (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p,)
+
+ PropertyOnePush = __tisgrabber.IC_PropertyOnePush
+ PropertyOnePush.restype = C.c_int
+ PropertyOnePush.argtypes = (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p, )
+
+
+ SetPropertyAbsoluteValue = __tisgrabber.IC_SetPropertyAbsoluteValue
+ SetPropertyAbsoluteValue.restype = C.c_int
+ SetPropertyAbsoluteValue.argtypes = (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p,
+ C.c_float, )
+
+ GetPropertyAbsoluteValue = __tisgrabber.IC_GetPropertyAbsoluteValue
+ GetPropertyAbsoluteValue.restype = C.c_int
+ GetPropertyAbsoluteValue.argtypes = (GrabberHandlePtr,
+ C.c_char_p,
+ C.c_char_p,
+ C.POINTER(C.c_float), )
+
+ # definition of the frameready callback
+ FRAMEREADYCALLBACK = C.CFUNCTYPE(C.c_void_p,C.c_int, C.POINTER(C.c_ubyte), C.c_ulong, C.py_object )
+
+ # set callback function
+ SetFrameReadyCallback = __tisgrabber.IC_SetFrameReadyCallback
+ SetFrameReadyCallback.restype = C.c_int
+ SetFrameReadyCallback.argtypes = [GrabberHandlePtr, FRAMEREADYCALLBACK, C.py_object]
+
+ SetContinuousMode = __tisgrabber.IC_SetContinuousMode
+
+ SaveImage = __tisgrabber.IC_SaveImage
+ SaveImage.restype = C.c_int
+ SaveImage.argtypes = [C.c_void_p, C.c_char_p, C.c_int, C.c_int ]
+
+ OpenVideoCaptureDevice = __tisgrabber.IC_OpenVideoCaptureDevice
+ OpenVideoCaptureDevice.restype = C.c_int
+ OpenVideoCaptureDevice.argtypes = [C.c_void_p, C.c_char_p]
+
+# ############################################################################
+
+ ### GK Additions - adding frame filters. Pieces copied from: https://github.com/morefigs/py-ic-imaging-control
+
+ CreateFrameFilter = __tisgrabber.IC_CreateFrameFilter
+ CreateFrameFilter.restype = C.c_int
+ CreateFrameFilter.argtypes = (C.c_char_p, C.POINTER(FrameFilterHandle))
+
+ AddFrameFilter = __tisgrabber.IC_AddFrameFilterToDevice
+ AddFrameFilter.restype = C.c_int
+ AddFrameFilter.argtypes = (GrabberHandlePtr, C.POINTER(FrameFilterHandle))
+
+ FilterGetParameter = __tisgrabber.IC_FrameFilterGetParameter
+ FilterGetParameter.restype = C.c_int
+ FilterGetParameter.argtypes = (C.POINTER(FrameFilterHandle),
+ C.c_char_p,
+ C.c_void_p)
+
+ FilterSetParameter = __tisgrabber.IC_FrameFilterSetParameterInt
+ FilterSetParameter.restype = C.c_int
+ FilterSetParameter.argtypes = (C.POINTER(FrameFilterHandle),
+ C.c_char_p,
+ C.c_int)
+
+# ############################################################################
+
+
+class TIS_CAM(object):
+ @property
+ def callback_registered(self):
+ return self._callback_registered
+
+ def __init__(self):
+
+ self._handle = C.POINTER(GrabberHandle)
+ self._handle = TIS_GrabberDLL.create_grabber()
+ self._callback_registered = False
+ self._frame = {'num' : -1,
+ 'ready' : False}
+
+ def s(self,strin):
+ if sys.version[0] == "2":
+ return strin
+ if type(strin) == "byte":
+ return strin
+ return strin.encode("utf-8")
+
+ def SetFrameReadyCallback(self, CallbackFunction, data):
+ """ Set a callback function, which is called, when a new frame arrives.
+
+ CallbackFunction : The callback function
+
+ data : a self defined class with user data.
+ """
+ return TIS_GrabberDLL.SetFrameReadyCallback( self._handle, CallbackFunction, data )
+
+ def SetContinuousMode(self, Mode):
+ ''' Determines, whether new frames are automatically copied into memory.
+
+ :param Mode: If 0, all frames are copied automatically into memory. This is recommened, if the camera runs in trigger mode.
+ If 1, then snapImages must be called to get a frame into memory.
+ :return: None
+ '''
+ return TIS_GrabberDLL.SetContinuousMode(self._handle, Mode)
+
+ def open(self,unique_device_name):
+ """ Open a device
+
+ unique_device_name : The name and serial number of the device to be opened. The device name and serial number are separated by a space.
+ """
+ test = TIS_GrabberDLL.open_device_by_unique_name(self._handle,
+ self.s(unique_device_name))
+
+ return test
+
+ def close(self):
+ TIS_GrabberDLL.close_device(self._handle)
+
+ def ShowDeviceSelectionDialog(self):
+ self._handle = TIS_GrabberDLL.ShowDeviceSelectionDialog(self._handle)
+
+ def ShowPropertyDialog(self):
+ self._handle = TIS_GrabberDLL.ShowPropertyDialog(self._handle)
+
+ def IsDevValid(self):
+ return TIS_GrabberDLL.IsDevValid(self._handle)
+
+ def SetHWND(self, Hwnd):
+ return TIS_GrabberDLL.SetHWND(self._handle, Hwnd)
+
+ def SaveDeviceStateToFile(self, FileName):
+ return TIS_GrabberDLL.SaveDeviceStateToFile(self._handle, self.s(FileName))
+
+ def LoadDeviceStateFromFile(self,FileName):
+ self._handle = TIS_GrabberDLL.LoadDeviceStateFromFile(self._handle,self.s(FileName))
+
+
+ def SetVideoFormat(self,Format):
+ return TIS_GrabberDLL.set_videoformat(self._handle, self.s(Format))
+
+ def SetFrameRate(self,FPS):
+ return TIS_GrabberDLL.set_framerate(self._handle, FPS)
+
+ def get_video_format_width(self):
+ return TIS_GrabberDLL.get_video_format_width(self._handle)
+
+ def get_video_format_height(self):
+ return TIS_GrabberDLL.get_video_format_height(self._handle)
+
+
+ def GetDevices(self):
+ self._Devices=[]
+ iDevices = TIS_GrabberDLL.get_devicecount()
+ for i in range(iDevices):
+ self._Devices.append(TIS_GrabberDLL.get_unique_name_from_list(i))
+ return self._Devices
+
+
+ def GetVideoFormats(self):
+ self._Properties=[]
+ iVideoFormats = TIS_GrabberDLL.GetVideoFormatCount(self._handle)
+ for i in range(iVideoFormats):
+ self._Properties.append(TIS_GrabberDLL.GetVideoFormat(self._handle,i))
+ return self._Properties
+
+ def GetInputChannels(self):
+ self.InputChannels=[]
+ InputChannelscount = TIS_GrabberDLL.GetInputChannelCount(self._handle)
+ for i in range (InputChannelscount):
+ self.InputChannels.append(TIS_GrabberDLL.GetInputChannel(self._handle,i))
+ return self.InputChannels
+
+ def GetVideoNormCount(self):
+ self.GetVideoNorm=[]
+ GetVideoNorm_Count=TIS_GrabberDLL.GetVideoNormCount(self._handle)
+ for i in range(GetVideoNorm_Count):
+ self.GetVideoNorm.append(TIS_GrabberDLL.GetVideoNorm(self._handle, i))
+ return self.GetVideoNorm
+
+
+ def SetFormat(self, Format):
+ ''' SetFormat
+ Sets the pixel format in memory
+ @param Format Sinkformat enumeration
+ '''
+ TIS_GrabberDLL.SetFormat(self._handle, Format.value)
+
+ def GetFormat(self):
+ val = TIS_GrabberDLL.GetFormat(self._handle)
+ if val == 0:
+ return SinkFormats.Y800
+ if val == 2:
+ return SinkFormats.RGB32
+ if val == 1:
+ return SinkFormats.RGB24
+ if val == 3:
+ return SinkFormats.UYVY
+ if val == 4:
+ return SinkFormats.Y16
+ return SinkFormats.RGB24
+
+
+ def StartLive(self, showlive = 1):
+ """
+ Start the live video stream.
+
+ showlive: 1 : a live video is shown, 0 : the live video is not shown.
+ """
+ Error = TIS_GrabberDLL.StartLive(self._handle, showlive)
+ return Error
+
+ def StopLive(self):
+ """
+ Stop the live video.
+ """
+ Error = TIS_GrabberDLL.StopLive(self._handle)
+ return Error
+
+
+ def SnapImage(self):
+ Error = TIS_GrabberDLL.SnapImage(self._handle, 2000)
+ return Error
+
+
+ def GetImageDescription(self):
+ lWidth=C.c_long()
+ lHeight= C.c_long()
+ iBitsPerPixel=C.c_int()
+ COLORFORMAT=C.c_int()
+
+ Error = TIS_GrabberDLL.GetImageDescription(self._handle, lWidth,
+ lHeight,iBitsPerPixel,COLORFORMAT)
+ return (lWidth.value,lHeight.value,iBitsPerPixel.value,COLORFORMAT.value)
+
+ def GetImagePtr(self):
+ ImagePtr = TIS_GrabberDLL.GetImagePtr(self._handle)
+
+ return ImagePtr
+
+ def GetImage(self):
+ BildDaten = self.GetImageDescription()[:4]
+ lWidth=BildDaten[0]
+ lHeight= BildDaten[1]
+ iBitsPerPixel=BildDaten[2]//8
+
+ buffer_size = lWidth*lHeight*iBitsPerPixel*C.sizeof(C.c_uint8)
+ img_ptr = self.GetImagePtr()
+
+ Bild = C.cast(img_ptr, C.POINTER(C.c_ubyte * buffer_size))
+
+
+ img = np.ndarray(buffer = Bild.contents,
+ dtype = np.uint8,
+ shape = (lHeight,
+ lWidth,
+ iBitsPerPixel))
+ return img
+
+ def GetImageEx(self):
+ """ Return a numpy array with the image data tyes
+ If the sink is Y16 or RGB64 (not supported yet), the dtype in the array is uint16, othereise it is uint8
+ """
+ BildDaten = self.GetImageDescription()[:4]
+ lWidth=BildDaten[0]
+ lHeight= BildDaten[1]
+ iBytesPerPixel=BildDaten[2]//8
+
+ buffer_size = lWidth*lHeight*iBytesPerPixel*C.sizeof(C.c_uint8)
+ img_ptr = self.GetImagePtr()
+
+ Bild = C.cast(img_ptr, C.POINTER(C.c_ubyte * buffer_size))
+
+ pixeltype = np.uint8
+
+ if BildDaten[3] == 4: #SinkFormats.Y16:
+ pixeltype = np.uint16
+ iBytesPerPixel = 1
+
+ img = np.ndarray(buffer = Bild.contents,
+ dtype = pixeltype,
+ shape = (lHeight,
+ lWidth,
+ iBytesPerPixel))
+ return img
+
+
+ def GetCameraProperty(self,iProperty):
+ lFocusPos = C.c_long()
+ Error = TIS_GrabberDLL.GetCameraProperty(self._handle,iProperty, lFocusPos)
+ return (lFocusPos.value)
+
+ def SetCameraProperty(self,iProperty,iValue):
+ Error = TIS_GrabberDLL.SetCameraProperty(self._handle,iProperty, iValue)
+ return (Error)
+
+ def SetPropertyValue(self, Property, Element, Value ):
+ error = TIS_GrabberDLL.SetPropertyValue(self._handle,
+ self.s(Property),
+ self.s(Element),
+ Value)
+ return error
+
+
+ def GetPropertyValue(self, Property, Element ):
+ Value = C.c_long()
+ error = TIS_GrabberDLL.GetPropertyValue(self._handle,
+ self.s(Property),
+ self.s(Element),
+ Value)
+ return Value.value
+
+
+
+ def PropertyAvailable(self, Property):
+ Null = None
+ error = TIS_GrabberDLL.IsPropertyAvailable(self._handle,
+ self.s(Property),
+ Null)
+ return error
+
+
+ def SetPropertySwitch(self, Property, Element, Value):
+ error = TIS_GrabberDLL.SetPropertySwitch(self._handle,
+ self.s(Property),
+ self.s(Element),
+ Value)
+ return error
+
+ def GetPropertySwitch(self, Property, Element, Value):
+ lValue = C.c_long()
+ error = TIS_GrabberDLL.GetPropertySwitch(self._handle,
+ self.s(Property),
+ self.s(Element),
+ lValue)
+ Value[0] = lValue.value
+ return error
+
+ def PropertyOnePush(self, Property, Element ):
+ error = TIS_GrabberDLL.PropertyOnePush(self._handle,
+ self.s(Property),
+ self.s(Element ))
+ return error
+
+ def SetPropertyAbsoluteValue(self, Property, Element, Value ):
+ error = TIS_GrabberDLL.SetPropertyAbsoluteValue(self._handle,
+ self.s(Property),
+ self.s(Element),
+ Value)
+ return error
+
+ def GetPropertyAbsoluteValue(self, Property, Element,Value ):
+ """ Get a property value of absolute values interface, e.g. seconds or dB.
+ Example code:
+ ExposureTime=[0]
+ Camera.GetPropertyAbsoluteValue("Exposure","Value", ExposureTime)
+ print("Exposure time in secods: ", ExposureTime[0])
+
+ :param Property: Name of the property, e.g. Gain, Exposure
+ :param Element: Name of the element, e.g. "Value"
+ :param Value: Object, that receives the value of the property
+ :returns: 0 on success
+ """
+ lValue = C.c_float()
+ error = TIS_GrabberDLL.GetPropertyAbsoluteValue(self._handle,
+ self.s(Property),
+ self.s(Element),
+ lValue)
+ Value[0] = lValue.value
+ return error
+
+
+ def SaveImage(self,FileName, FileType, Quality=75):
+ ''' Saves the last snapped image. Can by of type BMP or JPEG.
+ :param FileName : Name of the mage file
+ :param FileType : Determines file type, can be "JPEG" or "BMP"
+ :param Quality : If file typ is JPEG, the qualitly can be given from 1 to 100.
+ :return: Error code
+ '''
+ return TIS_GrabberDLL.SaveImage(self._handle, self.s(FileName), IC.ImageFileTypes[self.s(FileType)],Quality)
+
+ def openVideoCaptureDevice(self, DeviceName):
+ ''' Open the device specified by DeviceName
+ :param DeviceName: Name of the device , e.g. "DFK 72AUC02"
+ :returns: 1 on success, 0 otherwise.
+ '''
+ return TIS_GrabberDLL.OpenVideoCaptureDevice(self._handle, self.s(DeviceName))
+
+ def CreateFrameFilter(self, name):
+ frame_filter_handle = FrameFilterHandle()
+
+ err = TIS_GrabberDLL.CreateFrameFilter(C.c_char_p(name), C.byref(frame_filter_handle))
+ if err != 1:
+ raise Exception("ERROR CREATING FILTER")
+ return frame_filter_handle
+
+ def AddFrameFilter(self, frame_filter_handle):
+ err = TIS_GrabberDLL.AddFrameFilter(self._handle, frame_filter_handle)
+ return err
+
+ def FilterGetParameter(self, frame_filter_handle, parameter_name):
+ data = C.c_int()
+
+ err = TIS_GrabberDLL.FilterGetParameter(frame_filter_handle, parameter_name, C.byref(data))
+ return err
+
+ def FilterSetParameter(self, frame_filter_handle, parameter_name, data):
+ if type(data) is int:
+ err = TIS_GrabberDLL.FilterSetParameter(frame_filter_handle,
+ C.c_char_p(parameter_name),
+ C.c_int(data))
+ return err
+ else:
+ raise Exception('Unknown set parameter type')
diff --git a/write_camera_details_TEMPLATE.py b/write_camera_details_TEMPLATE.py
index 96aa942..ed91c0f 100644
--- a/write_camera_details_TEMPLATE.py
+++ b/write_camera_details_TEMPLATE.py
@@ -20,13 +20,13 @@
cam_0 = {'name' : 'Cog Rig',
'crop' : {'top' : 150, 'left' : 225, 'height' : 250, 'width' : 300},
'rotate' : 0,
- 'exposure' : -14,
+ 'exposure' : .003,
'output_dir' : 'C:/Users/user1/Desktop/video/RIG6_DATA/cog_rig/video'}
cam_1 = {'name' : 'Neuro Rig',
'crop' : {'top' : 200, 'left' : 140, 'height' : 325, 'width' : 200},
'rotate' : 90,
- 'exposure' : -6,
+ 'exposure' : .003,
'output_dir' : 'C:/Users/user1/Desktop/video/RIG6_DATA/cog_rig/video'}
subs = ['test1', 'test2', 'test3'] # optional, can manually enter subject for each session.