├── setup.cfg ├── pixelinkWrapper └── __init__.py ├── samples ├── Linux │ ├── getXml.py │ ├── getNumberCameras.py │ ├── recoverCamera.py │ ├── jumboFrames.py │ ├── measureCallbackRate.py │ ├── setIpAddress.py │ ├── getNextFrame.py │ ├── getNextNumPyFrame.py │ ├── ptpV2.py │ ├── eventCallback.py │ ├── getCameraInfo.py │ ├── gigeHeartbeat.py │ ├── getFeature.py │ ├── measureGetNextFrameRate.py │ ├── commitSettingsAsDefault.py │ ├── autoWhiteBalance.py │ ├── setFeature.py │ ├── preview.py │ ├── lowLinkMemory.py │ ├── openCVSnapshot.py │ ├── frameActions.py │ ├── saveSettings.py │ ├── softwareTriggerWithCallback.py │ ├── gpio.py │ ├── getMultipleSnapshots.py │ └── callback.py └── Windows │ ├── getXml.py │ ├── getNumberCameras.py │ ├── measureCallbackRate.py │ ├── recoverCamera.py │ ├── jumboFrames.py │ ├── eventCallback.py │ ├── setIpAddress.py │ ├── getNextFrame.py │ ├── measureGetNextFrameRate.py │ ├── getNextNumPyFrame.py │ ├── ptpV2.py │ ├── getCameraInfo.py │ ├── gigeHeartbeat.py │ ├── getFeature.py │ ├── commitSettingsAsDefault.py │ ├── autoWhiteBalance.py │ ├── setFeature.py │ ├── previewWithTk.py │ ├── gpio.py │ ├── openCVSnapshot.py │ ├── preview.py │ ├── frameActions.py │ ├── saveSettings.py │ ├── previewWithPyQt5.py │ ├── softwareTriggerWithCallback.py │ └── getMultipleSnapshots.py └── LICENSE.txt /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | license_files = LICENSE.txt 3 | -------------------------------------------------------------------------------- /pixelinkWrapper/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A Pixelink API Python wrapper package for Pixelink cameras 3 | """ 4 | 5 | from . pixelink import PxLApi 6 | 7 | __all__ = ["PxLApi"] 8 | __version__ = "1.4.1" 9 | -------------------------------------------------------------------------------- /samples/Linux/getXml.py: -------------------------------------------------------------------------------- 1 | """ 2 | getXml.py 3 | 4 | A simple demonstration of reading the XML file for a given camera 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | 9 | EXIT_SUCCESS = 0 10 | EXIT_FAILURE = 1 11 | 12 | def main(): 13 | 14 | # Initialize any camera 15 | ret = PxLApi.initialize(0) 16 | if not PxLApi.apiSuccess(ret[0]): 17 | print("ERROR: Unable to initialize a camera (%d)" % ret[0]) 18 | return EXIT_FAILURE 19 | 20 | hCamera = ret[1] 21 | 22 | # Grab the XML from the camera 23 | ret = PxLApi.getCameraXml(hCamera) 24 | if not PxLApi.apiSuccess(ret[0]): 25 | print("ERROR: Cannot read the XML file of this camera (%d)" % ret[0]) 26 | PxLApi.uninitialize(hCamera) 27 | return EXIT_FAILURE 28 | 29 | xmlFile = ret[1] 30 | 31 | print("=================== Camera's XML file (%d bytes) ===================\n" % len(xmlFile)) 32 | print("%s" % str(xmlFile, encoding='utf-8'), end='') 33 | 34 | PxLApi.uninitialize(hCamera) 35 | return EXIT_SUCCESS 36 | 37 | 38 | if __name__ == "__main__": 39 | main() -------------------------------------------------------------------------------- /samples/Windows/getXml.py: -------------------------------------------------------------------------------- 1 | """ 2 | getXml.py 3 | 4 | A simple demonstration of reading the XML file for a given camera 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | 9 | EXIT_SUCCESS = 0 10 | EXIT_FAILURE = 1 11 | 12 | def main(): 13 | 14 | # Initialize any camera 15 | ret = PxLApi.initialize(0) 16 | if not PxLApi.apiSuccess(ret[0]): 17 | print("ERROR: Unable to initialize a camera (%d)" % ret[0]) 18 | return EXIT_FAILURE 19 | 20 | hCamera = ret[1] 21 | 22 | # Grab the XML from the camera 23 | ret = PxLApi.getCameraXml(hCamera) 24 | if not PxLApi.apiSuccess(ret[0]): 25 | print("ERROR: Cannot read the XML file of this camera (%d)" % ret[0]) 26 | PxLApi.uninitialize(hCamera) 27 | return EXIT_FAILURE 28 | 29 | xmlFile = ret[1] 30 | 31 | print("=================== Camera's XML file (%d bytes) ===================\n" % len(xmlFile)) 32 | print("%s" % str(xmlFile, encoding='utf-8'), end='') 33 | 34 | PxLApi.uninitialize(hCamera) 35 | return EXIT_SUCCESS 36 | 37 | 38 | if __name__ == "__main__": 39 | main() -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Pixelink an Ametek company 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /samples/Linux/getNumberCameras.py: -------------------------------------------------------------------------------- 1 | """ 2 | getNumberCameras.py 3 | 4 | Simple sample application demostrating the use of the getNumberCameras function 5 | in the pixelinkWrapper. 6 | """ 7 | from pixelinkWrapper import* 8 | 9 | 10 | def main(): 11 | 12 | # 13 | # Call getNumberCameras to see not only how many Pixelink cameras 14 | # are connected to this system, but to get connection information on 15 | # each of the cameras found 16 | # 17 | # Like all pixelinkWrapper functions, getNumberCameras returns a tuple with 18 | # a number of elements. More specifically, getNumberCameras will return: 19 | # ret[0] - Return code 20 | # ret[1] - A list of PxLApi._CameraIdInfo(s), with an element for each camera found 21 | ret = PxLApi.getNumberCameras() 22 | if PxLApi.apiSuccess(ret[0]): 23 | 24 | # The list of cameras found is actually a list of PxLApi._CameraIdInfo(s). See the 25 | # Pixelink API documentation for details on each of the fields in the CAMERA_ID_INFO 26 | cameras = ret[1] 27 | print ("Found %d Cameras:" % len(cameras)) 28 | for i in range(len(cameras)): 29 | print(" Serial number - %d" % cameras[i].CameraSerialNum) 30 | else: 31 | print ("getNumberCameras return code: %d" % ret[0]) 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /samples/Windows/getNumberCameras.py: -------------------------------------------------------------------------------- 1 | """ 2 | getNumberCameras.py 3 | 4 | Simple sample application demostrating the use of the getNumberCameras function 5 | in the pixelinkWrapper. 6 | """ 7 | from pixelinkWrapper import* 8 | 9 | 10 | def main(): 11 | 12 | # 13 | # Call getNumberCameras to see not only how many Pixelink cameras 14 | # are connected to this system, but to get connection information on 15 | # each of the cameras found 16 | # 17 | # Like all pixelinkWrapper functions, getNumberCameras returns a tuple with 18 | # a number of elements. More specifically, getNumberCameras will return: 19 | # ret[0] - Return code 20 | # ret[1] - A list of PxLApi._CameraIdInfo(s), with an element for each camera found 21 | ret = PxLApi.getNumberCameras() 22 | if PxLApi.apiSuccess(ret[0]): 23 | 24 | # The list of cameras found is actually a list of PxLApi._CameraIdInfo(s). See the 25 | # Pixelink API documentation for details on each of the fields in the CAMERA_ID_INFO 26 | cameras = ret[1] 27 | print ("Found %d Cameras:" % len(cameras)) 28 | for i in range(len(cameras)): 29 | print(" Serial number - %d" % cameras[i].CameraSerialNum) 30 | else: 31 | print ("getNumberCameras return code: %d" % ret[0]) 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /samples/Windows/measureCallbackRate.py: -------------------------------------------------------------------------------- 1 | """ 2 | measureCallbackRate.py 3 | 4 | Sample code to show how to create a simple callback. This program simply 5 | calculates the frame rate of the camera (via callbacks). 6 | """ 7 | 8 | from pixelinkWrapper import* 9 | import sys 10 | import time 11 | import msvcrt 12 | 13 | 14 | @PxLApi._dataProcessFunction 15 | def simple_callback(hCamera, frameData, dataFormat, frameDesc, userData): 16 | 17 | global gCallbackCount 18 | gCallbackCount += 1 19 | 20 | return 0 21 | 22 | 23 | def main(): 24 | 25 | sys.stdin.flush() 26 | 27 | ret = PxLApi.initialize(0) 28 | if not(PxLApi.apiSuccess(ret[0])): 29 | print("Could not initialize the camera! rc = %i" % ret[0]) 30 | return 1 31 | 32 | hCamera = ret[1] 33 | 34 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, None, simple_callback) 35 | if PxLApi.apiSuccess(ret[0]): 36 | ret = PxLApi.setStreamState(hCamera,PxLApi.StreamState.START) 37 | if PxLApi.apiSuccess(ret[0]): 38 | 39 | print("Counting the number of images over a 20 second period...") 40 | 41 | time.sleep(20) # Delay 20 seconds 42 | callbackCount = gCallbackCount 43 | 44 | PxLApi.setStreamState(hCamera,PxLApi.StreamState.STOP) 45 | PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, None, None) # Remove the callback 46 | print(" Received %i frames, or %8.2f frames/second" % (callbackCount, (float)(callbackCount/20.0))) 47 | print("Press any key to exit") 48 | 49 | kbHit() 50 | 51 | PxLApi.uninitialize(hCamera) 52 | 53 | return 0 54 | 55 | """ 56 | Unbuffered keyboard input on command line. 57 | Keyboard input will be passed to the application without the user pressing 58 | the enter key. 59 | Note: IDLE does not support this functionality. 60 | """ 61 | def kbHit(): 62 | keyPressed = msvcrt.getch() 63 | if b'\xe0' == keyPressed: 64 | return str(keyPressed) 65 | return str(keyPressed, "utf-8") 66 | 67 | 68 | if __name__ == "__main__": 69 | gCallbackCount = 0 # Careful -- this global is not protected by a mutex 70 | main() -------------------------------------------------------------------------------- /samples/Linux/recoverCamera.py: -------------------------------------------------------------------------------- 1 | """ 2 | recoverCamera.py 3 | 4 | Demonstrates how to 'fully initialize' a camera. That is, to connect to a camera in an 5 | unknown state, and to initialize the camera so that it is in a known, default state. 6 | 7 | The techniques shown here are particularly useful if your applications crashes, or is shut 8 | down, without having to having done the necessary 'cleanup' operations. 9 | """ 10 | 11 | from pixelinkWrapper import* 12 | 13 | 14 | def main(): 15 | 16 | """ 17 | Step 1. 18 | Initialize the camera in a stream stopped state. 19 | 20 | If a camera control application 'crashes' while stream a camera, then the 21 | camera is left in a state where it is trying to output images to the host, 22 | but the host is not in a state to receive images. This is characterized 23 | by the camera's LED flashing red. Under these circumstances, the USB host 24 | may have difficulties initializing the camera, and establishing a control 25 | path to the camera. 26 | 27 | Under these circumstances, asserting a stream stop state at initialization, 28 | will ensure the camera control path gets properly established. Applications 29 | may want to consider using PxLApi.InitializeExFlags.ISSUE_STREAM_STOP every 30 | time they initialize a camera, but keep in mind this may not have the desired 31 | effect if you have multiple applications controlling the same camera. 32 | """ 33 | 34 | # We assume there's only one camera connected 35 | ret = PxLApi.initialize(0, PxLApi.InitializeExFlags.ISSUE_STREAM_STOP) 36 | if PxLApi.apiSuccess(ret[0]): 37 | hCamera = ret[1] 38 | 39 | """ 40 | Step 2. 41 | Assert all camera features to the factory default values. 42 | 43 | Rather than leave the camera parameters at their last used value, 44 | set them to factory default values. 45 | """ 46 | 47 | ret = PxLApi.loadSettings(hCamera, PxLApi.Settings.SETTINGS_FACTORY) 48 | if not PxLApi.apiSuccess(ret[0]): 49 | print("Could not load factory settings!") 50 | else: 51 | print("Factory default settings restored") 52 | 53 | # Uninitialize the camera now that we're done with it. 54 | PxLApi.uninitialize(hCamera) 55 | else: 56 | print("Could not initialize a camera!") 57 | 58 | return 0 59 | 60 | 61 | if __name__ == "__main__": 62 | main() 63 | -------------------------------------------------------------------------------- /samples/Windows/recoverCamera.py: -------------------------------------------------------------------------------- 1 | """ 2 | recoverCamera.py 3 | 4 | Demonstrates how to 'fully initialize' a camera. That is, to connect to a camera in an 5 | unknown state, and to initialize the camera so that it is in a known, default state. 6 | 7 | The techniques shown here are particularly useful if your applications crashes, or is shut 8 | down, without having to having done the necessary 'cleanup' operations. 9 | """ 10 | 11 | from pixelinkWrapper import* 12 | 13 | 14 | def main(): 15 | 16 | """ 17 | Step 1. 18 | Initialize the camera in a stream stopped state. 19 | 20 | If a camera control application 'crashes' while stream a camera, then the 21 | camera is left in a state where it is trying to output images to the host, 22 | but the host is not in a state to receive images. This is characterized 23 | by the camera's LED flashing red. Under these circumstances, the USB host 24 | may have difficulties initializing the camera, and establishing a control 25 | path to the camera. 26 | 27 | Under these circumstances, asserting a stream stop state at initialization, 28 | will ensure the camera control path gets properly established. Applications 29 | may want to consider using PxLApi.InitializeExFlags.ISSUE_STREAM_STOP every 30 | time they initialize a camera, but keep in mind this may not have the desired 31 | effect if you have multiple applications controlling the same camera. 32 | """ 33 | 34 | # We assume there's only one camera connected 35 | ret = PxLApi.initialize(0, PxLApi.InitializeExFlags.ISSUE_STREAM_STOP) 36 | if PxLApi.apiSuccess(ret[0]): 37 | hCamera = ret[1] 38 | 39 | """ 40 | Step 2. 41 | Assert all camera features to the factory default values. 42 | 43 | Rather than leave the camera parameters at their last used value, 44 | set them to factory default values. 45 | """ 46 | 47 | ret = PxLApi.loadSettings(hCamera, PxLApi.Settings.SETTINGS_FACTORY) 48 | if not PxLApi.apiSuccess(ret[0]): 49 | print("Could not load factory settings!") 50 | else: 51 | print("Factory default settings restored") 52 | 53 | # Uninitialize the camera now that we're done with it. 54 | PxLApi.uninitialize(hCamera) 55 | else: 56 | print("Could not initialize a camera!") 57 | 58 | return 0 59 | 60 | 61 | if __name__ == "__main__": 62 | main() 63 | -------------------------------------------------------------------------------- /samples/Linux/jumboFrames.py: -------------------------------------------------------------------------------- 1 | """ 2 | jumboFrames.py 3 | 4 | A demonstration of how to enable jumbo frames for a Gigabit Ethernet camera. 5 | 6 | NOTE: 7 | - All GigE cameras initialized after jumbo frames are enabled will use jumbo frames. 8 | - All GigE cameras initialized after jumbo frames are disabled will not use jumbo frames. 9 | - Support for jumbo frames is limited to the life of the application. i.e. You must enable it 10 | each time your program runs. 11 | - Support for jumbo frames is limited to the life of the application enabling jumbo frames. i.e. If you have 12 | another program talking to a Pixelink GigE camera, that application must itself enable jumbo frames. 13 | BE AWARE: 14 | - The IEEE 802 standards committee does not official recognize jumbo frames. 15 | 16 | - By "enabling" jumbo frames here, the Pixelink library is simply being asked to use jumbo frames. Your 17 | network interface card (NIC) must not only support jumbo frames, but must also have jumbo frames enabled. 18 | 19 | - NICs that do support jumbo frames typically default to jumbo frame support DISABLED. Please consult the 20 | documentation for your NIC. 21 | 22 | - All devices (routers, switches etc.) between the host NIC and the GigE camera must support and have 23 | jumbo frames enabled. 24 | """ 25 | 26 | from pixelinkWrapper import* 27 | 28 | PRIVATE_COMMAND_ENABLE_JUMBO_FRAMES = 37 29 | PRIVATE_COMMAND_DISABLE_JUMBO_FRAMES = 38 30 | 31 | """ 32 | Enable or disable jumbo frame support in the Pixelink API. 33 | """ 34 | def enable_jumbo_frames(enable): 35 | 36 | hCamera = None 37 | opcode = [PRIVATE_COMMAND_ENABLE_JUMBO_FRAMES] if enable == True else PRIVATE_COMMAND_DISABLE_JUMBO_FRAMES 38 | ret = PxLApi.privateCmd(hCamera, opcode) 39 | return ret 40 | 41 | 42 | def main(): 43 | 44 | # Enable jumbo frames before we connect to any GigE cameras 45 | ret = enable_jumbo_frames(True) 46 | if not PxLApi.apiSuccess(ret[0]): 47 | print("ERROR: Unable to enable jumbo frames. Error code %d." % ret[0]) 48 | return 1 49 | 50 | # And now any GigE cameras initialized after this will use jumbo frames. 51 | # Just connecting to a camera (any camera) 52 | ret = PxLApi.initialize(0) 53 | if not PxLApi.apiSuccess(ret[0]): 54 | print("ERROR: Unable to initialize a camera. Error code %d." % ret[0]) 55 | return 1 56 | 57 | hCamera = ret[1] 58 | 59 | # Do camera stuff 60 | 61 | PxLApi.uninitialize(hCamera) 62 | return 0 63 | 64 | 65 | if __name__ == "__main__": 66 | main() -------------------------------------------------------------------------------- /samples/Windows/jumboFrames.py: -------------------------------------------------------------------------------- 1 | """ 2 | jumboFrames.py 3 | 4 | A demonstration of how to enable jumbo frames for a Gigabit Ethernet camera. 5 | 6 | NOTE: 7 | - All GigE cameras initialized after jumbo frames are enabled will use jumbo frames. 8 | - All GigE cameras initialized after jumbo frames are disabled will not use jumbo frames. 9 | - Support for jumbo frames is limited to the life of the application. i.e. You must enable it 10 | each time your program runs. 11 | - Support for jumbo frames is limited to the life of the application enabling jumbo frames. i.e. If you have 12 | another program talking to a Pixelink GigE camera, that application must itself enable jumbo frames. 13 | BE AWARE: 14 | - The IEEE 802 standards committee does not official recognize jumbo frames. 15 | 16 | - By "enabling" jumbo frames here, the Pixelink library is simply being asked to use jumbo frames. Your 17 | network interface card (NIC) must not only support jumbo frames, but must also have jumbo frames enabled. 18 | 19 | - NICs that do support jumbo frames typically default to jumbo frame support DISABLED. Please consult the 20 | documentation for your NIC. 21 | 22 | - All devices (routers, switches etc.) between the host NIC and the GigE camera must support and have 23 | jumbo frames enabled. 24 | """ 25 | 26 | from pixelinkWrapper import* 27 | 28 | PRIVATE_COMMAND_ENABLE_JUMBO_FRAMES = 37 29 | PRIVATE_COMMAND_DISABLE_JUMBO_FRAMES = 38 30 | 31 | """ 32 | Enable or disable jumbo frame support in the Pixelink API. 33 | """ 34 | def enable_jumbo_frames(enable): 35 | 36 | hCamera = None 37 | opcode = [PRIVATE_COMMAND_ENABLE_JUMBO_FRAMES] if enable == True else PRIVATE_COMMAND_DISABLE_JUMBO_FRAMES 38 | ret = PxLApi.privateCmd(hCamera, opcode) 39 | return ret 40 | 41 | 42 | def main(): 43 | 44 | # Enable jumbo frames before we connect to any GigE cameras 45 | ret = enable_jumbo_frames(True) 46 | if not PxLApi.apiSuccess(ret[0]): 47 | print("ERROR: Unable to enable jumbo frames. Error code %d." % ret[0]) 48 | return 1 49 | 50 | # And now any GigE cameras initialized after this will use jumbo frames. 51 | # Just connecting to a camera (any camera) 52 | ret = PxLApi.initialize(0) 53 | if not PxLApi.apiSuccess(ret[0]): 54 | print("ERROR: Unable to initialize a camera. Error code %d." % ret[0]) 55 | return 1 56 | 57 | hCamera = ret[1] 58 | 59 | # Do camera stuff 60 | 61 | PxLApi.uninitialize(hCamera) 62 | return 0 63 | 64 | 65 | if __name__ == "__main__": 66 | main() -------------------------------------------------------------------------------- /samples/Linux/measureCallbackRate.py: -------------------------------------------------------------------------------- 1 | """ 2 | measureCallbackRate.py 3 | 4 | Sample code to show how to create a simple callback. This program simply 5 | calculates the frame rate of the camera (via callbacks). 6 | """ 7 | 8 | from pixelinkWrapper import* 9 | from select import select 10 | import sys 11 | import time 12 | import tty 13 | import termios 14 | 15 | 16 | @PxLApi._dataProcessFunction 17 | def simple_callback(hCamera, frameData, dataFormat, frameDesc, userData): 18 | 19 | global gCallbackCount 20 | gCallbackCount += 1 21 | 22 | return 0 23 | 24 | 25 | def main(): 26 | 27 | sys.stdin.flush() 28 | 29 | ret = PxLApi.initialize(0) 30 | if not(PxLApi.apiSuccess(ret[0])): 31 | print("Could not initialize the camera! rc = %i" % ret[0]) 32 | return 1 33 | 34 | hCamera = ret[1] 35 | 36 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, None, simple_callback) 37 | if PxLApi.apiSuccess(ret[0]): 38 | ret = PxLApi.setStreamState(hCamera,PxLApi.StreamState.START) 39 | if PxLApi.apiSuccess(ret[0]): 40 | 41 | print("Counting the number of images over a 20 second period...") 42 | 43 | time.sleep(20) # Delay 20 seconds 44 | callbackCount = gCallbackCount 45 | 46 | PxLApi.setStreamState(hCamera,PxLApi.StreamState.STOP) 47 | PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, None, None) # Remove the callback 48 | print(" Received %i frames, or %8.2f frames/second" % (callbackCount, (float)(callbackCount/20.0))) 49 | print("Press any key to exit") 50 | 51 | setUnbufKb(True) 52 | kbHit() 53 | setUnbufKb(False) 54 | print("\r") 55 | 56 | PxLApi.uninitialize(hCamera) 57 | 58 | return 0 59 | 60 | """ 61 | Unbuffered keyboard input on command line. 62 | Keyboard input will be passed to the application without the user pressing 63 | the enter key. 64 | Note: IDLE does not support this functionality. 65 | """ 66 | # A couple of useful global variables 67 | fd = sys.stdin.fileno() 68 | original_term_settings = termios.tcgetattr(fd) 69 | 70 | # Enable/disable unbuffered keyboard input 71 | def setUnbufKb(enable): 72 | if enable: 73 | tty.setraw(sys.stdin.fileno()) 74 | else: 75 | termios.tcsetattr(fd, termios.TCSADRAIN, original_term_settings) 76 | 77 | # Read hit button 78 | def kbHit(): 79 | return sys.stdin.read(1) 80 | 81 | 82 | if __name__ == "__main__": 83 | gCallbackCount = 0 # Careful -- this global is not protected by a mutex 84 | main() -------------------------------------------------------------------------------- /samples/Windows/eventCallback.py: -------------------------------------------------------------------------------- 1 | """ 2 | eventCallback.py 3 | 4 | Demonstrates how to use event callbacks 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | import time 9 | import msvcrt 10 | 11 | STALL_TIME = 20 # 20 seconds 12 | EXIT_SUCCESS = 0 13 | EXIT_FAILURE = 1 14 | 15 | """ 16 | Callback function called by the API with each event (of interest) reported by the camera. 17 | N.B. This is called by the API on a thread created in the API. 18 | """ 19 | @PxLApi._eventProcessFunction 20 | def event_callback_func( 21 | hCamera, \ 22 | eventId, \ 23 | eventTimestamp, \ 24 | numDataBytes, \ 25 | data, \ 26 | userData): 27 | 28 | # Copy event specific data, if it is provided 29 | eventData = data.contents if bool(data) == True else 0 30 | 31 | print("EventCallbackFunction: hCamera=%s, eventId=%d" % (hex(hCamera), eventId)) 32 | print(" eventTimestamp=%f, numDataBytes=%d" % (eventTimestamp, numDataBytes)) 33 | print(" eventData=%s, userData=%d (%s)\n" % (hex(eventData), userData, hex(userData))) 34 | return PxLApi.ReturnCode.ApiSuccess 35 | 36 | 37 | def main(): 38 | 39 | print("This sample application will use the GPI line to demostrate events, OK to proceed Y/N?") 40 | userChar = kbHit() 41 | if 'y' != userChar and 'Y' != userChar: 42 | return EXIT_SUCCESS 43 | 44 | ret = PxLApi.initialize(0) 45 | if not PxLApi.apiSuccess(ret[0]): 46 | print("ERROR on PxLApi.initialize: %d" % ret[0]) 47 | return EXIT_FAILURE 48 | 49 | hCamera = ret[1] 50 | 51 | print("\nMain thread, stalling for %d seconds awaiting events. Toggle the GPI line...\n" % STALL_TIME) 52 | 53 | userData = 1526647550 # hex(0x5AFECAFE) 54 | # Note: We can specify a specific event, or all of them 55 | ret = PxLApi.setEventCallback( 56 | hCamera, \ 57 | PxLApi.EventId.ANY, \ 58 | userData, \ 59 | event_callback_func) 60 | 61 | if not PxLApi.apiSuccess(ret[0]): 62 | retErr = PxLApi.getErrorReport(hCamera) 63 | err = retErr[1] 64 | print("ERROR setting event callback function: %d (%s)" % (ret[0], str(err.strReturnCode, encoding='utf-8'))) 65 | PxLApi.uninitialize(hCamera) 66 | return EXIT_FAILURE 67 | 68 | time.sleep(STALL_TIME) 69 | 70 | PxLApi.setEventCallback(hCamera, PxLApi.EventId.ANY, userData, 0) # Cancel the callback 71 | PxLApi.uninitialize(hCamera) 72 | return EXIT_SUCCESS 73 | 74 | 75 | """ 76 | Unbuffered keyboard input on command line. 77 | Keyboard input will be passed to the application without the user pressing 78 | the enter key. 79 | Note: IDLE does not support this functionality. 80 | """ 81 | def kbHit(): 82 | keyPressed = msvcrt.getch() 83 | if b'\xe0' == keyPressed: 84 | return str(keyPressed) 85 | return str(keyPressed, "utf-8") 86 | 87 | 88 | if __name__ == "__main__": 89 | main() 90 | -------------------------------------------------------------------------------- /samples/Linux/setIpAddress.py: -------------------------------------------------------------------------------- 1 | """ 2 | setIpAddress.py 3 | 4 | This demonstration application assumes that you have one GigE camera visible to the host, and that 5 | that GigE camera is connected to a GigE card with a statically assigned IP address. 6 | 7 | This demo app is incomplete in that we can't know a priori what IP address, subnet mask and 8 | gateway *YOU* need to set. If you're unsure what values these need to be, please consult 9 | your local network administrator/administratrix. 10 | """ 11 | 12 | from pixelinkWrapper import* 13 | 14 | A_OK = 0 # non-zero error codes 15 | GENERAL_ERROR = 1 16 | 17 | """ 18 | Check if an IP address matches the network interface card (NIC) subnet 19 | """ 20 | def is_subnet_matches(cameraIpAddress, cameraSubnetMask, cameraIdInfo): 21 | 22 | cameraSubnetAddress = list() 23 | nicSubnetAddress = list() 24 | for i in range(len(cameraIpAddress)): 25 | cameraSubnetAddress.append(cameraIpAddress[i] & cameraSubnetMask[i]) 26 | 27 | for i in range(len(cameraIdInfo.NicIpAddress.Address.u8Address)): 28 | nicSubnetAddress.append(cameraIdInfo.NicIpAddress.Address.u8Address[i] & cameraIdInfo.NicIpMask.Address.u8Address[i]) 29 | 30 | for i in range(len(cameraIpAddress)): 31 | if cameraSubnetAddress[i] != nicSubnetAddress[i]: 32 | return False 33 | 34 | return True 35 | 36 | def main(): 37 | 38 | # ******************* NOTE: Assign your values here ******************* 39 | cameraIpAddress = (192, 168, 1, 2) 40 | cameraSubnetMask = (255, 255, 255, 0) 41 | cameraDefaultGateway = (222, 1, 1, 1) 42 | addressIsPersistent = False 43 | # ******************* NOTE: Assign your values here ******************* 44 | 45 | # Remove this after you've set up your own appropriate values above. 46 | print("This demonstration application has not been configured for your local environment\nSee the notes in setIpAddress.py for more information.") 47 | return GENERAL_ERROR 48 | 49 | # Check our assumption that there's only one camera 50 | ret = PxLApi.getNumberCameras() 51 | numberOfCameras = ret[1] 52 | 53 | assert PxLApi.apiSuccess(ret[0]) 54 | assert 1 == len(numberOfCameras) 55 | 56 | # Get the information for that camera 57 | cameraIdInfo = numberOfCameras[0] 58 | 59 | # A bit of sanity checking 60 | assert cameraIdInfo.NicIpAddress.Address.u32Address != 0 61 | 62 | if not is_subnet_matches(cameraIpAddress, cameraSubnetMask, cameraIdInfo): 63 | print("WARNING: You are setting an IP address that doesn't match the network interface card (NIC) subnet") 64 | 65 | # Copy MAC address found in the cameraIdInfo into a list 66 | cameraMacAddress = list() 67 | for i in range(len(cameraIdInfo.CameraMac.MacAddr)): 68 | cameraMacAddress.append(cameraIdInfo.CameraMac.MacAddr[i]) 69 | 70 | ret = PxLApi.setCameraIpAddress(cameraMacAddress, cameraIpAddress, cameraSubnetMask, cameraDefaultGateway, addressIsPersistent) 71 | 72 | print("PxLApi.setCameraIpAddress returned %d" % ret[0]) 73 | if not PxLApi.apiSuccess(ret[0]): 74 | return GENERAL_ERROR 75 | 76 | return A_OK 77 | 78 | 79 | if __name__ == "__main__": 80 | main() 81 | -------------------------------------------------------------------------------- /samples/Windows/setIpAddress.py: -------------------------------------------------------------------------------- 1 | """ 2 | setIpAddress.py 3 | 4 | This demonstration application assumes that you have one GigE camera visible to the host, and that 5 | that GigE camera is connected to a GigE card with a statically assigned IP address. 6 | 7 | This demo app is incomplete in that we can't know a priori what IP address, subnet mask and 8 | gateway *YOU* need to set. If you're unsure what values these need to be, please consult 9 | your local network administrator/administratrix. 10 | """ 11 | 12 | from pixelinkWrapper import* 13 | 14 | A_OK = 0 # non-zero error codes 15 | GENERAL_ERROR = 1 16 | 17 | """ 18 | Check if an IP address matches the network interface card (NIC) subnet 19 | """ 20 | def is_subnet_matches(cameraIpAddress, cameraSubnetMask, cameraIdInfo): 21 | 22 | cameraSubnetAddress = list() 23 | nicSubnetAddress = list() 24 | for i in range(len(cameraIpAddress)): 25 | cameraSubnetAddress.append(cameraIpAddress[i] & cameraSubnetMask[i]) 26 | 27 | for i in range(len(cameraIdInfo.NicIpAddress.Address.u8Address)): 28 | nicSubnetAddress.append(cameraIdInfo.NicIpAddress.Address.u8Address[i] & cameraIdInfo.NicIpMask.Address.u8Address[i]) 29 | 30 | for i in range(len(cameraIpAddress)): 31 | if cameraSubnetAddress[i] != nicSubnetAddress[i]: 32 | return False 33 | 34 | return True 35 | 36 | def main(): 37 | 38 | # ******************* NOTE: Assign your values here ******************* 39 | cameraIpAddress = (192, 168, 1, 2) 40 | cameraSubnetMask = (255, 255, 255, 0) 41 | cameraDefaultGateway = (222, 1, 1, 1) 42 | addressIsPersistent = False 43 | # ******************* NOTE: Assign your values here ******************* 44 | 45 | # Remove this after you've set up your own appropriate values above. 46 | print("This demonstration application has not been configured for your local environment\nSee the notes in setIpAddress.py for more information.") 47 | return GENERAL_ERROR 48 | 49 | # Check our assumption that there's only one camera 50 | ret = PxLApi.getNumberCameras() 51 | numberOfCameras = ret[1] 52 | 53 | assert PxLApi.apiSuccess(ret[0]) 54 | assert 1 == len(numberOfCameras) 55 | 56 | # Get the information for that camera 57 | cameraIdInfo = numberOfCameras[0] 58 | 59 | # A bit of sanity checking 60 | assert cameraIdInfo.NicIpAddress.Address.u32Address != 0 61 | 62 | if not is_subnet_matches(cameraIpAddress, cameraSubnetMask, cameraIdInfo): 63 | print("WARNING: You are setting an IP address that doesn't match the network interface card (NIC) subnet") 64 | 65 | # Copy MAC address found in the cameraIdInfo into a list 66 | cameraMacAddress = list() 67 | for i in range(len(cameraIdInfo.CameraMac.MacAddr)): 68 | cameraMacAddress.append(cameraIdInfo.CameraMac.MacAddr[i]) 69 | 70 | ret = PxLApi.setCameraIpAddress(cameraMacAddress, cameraIpAddress, cameraSubnetMask, cameraDefaultGateway, addressIsPersistent) 71 | 72 | print("PxLApi.setCameraIpAddress returned %d" % ret[0]) 73 | if not PxLApi.apiSuccess(ret[0]): 74 | return GENERAL_ERROR 75 | 76 | return A_OK 77 | 78 | 79 | if __name__ == "__main__": 80 | main() 81 | -------------------------------------------------------------------------------- /samples/Linux/getNextFrame.py: -------------------------------------------------------------------------------- 1 | """ 2 | getNextFrame.py 3 | 4 | A demonstration of a robust wrapper around PxLApi.getNextFrame. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import time 10 | 11 | # Just going to declare a very large buffer here. One that's large enough for any Pixelink camera 12 | MAX_IMAGE_SIZE = 5000*5000*2 13 | 14 | """ 15 | A robust wrapper around PxLApi.getNextFrame. 16 | This will handle the occasional error that can be returned by the API because of timeouts. 17 | 18 | Note that this should only be called when grabbing images from a camera NOT currently configured for triggering. 19 | """ 20 | def get_next_frame(hCamera, frame, maxNumberOfTries): 21 | 22 | ret = (PxLApi.ReturnCode.ApiUnknownError,) 23 | 24 | for i in range(maxNumberOfTries): 25 | ret = PxLApi.getNextFrame(hCamera, frame) 26 | if PxLApi.apiSuccess(ret[0]): 27 | return ret 28 | else: 29 | # If the streaming is turned off, or worse yet -- is gone? 30 | # If so, no sense in continuing. 31 | if PxLApi.ReturnCode.ApiStreamStopped == ret[0] or \ 32 | PxLApi.ReturnCode.ApiNoCameraAvailableError == ret[0]: 33 | return ret 34 | else: 35 | print(" Hmmm... getNextFrame returned %i" % ret[0]) 36 | 37 | # Ran out of tries, so return whatever the last error was. 38 | return ret 39 | 40 | 41 | def main(): 42 | 43 | firstFrame = True 44 | firstFrameTime = 0.0 45 | frame = create_string_buffer(MAX_IMAGE_SIZE) # Just going to declare a very large buffer here. 46 | 47 | # Initialize any camera 48 | ret = PxLApi.initialize(0) 49 | if not(PxLApi.apiSuccess(ret[0])): 50 | print("Error: Unable to initialize a camera! rc = %i" % ret[0]) 51 | return 1 52 | 53 | hCamera = ret[1] 54 | 55 | # Start the stream 56 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 57 | 58 | if PxLApi.apiSuccess(ret[0]): 59 | for i in range(15): 60 | ret = get_next_frame(hCamera, frame, 5) 61 | print("\ngetNextFrame returned %i" % ret[0]) 62 | if PxLApi.apiSuccess(ret[0]): 63 | frameDescriptor = ret[1] 64 | if firstFrame: 65 | firstFrameTime = frameDescriptor.fFrameTime 66 | firstFrame = False 67 | print("\tframe number %i, frame time %3.3f" % (frameDescriptor.uFrameNumber, frameDescriptor.fFrameTime - firstFrameTime)) 68 | else: 69 | if PxLApi.ReturnCode.ApiBufferTooSmall == ret[0]: 70 | print("This program can only capture frames of %i bytes, or smaller. Reduce the camera's ROI" % MAX_IMAGE_SIZE) 71 | time.sleep(0.5) # 500 ms 72 | else: 73 | print("setStreamState with StreamState.START failed, rc = %i" % ret[0]) 74 | 75 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 76 | assert PxLApi.apiSuccess(ret[0]), "setStreamState with StreamState.STOP failed" 77 | 78 | PxLApi.uninitialize(hCamera) 79 | assert PxLApi.apiSuccess(ret[0]), "uninitialize failed" 80 | 81 | return 0 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /samples/Windows/getNextFrame.py: -------------------------------------------------------------------------------- 1 | """ 2 | getNextFrame.py 3 | 4 | A demonstration of a robust wrapper around PxLApi.getNextFrame. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import time 10 | 11 | # Just going to declare a very large buffer here. One that's large enough for any Pixelink camera 12 | MAX_IMAGE_SIZE = 5000*5000*2 13 | 14 | """ 15 | A robust wrapper around PxLApi.getNextFrame. 16 | This will handle the occasional error that can be returned by the API because of timeouts. 17 | 18 | Note that this should only be called when grabbing images from a camera NOT currently configured for triggering. 19 | """ 20 | def get_next_frame(hCamera, frame, maxNumberOfTries): 21 | 22 | ret = (PxLApi.ReturnCode.ApiUnknownError,) 23 | 24 | for i in range(maxNumberOfTries): 25 | ret = PxLApi.getNextFrame(hCamera, frame) 26 | if PxLApi.apiSuccess(ret[0]): 27 | return ret 28 | else: 29 | # If the streaming is turned off, or worse yet -- is gone? 30 | # If so, no sense in continuing. 31 | if PxLApi.ReturnCode.ApiStreamStopped == ret[0] or \ 32 | PxLApi.ReturnCode.ApiNoCameraAvailableError == ret[0]: 33 | return ret 34 | else: 35 | print(" Hmmm... getNextFrame returned %i" % ret[0]) 36 | 37 | # Ran out of tries, so return whatever the last error was. 38 | return ret 39 | 40 | 41 | def main(): 42 | 43 | firstFrame = True 44 | firstFrameTime = 0.0 45 | frame = create_string_buffer(MAX_IMAGE_SIZE) # Just going to declare a very large buffer here. 46 | 47 | # Initialize any camera 48 | ret = PxLApi.initialize(0) 49 | if not(PxLApi.apiSuccess(ret[0])): 50 | print("Error: Unable to initialize a camera! rc = %i" % ret[0]) 51 | return 1 52 | 53 | hCamera = ret[1] 54 | 55 | # Start the stream 56 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 57 | 58 | if PxLApi.apiSuccess(ret[0]): 59 | for i in range(15): 60 | ret = get_next_frame(hCamera, frame, 5) 61 | print("\ngetNextFrame returned %i" % ret[0]) 62 | if PxLApi.apiSuccess(ret[0]): 63 | frameDescriptor = ret[1] 64 | if firstFrame: 65 | firstFrameTime = frameDescriptor.fFrameTime 66 | firstFrame = False 67 | print("\tframe number %i, frame time %3.3f" % (frameDescriptor.uFrameNumber, frameDescriptor.fFrameTime - firstFrameTime)) 68 | else: 69 | if PxLApi.ReturnCode.ApiBufferTooSmall == ret[0]: 70 | print("This program can only capture frames of %i bytes, or smaller. Reduce the camera's ROI" % MAX_IMAGE_SIZE) 71 | time.sleep(0.5) # 500 ms 72 | else: 73 | print("setStreamState with StreamState.START failed, rc = %i" % ret[0]) 74 | 75 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 76 | assert PxLApi.apiSuccess(ret[0]), "setStreamState with StreamState.STOP failed" 77 | 78 | PxLApi.uninitialize(hCamera) 79 | assert PxLApi.apiSuccess(ret[0]), "uninitialize failed" 80 | 81 | return 0 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /samples/Windows/measureGetNextFrameRate.py: -------------------------------------------------------------------------------- 1 | """ 2 | measureGetNextFrameRate.py 3 | 4 | Sample code to show a very simple frame grab. See the sample application 5 | 'getNextFrame' for a more robust frame grab example. 6 | 7 | This program simply calculates the frame rate of the camera (via frame grabs). 8 | """ 9 | 10 | from pixelinkWrapper import* 11 | from ctypes import* 12 | import sys 13 | import time 14 | import msvcrt 15 | 16 | 17 | def no_camera(rc): 18 | 19 | if rc == PxLApi.ReturnCode.ApiNoCameraError or rc == PxLApi.ReturnCode.ApiNoCameraAvailableError: 20 | return True 21 | 22 | return False 23 | 24 | 25 | def main(): 26 | 27 | getNextFramesPerItteration = 1 28 | 29 | # Just going to declare a very large buffer here 30 | # One that's large enough for any PixeLINK 4.0 camera 31 | frame = create_string_buffer(5000 * 5000 * 2) 32 | 33 | sys.stdin.flush() 34 | 35 | ret = PxLApi.initialize(0) 36 | if not(PxLApi.apiSuccess(ret[0])): 37 | print("Could not initialize the camera! rc = %i" % ret[0]) 38 | return 1 39 | 40 | hCamera = ret[1] 41 | 42 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 43 | if not(PxLApi.apiSuccess(ret[0])): 44 | print("Could not stream the camera! rc = %i" % ret[0]) 45 | PxLApi.uninitialize(hCamera) 46 | return 1 47 | 48 | print("Counting the number of images over a 20 second period...") 49 | 50 | frameCount = badFrameCount = 0 51 | startTime = currentTime = time.time() * 1000.0 # in milliseconds 52 | 53 | while 1: 54 | 55 | for i in range(getNextFramesPerItteration): 56 | ret = PxLApi.getNextFrame(hCamera, frame) 57 | if PxLApi.apiSuccess(ret[0]): 58 | frameCount += 1 59 | else: 60 | badFrameCount += 1 61 | if no_camera(ret[0]): 62 | print("Camera is Gone!! -- Aborting") 63 | return 1 # No point is continuing 64 | break # Do a time check to see if we are done. 65 | 66 | currentTime = time.time() * 1000.0 67 | 68 | if currentTime >= (startTime + 20000): 69 | break 70 | if currentTime <= (startTime + 200): 71 | getNextFramesPerItteration = getNextFramesPerItteration << 1 72 | 73 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 74 | 75 | print(" Received %i frames (%i bad), or %8.2f frames/second. %i getNextFrames/timecheck" % 76 | (frameCount+badFrameCount, badFrameCount, (frameCount+badFrameCount)/((currentTime - startTime) / 1000.0), 77 | getNextFramesPerItteration)) 78 | 79 | print("Press any key to exit") 80 | kbHit() 81 | 82 | PxLApi.uninitialize(hCamera) 83 | 84 | return 0 85 | 86 | """ 87 | Unbuffered keyboard input on command line. 88 | Keyboard input will be passed to the application without the user pressing 89 | the enter key. 90 | Note: IDLE does not support this functionality. 91 | """ 92 | def kbHit(): 93 | keyPressed = msvcrt.getch() 94 | if b'\xe0' == keyPressed: 95 | return str(keyPressed) 96 | return str(keyPressed, "utf-8") 97 | 98 | 99 | if __name__ == "__main__": 100 | main() 101 | -------------------------------------------------------------------------------- /samples/Linux/getNextNumPyFrame.py: -------------------------------------------------------------------------------- 1 | """ 2 | getNextFrame.py 3 | 4 | A demonstration of a robust wrapper around PxLApi.getNextFrame. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import time 10 | import numpy as np 11 | 12 | # Just to define our image buffer; One that's large enough for the Pixelink camera being used 13 | MAX_WIDTH = 5000 # in pixels 14 | MAX_HEIGHT = 5000 # in pixels 15 | MAX_BYTES_PER_PIXEL = 3 16 | 17 | """ 18 | A robust wrapper around PxLApi.getNextFrame. 19 | This will handle the occasional error that can be returned by the API because of timeouts. 20 | 21 | Note that this should only be called when grabbing images from a camera NOT currently configured for triggering. 22 | """ 23 | def get_next_frame(hCamera, frame, maxNumberOfTries): 24 | 25 | ret = (PxLApi.ReturnCode.ApiUnknownError,) 26 | 27 | for i in range(maxNumberOfTries): 28 | ret = PxLApi.getNextNumPyFrame(hCamera, frame) 29 | if PxLApi.apiSuccess(ret[0]): 30 | return ret 31 | else: 32 | # If the streaming is turned off, or worse yet -- is gone? 33 | # If so, no sense in continuing. 34 | if PxLApi.ReturnCode.ApiStreamStopped == ret[0] or \ 35 | PxLApi.ReturnCode.ApiNoCameraAvailableError == ret[0]: 36 | return ret 37 | else: 38 | print(" Hmmm... getNextFrame returned %i" % ret[0]) 39 | 40 | # Ran out of tries, so return whatever the last error was. 41 | return ret 42 | 43 | 44 | def main(): 45 | 46 | firstFrame = True 47 | firstFrameTime = 0.0 48 | 49 | # Just going to declare a very large (NumPy 2D array)buffer here. 50 | frame = np.zeros([MAX_HEIGHT,MAX_WIDTH*MAX_BYTES_PER_PIXEL], dtype=np.uint8) 51 | 52 | # Initialize any camera 53 | ret = PxLApi.initialize(0) 54 | if not(PxLApi.apiSuccess(ret[0])): 55 | print("Error: Unable to initialize a camera! rc = %i" % ret[0]) 56 | return 1 57 | 58 | hCamera = ret[1] 59 | 60 | # Start the stream 61 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 62 | 63 | if PxLApi.apiSuccess(ret[0]): 64 | for i in range(15): 65 | ret = get_next_frame(hCamera, frame, 5) 66 | print("\ngetNextFrame returned %i" % ret[0]) 67 | if PxLApi.apiSuccess(ret[0]): 68 | frameDescriptor = ret[1] 69 | if firstFrame: 70 | firstFrameTime = frameDescriptor.fFrameTime 71 | firstFrame = False 72 | print("\tframe number %i, frame time %3.3f" % (frameDescriptor.uFrameNumber, frameDescriptor.fFrameTime - firstFrameTime)) 73 | else: 74 | if PxLApi.ReturnCode.ApiBufferTooSmall == ret[0]: 75 | print("This program can only capture frames of %i bytes, or smaller. Reduce the camera's ROI" % frame.size) 76 | time.sleep(0.5) # 500 ms 77 | else: 78 | print("setStreamState with StreamState.START failed, rc = %i" % ret[0]) 79 | 80 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 81 | assert PxLApi.apiSuccess(ret[0]), "setStreamState with StreamState.STOP failed" 82 | 83 | PxLApi.uninitialize(hCamera) 84 | assert PxLApi.apiSuccess(ret[0]), "uninitialize failed" 85 | 86 | return 0 87 | 88 | 89 | if __name__ == "__main__": 90 | main() 91 | -------------------------------------------------------------------------------- /samples/Windows/getNextNumPyFrame.py: -------------------------------------------------------------------------------- 1 | """ 2 | getNextFrame.py 3 | 4 | A demonstration of a robust wrapper around PxLApi.getNextFrame. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import time 10 | import numpy as np 11 | 12 | # Just to define our image buffer; One that's large enough for the Pixelink camera being used 13 | MAX_WIDTH = 5000 # in pixels 14 | MAX_HEIGHT = 5000 # in pixels 15 | MAX_BYTES_PER_PIXEL = 3 16 | 17 | """ 18 | A robust wrapper around PxLApi.getNextFrame. 19 | This will handle the occasional error that can be returned by the API because of timeouts. 20 | 21 | Note that this should only be called when grabbing images from a camera NOT currently configured for triggering. 22 | """ 23 | def get_next_frame(hCamera, frame, maxNumberOfTries): 24 | 25 | ret = (PxLApi.ReturnCode.ApiUnknownError,) 26 | 27 | for i in range(maxNumberOfTries): 28 | ret = PxLApi.getNextNumPyFrame(hCamera, frame) 29 | if PxLApi.apiSuccess(ret[0]): 30 | return ret 31 | else: 32 | # If the streaming is turned off, or worse yet -- is gone? 33 | # If so, no sense in continuing. 34 | if PxLApi.ReturnCode.ApiStreamStopped == ret[0] or \ 35 | PxLApi.ReturnCode.ApiNoCameraAvailableError == ret[0]: 36 | return ret 37 | else: 38 | print(" Hmmm... getNextFrame returned %i" % ret[0]) 39 | 40 | # Ran out of tries, so return whatever the last error was. 41 | return ret 42 | 43 | 44 | def main(): 45 | 46 | firstFrame = True 47 | firstFrameTime = 0.0 48 | 49 | # Just going to declare a very large (NumPy 2D array)buffer here. 50 | frame = np.zeros([MAX_HEIGHT,MAX_WIDTH*MAX_BYTES_PER_PIXEL], dtype=np.uint8) 51 | 52 | # Initialize any camera 53 | ret = PxLApi.initialize(0) 54 | if not(PxLApi.apiSuccess(ret[0])): 55 | print("Error: Unable to initialize a camera! rc = %i" % ret[0]) 56 | return 1 57 | 58 | hCamera = ret[1] 59 | 60 | # Start the stream 61 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 62 | 63 | if PxLApi.apiSuccess(ret[0]): 64 | for i in range(15): 65 | ret = get_next_frame(hCamera, frame, 5) 66 | print("\ngetNextFrame returned %i" % ret[0]) 67 | if PxLApi.apiSuccess(ret[0]): 68 | frameDescriptor = ret[1] 69 | if firstFrame: 70 | firstFrameTime = frameDescriptor.fFrameTime 71 | firstFrame = False 72 | print("\tframe number %i, frame time %3.3f" % (frameDescriptor.uFrameNumber, frameDescriptor.fFrameTime - firstFrameTime)) 73 | else: 74 | if PxLApi.ReturnCode.ApiBufferTooSmall == ret[0]: 75 | print("This program can only capture frames of %i bytes, or smaller. Reduce the camera's ROI" % frame.size) 76 | time.sleep(0.5) # 500 ms 77 | else: 78 | print("setStreamState with StreamState.START failed, rc = %i" % ret[0]) 79 | 80 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 81 | assert PxLApi.apiSuccess(ret[0]), "setStreamState with StreamState.STOP failed" 82 | 83 | PxLApi.uninitialize(hCamera) 84 | assert PxLApi.apiSuccess(ret[0]), "uninitialize failed" 85 | 86 | return 0 87 | 88 | 89 | if __name__ == "__main__": 90 | main() 91 | -------------------------------------------------------------------------------- /samples/Linux/ptpV2.py: -------------------------------------------------------------------------------- 1 | """ 2 | ptpV2.py 3 | 4 | Demonstration of a trivial interaction with the Pixelink API 5 | 6 | More specifically, this demo will demonstarte how to use IEEE 1588 (PTPv2) 7 | on a Pixelink camera. This demo program has minimal error handling, as its 8 | purpose is to show minimal code to interact with the Pixelink API, not tell 9 | you how to do your error handling. 10 | 11 | With this program, we assume that there is at least one camera connected, 12 | and that no cameras are connected or disconnected while the program is 13 | running. 14 | """ 15 | 16 | from pixelinkWrapper import* 17 | import time 18 | 19 | EXIT_SUCCESS = 0 20 | EXIT_FAILURE = 1 21 | 22 | 23 | def transitory_ptp_state(state): 24 | 25 | # Returns True if the PTP state machine is in a transitory (non-stable) state 26 | switcher = { 27 | PxLApi.PtpStatus.INITIALIZING: True, 28 | PxLApi.PtpStatus.FAULTY: False, 29 | PxLApi.PtpStatus.DISABLED: False, 30 | PxLApi.PtpStatus.LISTENING: True, 31 | PxLApi.PtpStatus.PREMASTER: True, 32 | PxLApi.PtpStatus.MASTER: False, 33 | PxLApi.PtpStatus.PASSIVE: False, 34 | PxLApi.PtpStatus.UNCALIBRATED: True, 35 | PxLApi.PtpStatus.SLAVE: False, 36 | } 37 | return switcher.get(state, False) 38 | 39 | 40 | def main(): 41 | 42 | # Initialize any camera 43 | ret = PxLApi.initialize(0) 44 | if not PxLApi.apiSuccess(ret[0]): 45 | print("Error: Unable to initialize a camera: rc=%d" % ret[0]) 46 | return EXIT_FAILURE 47 | 48 | hCamera = ret[1] 49 | 50 | # do a get on the feature, mostly to make sure the camera supports it. 51 | ptpParams = [0] * PxLApi.PtpParams.NUM_PARAMS 52 | 53 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PTP, ptpParams) 54 | if not PxLApi.apiSuccess(ret[0]): 55 | print("Error: Unable to get FEATURE_PTP for the camera: rc=%d" % ret[0]) 56 | PxLApi.uninitialize(hCamera) 57 | return EXIT_FAILURE 58 | 59 | print("Enabling PTP Auto mode, and waiting for clock synchronization...") 60 | 61 | ptpParams[PxLApi.PtpParams.MODE] = PxLApi.PtpModes.AUTOMATIC 62 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.PTP, PxLApi.FeatureFlags.AUTO, ptpParams) 63 | if not PxLApi.apiSuccess(ret[0]): 64 | print("Error: Unable to set FEATURE_PTP for the camera: rc=%d" % ret[0]) 65 | PxLApi.uninitialize(hCamera) 66 | return EXIT_FAILURE 67 | 68 | while(True): 69 | 70 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PTP) 71 | if not PxLApi.apiSuccess(ret[0]): 72 | print("Error: Unable to get FEATURE_PTP for the camera: rc=%d" % ret[0]) 73 | PxLApi.uninitialize(hCamera) 74 | return EXIT_FAILURE 75 | 76 | ptpParams = ret[2] 77 | print(" \r Current PTP state:%d" % ptpParams[PxLApi.PtpParams.STATUS], end="") 78 | if not transitory_ptp_state(ptpParams[PxLApi.PtpParams.STATUS]): 79 | break 80 | 81 | time.sleep(0.250) # Take a breather 82 | 83 | print("\n PTP Info:") 84 | print(" Mode: %d" % ptpParams[0]) 85 | print(" Status: %d" % ptpParams[1]) 86 | print(" My Clock Accuracy: %.9f" % ptpParams[2]) 87 | print(" Offset From Master: %.9f" % ptpParams[3]) 88 | 89 | PxLApi.uninitialize(hCamera) 90 | return EXIT_SUCCESS 91 | 92 | if __name__ == "__main__": 93 | main() 94 | -------------------------------------------------------------------------------- /samples/Windows/ptpV2.py: -------------------------------------------------------------------------------- 1 | """ 2 | ptpV2.py 3 | 4 | Demonstration of a trivial interaction with the Pixelink API 5 | 6 | More specifically, this demo will demonstarte how to use IEEE 1588 (PTPv2) 7 | on a Pixelink camera. This demo program has minimal error handling, as its 8 | purpose is to show minimal code to interact with the Pixelink API, not tell 9 | you how to do your error handling. 10 | 11 | With this program, we assume that there is at least one camera connected, 12 | and that no cameras are connected or disconnected while the program is 13 | running. 14 | """ 15 | 16 | from pixelinkWrapper import* 17 | import time 18 | 19 | EXIT_SUCCESS = 0 20 | EXIT_FAILURE = 1 21 | 22 | 23 | def transitory_ptp_state(state): 24 | 25 | # Returns True if the PTP state machine is in a transitory (non-stable) state 26 | switcher = { 27 | PxLApi.PtpStatus.INITIALIZING: True, 28 | PxLApi.PtpStatus.FAULTY: False, 29 | PxLApi.PtpStatus.DISABLED: False, 30 | PxLApi.PtpStatus.LISTENING: True, 31 | PxLApi.PtpStatus.PREMASTER: True, 32 | PxLApi.PtpStatus.MASTER: False, 33 | PxLApi.PtpStatus.PASSIVE: False, 34 | PxLApi.PtpStatus.UNCALIBRATED: True, 35 | PxLApi.PtpStatus.SLAVE: False, 36 | } 37 | return switcher.get(state, False) 38 | 39 | 40 | def main(): 41 | 42 | # Initialize any camera 43 | ret = PxLApi.initialize(0) 44 | if not PxLApi.apiSuccess(ret[0]): 45 | print("Error: Unable to initialize a camera: rc=%d" % ret[0]) 46 | return EXIT_FAILURE 47 | 48 | hCamera = ret[1] 49 | 50 | # do a get on the feature, mostly to make sure the camera supports it. 51 | ptpParams = [0] * PxLApi.PtpParams.NUM_PARAMS 52 | 53 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PTP, ptpParams) 54 | if not PxLApi.apiSuccess(ret[0]): 55 | print("Error: Unable to get FEATURE_PTP for the camera: rc=%d" % ret[0]) 56 | PxLApi.uninitialize(hCamera) 57 | return EXIT_FAILURE 58 | 59 | print("Enabling PTP Auto mode, and waiting for clock synchronization...") 60 | 61 | ptpParams[PxLApi.PtpParams.MODE] = PxLApi.PtpModes.AUTOMATIC 62 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.PTP, PxLApi.FeatureFlags.AUTO, ptpParams) 63 | if not PxLApi.apiSuccess(ret[0]): 64 | print("Error: Unable to set FEATURE_PTP for the camera: rc=%d" % ret[0]) 65 | PxLApi.uninitialize(hCamera) 66 | return EXIT_FAILURE 67 | 68 | while(True): 69 | 70 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PTP) 71 | if not PxLApi.apiSuccess(ret[0]): 72 | print("Error: Unable to get FEATURE_PTP for the camera: rc=%d" % ret[0]) 73 | PxLApi.uninitialize(hCamera) 74 | return EXIT_FAILURE 75 | 76 | ptpParams = ret[2] 77 | print(" \r Current PTP state:%d" % ptpParams[PxLApi.PtpParams.STATUS], end="") 78 | if not transitory_ptp_state(ptpParams[PxLApi.PtpParams.STATUS]): 79 | break 80 | 81 | time.sleep(0.250) # Take a breather 82 | 83 | print("\n PTP Info:") 84 | print(" Mode: %d" % ptpParams[0]) 85 | print(" Status: %d" % ptpParams[1]) 86 | print(" My Clock Accuracy: %.9f" % ptpParams[2]) 87 | print(" Offset From Master: %.9f" % ptpParams[3]) 88 | 89 | PxLApi.uninitialize(hCamera) 90 | return EXIT_SUCCESS 91 | 92 | if __name__ == "__main__": 93 | main() 94 | -------------------------------------------------------------------------------- /samples/Linux/eventCallback.py: -------------------------------------------------------------------------------- 1 | """ 2 | eventCallback.py 3 | 4 | Demonstrates how to use event callbacks 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | import time 9 | import sys 10 | import tty 11 | import termios 12 | 13 | STALL_TIME = 20 # 20 seconds 14 | EXIT_SUCCESS = 0 15 | EXIT_FAILURE = 1 16 | 17 | """ 18 | Callback function called by the API with each event (of interest) reported by the camera. 19 | N.B. This is called by the API on a thread created in the API. 20 | """ 21 | @PxLApi._eventProcessFunction 22 | def event_callback_func( 23 | hCamera, \ 24 | eventId, \ 25 | eventTimestamp, \ 26 | numDataBytes, \ 27 | data, \ 28 | userData): 29 | 30 | # Copy event specific data, if it is provided 31 | eventData = data.contents if bool(data) == True else 0 32 | 33 | print("EventCallbackFunction: hCamera=%s, eventId=%d" % (hex(hCamera), eventId)) 34 | print(" eventTimestamp=%f, numDataBytes=%d" % (eventTimestamp, numDataBytes)) 35 | print(" eventData=%s, userData=%d (%s)\n" % (hex(eventData), userData, hex(userData))) 36 | return PxLApi.ReturnCode.ApiSuccess 37 | 38 | 39 | def main(): 40 | 41 | print("This sample application will use the GPI line to demostrate events, OK to proceed Y/N?") 42 | setUnbufKb(True) # Enable unbuffered non-blocking keyboard input 43 | userChar = kbHit() 44 | setUnbufKb(False) # We are done with it, so disable it 45 | if 'y' != userChar and 'Y' != userChar: 46 | return EXIT_SUCCESS 47 | 48 | ret = PxLApi.initialize(0) 49 | if not PxLApi.apiSuccess(ret[0]): 50 | print("ERROR on PxLApi.initialize: %d" % ret[0]) 51 | return EXIT_FAILURE 52 | 53 | hCamera = ret[1] 54 | 55 | print("\nMain thread, stalling for %d seconds awaiting events. Toggle the GPI line...\n" % STALL_TIME) 56 | 57 | userData = 1526647550 # hex(0x5AFECAFE) 58 | # Note: We can specify a specific event, or all of them 59 | ret = PxLApi.setEventCallback( 60 | hCamera, \ 61 | PxLApi.EventId.ANY, \ 62 | userData, \ 63 | event_callback_func) 64 | 65 | if not PxLApi.apiSuccess(ret[0]): 66 | retErr = PxLApi.getErrorReport(hCamera) 67 | err = retErr[1] 68 | print("ERROR setting event callback function: %d (%s)" % (ret[0], str(err.strReturnCode, encoding='utf-8'))) 69 | PxLApi.uninitialize(hCamera) 70 | return EXIT_FAILURE 71 | 72 | time.sleep(STALL_TIME) 73 | 74 | PxLApi.setEventCallback(hCamera, PxLApi.EventId.ANY, userData, 0) # Cancel the callback 75 | PxLApi.uninitialize(hCamera) 76 | return EXIT_SUCCESS 77 | 78 | 79 | """ 80 | Unbuffered non-blocking keyboard input on command line. 81 | Keyboard input will be passed to the application without the user pressing 82 | the enter key. 83 | Note: IDLE does not support this functionality. 84 | """ 85 | # A couple of useful global variables 86 | fd = sys.stdin.fileno() 87 | original_term_settings = termios.tcgetattr(fd) 88 | 89 | # Enable/disable unbuffered keyboard input 90 | def setUnbufKb(enable): 91 | if enable: 92 | tty.setraw(sys.stdin.fileno()) 93 | else: 94 | termios.tcsetattr(fd, termios.TCSADRAIN, original_term_settings) 95 | 96 | # Read unbuffered hit button 97 | def kbHit(): 98 | return sys.stdin.read(1) 99 | 100 | 101 | if __name__ == "__main__": 102 | main() 103 | -------------------------------------------------------------------------------- /samples/Linux/getCameraInfo.py: -------------------------------------------------------------------------------- 1 | """ 2 | getCameraInfo.py 3 | 4 | Demonstration of a trivial interaction with the Pixelink API. 5 | 6 | This demo program has minimal error handling, as its purpose is to show minimal code to interact with the Pixelink API, 7 | not tell you how to do your error handling. 8 | 9 | With this program, we assume that there is at least one camera connected, and that no cameras are connected or disconnected 10 | while the program is running. 11 | """ 12 | 13 | from pixelinkWrapper import* 14 | 15 | """ 16 | This function assumes there's only one camera connected. 17 | """ 18 | def print_info_for_one_camera(): 19 | 20 | # Initialize a camera 21 | ret = PxLApi.initialize(0) 22 | if PxLApi.apiSuccess(ret[0]): 23 | hCamera = ret[1] 24 | ret = PxLApi.getCameraInfo(hCamera) 25 | if PxLApi.apiSuccess(ret[0]): 26 | cameraInfo = ret[1] 27 | print_camera_info(cameraInfo) 28 | # Uninitialize a camera 29 | PxLApi.uninitialize(hCamera) 30 | 31 | """ 32 | This will print information for all cameras connected and connectable. 33 | """ 34 | def print_info_for_all_cameras(): 35 | 36 | # First: Determine how many cameras are connected and available for connecting 37 | ret = PxLApi.getNumberCameras() 38 | if PxLApi.apiSuccess(ret[0]): 39 | cameraIdInfo = ret[1] 40 | numCameras = len(cameraIdInfo) 41 | if 0 < numCameras: 42 | # One-by-one, get the camera info for each camera 43 | for i in range(numCameras): 44 | serialNumber = cameraIdInfo[i].CameraSerialNum 45 | # Connect to the camera 46 | ret = PxLApi.initialize(serialNumber) 47 | if PxLApi.apiSuccess(ret[0]): 48 | hCamera = ret[1] 49 | # And get the info 50 | ret = PxLApi.getCameraInfo(hCamera) 51 | if PxLApi.apiSuccess(ret[0]): 52 | cameraInfo = ret[1] 53 | print("\nCamera %i of %i (serialNumber %i):" % (i+1, numCameras, serialNumber)) 54 | print_camera_info(cameraInfo) 55 | 56 | # Don't forget to tell the camera we're done, so that we don't use any camera-related resources. 57 | PxLApi.uninitialize(hCamera) 58 | 59 | """ 60 | Print all the info for the camera 61 | """ 62 | def print_camera_info(cameraInfo): 63 | 64 | print("Name -------------- '%s'" % cameraInfo.CameraName.decode("utf-8")) 65 | print("Description ------- '%s'" % cameraInfo.Description.decode("utf-8")) 66 | print("Vendor Name ------- '%s'" % cameraInfo.VendorName.decode("utf-8")) 67 | print("Serial Number ----- '%s'" % cameraInfo.SerialNumber.decode("utf-8")) 68 | print("Firmware Version -- '%s'" % cameraInfo.FirmwareVersion.decode("utf-8")) 69 | print("FPGA Version ------ '%s'" % cameraInfo.FPGAVersion.decode("utf-8")) 70 | print("XML Version ------- '%s'" % cameraInfo.XMLVersion.decode("utf-8")) 71 | print("Bootload Version -- '%s'" % cameraInfo.BootloadVersion.decode("utf-8")) 72 | print("Model Name -------- '%s'" % cameraInfo.ModelName.decode("utf-8")) 73 | print("Lens Description -- '%s'" % cameraInfo.LensDescription.decode("utf-8")) 74 | 75 | 76 | def main(): 77 | 78 | # We assume there's only one camera 79 | print_info_for_one_camera() 80 | 81 | # You can uncomment this to see how to get information for all cameras 82 | # print_info_for_all_cameras() 83 | 84 | return 0 85 | 86 | 87 | if __name__ == "__main__": 88 | main() 89 | -------------------------------------------------------------------------------- /samples/Windows/getCameraInfo.py: -------------------------------------------------------------------------------- 1 | """ 2 | getCameraInfo.py 3 | 4 | Demonstration of a trivial interaction with the Pixelink API. 5 | 6 | This demo program has minimal error handling, as its purpose is to show minimal code to interact with the Pixelink API, 7 | not tell you how to do your error handling. 8 | 9 | With this program, we assume that there is at least one camera connected, and that no cameras are connected or disconnected 10 | while the program is running. 11 | """ 12 | 13 | from pixelinkWrapper import* 14 | 15 | """ 16 | This function assumes there's only one camera connected. 17 | """ 18 | def print_info_for_one_camera(): 19 | 20 | # Initialize a camera 21 | ret = PxLApi.initialize(0) 22 | if PxLApi.apiSuccess(ret[0]): 23 | hCamera = ret[1] 24 | ret = PxLApi.getCameraInfo(hCamera) 25 | if PxLApi.apiSuccess(ret[0]): 26 | cameraInfo = ret[1] 27 | print_camera_info(cameraInfo) 28 | # Uninitialize a camera 29 | PxLApi.uninitialize(hCamera) 30 | 31 | """ 32 | This will print information for all cameras connected and connectable. 33 | """ 34 | def print_info_for_all_cameras(): 35 | 36 | # First: Determine how many cameras are connected and available for connecting 37 | ret = PxLApi.getNumberCameras() 38 | if PxLApi.apiSuccess(ret[0]): 39 | cameraIdInfo = ret[1] 40 | numCameras = len(cameraIdInfo) 41 | if 0 < numCameras: 42 | # One-by-one, get the camera info for each camera 43 | for i in range(numCameras): 44 | serialNumber = cameraIdInfo[i].CameraSerialNum 45 | # Connect to the camera 46 | ret = PxLApi.initialize(serialNumber) 47 | if PxLApi.apiSuccess(ret[0]): 48 | hCamera = ret[1] 49 | # And get the info 50 | ret = PxLApi.getCameraInfo(hCamera) 51 | if PxLApi.apiSuccess(ret[0]): 52 | cameraInfo = ret[1] 53 | print("\nCamera %i of %i (serialNumber %i):" % (i+1, numCameras, serialNumber)) 54 | print_camera_info(cameraInfo) 55 | 56 | # Don't forget to tell the camera we're done, so that we don't use any camera-related resources. 57 | PxLApi.uninitialize(hCamera) 58 | 59 | """ 60 | Print all the info for the camera 61 | """ 62 | def print_camera_info(cameraInfo): 63 | 64 | print("Name -------------- '%s'" % cameraInfo.CameraName.decode("utf-8")) 65 | print("Description ------- '%s'" % cameraInfo.Description.decode("utf-8")) 66 | print("Vendor Name ------- '%s'" % cameraInfo.VendorName.decode("utf-8")) 67 | print("Serial Number ----- '%s'" % cameraInfo.SerialNumber.decode("utf-8")) 68 | print("Firmware Version -- '%s'" % cameraInfo.FirmwareVersion.decode("utf-8")) 69 | print("FPGA Version ------ '%s'" % cameraInfo.FPGAVersion.decode("utf-8")) 70 | print("XML Version ------- '%s'" % cameraInfo.XMLVersion.decode("utf-8")) 71 | print("Bootload Version -- '%s'" % cameraInfo.BootloadVersion.decode("utf-8")) 72 | print("Model Name -------- '%s'" % cameraInfo.ModelName.decode("utf-8")) 73 | print("Lens Description -- '%s'" % cameraInfo.LensDescription.decode("utf-8")) 74 | 75 | 76 | def main(): 77 | 78 | # We assume there's only one camera 79 | print_info_for_one_camera() 80 | 81 | # You can uncomment this to see how to get information for all cameras 82 | # print_info_for_all_cameras() 83 | 84 | return 0 85 | 86 | 87 | if __name__ == "__main__": 88 | main() 89 | -------------------------------------------------------------------------------- /samples/Linux/gigeHeartbeat.py: -------------------------------------------------------------------------------- 1 | """ 2 | gigeHeartbeat.py 3 | 4 | As required by the GigE Vision specification, Pixelink GigE cameras use a 'heartbeat' 5 | between the camera and the host to determine the 'liveness' of the connection. If 6 | no communication (normal camera interaction, or heartbeat) occurs within a certain 7 | amount of time, the camera deems the connection as broken, and any further interaction 8 | (except for connections) is refused. 9 | 10 | This poses a problem when debugging because the debugger (e.g. Visual Studio, WinDbg) 11 | will suspend all the threads in a debugee process (i.e. your program which is trying 12 | to interact with the camera) for various reasons (e.g. breakpoints, exceptions, ...), 13 | thereby disabling the background heartbeat mechanism, and thereby causing a connection 14 | to a GigE camera to be terminated by the camera. 15 | 16 | Simply put: debugging a program talking to a Pixelink GigE camera will have problems 17 | after hitting a breakpoint or single-stepping. 18 | 19 | The only way to improve this situation is to increase the heartbeat timeout. The 20 | current default is 500ms, but this can currently be increased to as much as 65.535 21 | seconds. A gigeHeartbeat demo application, demonstrates how to use the Pixelink API to 22 | do this. 23 | 24 | All processes will start by using the default heartbeat timeout. If the heartbeat 25 | timeout value is changed programmatically, the heartbeat timeout value is valid only 26 | for the current process, and only for the life of the current process. 27 | 28 | The ability to change the heartbeat timeout is a double-edged sword. If you abruptly 29 | end your debugging session without giving the Pixelink API a chance to close the 30 | connection (i.e. PxLApi.uninitialize), the camera will not allow connections until 31 | the timeout from the last heartbeat passes. For example, if you set the heartbeat to 32 | 30 seconds, and then while debugging terminate debugging (e.g. in Visual Studio, 33 | using Debug\Stop Debugging), without having called PxLApi.uninitialize, it may take 34 | up to 30 seconds before the camera will accept new connections. 35 | """ 36 | 37 | from pixelinkWrapper import* 38 | import sys 39 | 40 | # Commands for PxLApi.privateCmd 41 | PRIVATE_COMMAND_SET_HEARTBEAT_TIMEOUT = 40 42 | 43 | """ 44 | Before connecting to a camera, set the GigE heartbeat timeout 45 | so that we can debug this process without killing the connection. 46 | 47 | We'll only do this for Debug runs. 48 | """ 49 | def initialize_camera(serialNumber): 50 | 51 | debugRun = sys.gettrace() 52 | if debugRun: 53 | 54 | # Before connecting to a GigE camera, set the GigE heartbeat timeout. 55 | # It is recommended that you do this just before calling PxLApi.initialize. 56 | 57 | data = [PRIVATE_COMMAND_SET_HEARTBEAT_TIMEOUT, 65535] # Set to max currently supported value (65535 ms = 65.535 seconds) 58 | 59 | ret = PxLApi.privateCmd(0, data) # camera handle doesn't matter 60 | if not PxLApi.apiSuccess(ret[0]): 61 | return ret 62 | 63 | # Can now connect in the usual way to the GigE camera. 64 | return PxLApi.initialize(serialNumber) 65 | 66 | 67 | def main(): 68 | 69 | ret = initialize_camera(0) 70 | if not PxLApi.apiSuccess(ret[0]): 71 | print("ERROR: Unable to initialize a camera (Return code = %d)" % ret[0]) 72 | return 1 73 | 74 | hCamera = ret[1] 75 | 76 | # Interact with your GigE camera as usual 77 | 78 | # And now uninitialize in the usual way. 79 | PxLApi.uninitialize(hCamera) 80 | hCamera = 0 81 | 82 | return 0 83 | 84 | 85 | if __name__ == "__main__": 86 | main() -------------------------------------------------------------------------------- /samples/Windows/gigeHeartbeat.py: -------------------------------------------------------------------------------- 1 | """ 2 | gigeHeartbeat.py 3 | 4 | As required by the GigE Vision specification, Pixelink GigE cameras use a 'heartbeat' 5 | between the camera and the host to determine the 'liveness' of the connection. If 6 | no communication (normal camera interaction, or heartbeat) occurs within a certain 7 | amount of time, the camera deems the connection as broken, and any further interaction 8 | (except for connections) is refused. 9 | 10 | This poses a problem when debugging because the debugger (e.g. Visual Studio, WinDbg) 11 | will suspend all the threads in a debugee process (i.e. your program which is trying 12 | to interact with the camera) for various reasons (e.g. breakpoints, exceptions, ...), 13 | thereby disabling the background heartbeat mechanism, and thereby causing a connection 14 | to a GigE camera to be terminated by the camera. 15 | 16 | Simply put: debugging a program talking to a Pixelink GigE camera will have problems 17 | after hitting a breakpoint or single-stepping. 18 | 19 | The only way to improve this situation is to increase the heartbeat timeout. The 20 | current default is 500ms, but this can currently be increased to as much as 65.535 21 | seconds. A gigeHeartbeat demo application, demonstrates how to use the Pixelink API to 22 | do this. 23 | 24 | All processes will start by using the default heartbeat timeout. If the heartbeat 25 | timeout value is changed programmatically, the heartbeat timeout value is valid only 26 | for the current process, and only for the life of the current process. 27 | 28 | The ability to change the heartbeat timeout is a double-edged sword. If you abruptly 29 | end your debugging session without giving the Pixelink API a chance to close the 30 | connection (i.e. PxLApi.uninitialize), the camera will not allow connections until 31 | the timeout from the last heartbeat passes. For example, if you set the heartbeat to 32 | 30 seconds, and then while debugging terminate debugging (e.g. in Visual Studio, 33 | using Debug\Stop Debugging), without having called PxLApi.uninitialize, it may take 34 | up to 30 seconds before the camera will accept new connections. 35 | """ 36 | 37 | from pixelinkWrapper import* 38 | import sys 39 | 40 | # Commands for PxLApi.privateCmd 41 | PRIVATE_COMMAND_SET_HEARTBEAT_TIMEOUT = 40 42 | 43 | """ 44 | Before connecting to a camera, set the GigE heartbeat timeout 45 | so that we can debug this process without killing the connection. 46 | 47 | We'll only do this for Debug runs. 48 | """ 49 | def initialize_camera(serialNumber): 50 | 51 | debugRun = sys.gettrace() 52 | if debugRun: 53 | 54 | # Before connecting to a GigE camera, set the GigE heartbeat timeout. 55 | # It is recommended that you do this just before calling PxLApi.initialize. 56 | 57 | data = [PRIVATE_COMMAND_SET_HEARTBEAT_TIMEOUT, 65535] # Set to max currently supported value (65535 ms = 65.535 seconds) 58 | 59 | ret = PxLApi.privateCmd(0, data) # camera handle doesn't matter 60 | if not PxLApi.apiSuccess(ret[0]): 61 | return ret 62 | 63 | # Can now connect in the usual way to the GigE camera. 64 | return PxLApi.initialize(serialNumber) 65 | 66 | 67 | def main(): 68 | 69 | ret = initialize_camera(0) 70 | if not PxLApi.apiSuccess(ret[0]): 71 | print("ERROR: Unable to initialize a camera (Return code = %d)" % ret[0]) 72 | return 1 73 | 74 | hCamera = ret[1] 75 | 76 | # Interact with your GigE camera as usual 77 | 78 | # And now uninitialize in the usual way. 79 | PxLApi.uninitialize(hCamera) 80 | hCamera = 0 81 | 82 | return 0 83 | 84 | 85 | if __name__ == "__main__": 86 | main() -------------------------------------------------------------------------------- /samples/Linux/getFeature.py: -------------------------------------------------------------------------------- 1 | """ 2 | getFeature.py 3 | 4 | Simple sample application demostrating the use of the getFeature function 5 | in the pixelinkWrapper. 6 | """ 7 | 8 | from pixelinkWrapper import* 9 | 10 | """ 11 | Demostrate the getFeature function of the pixelinkWrapper, by getting 12 | FeatureId.TRIGGER, as this is one of the more 'sophisticatted' features 13 | """ 14 | def main(): 15 | 16 | # 17 | # Step 1 18 | # Grab a Pixelink camera. Note that if there is more than one camera 19 | # connected, this will just grab the first one found. If we wanted 20 | # a specific camera, than we could use getNumberCameras/initialize 21 | # 22 | # Note also, we chose to use the optional InitializeExFlags.MONITOR_ACCESS_ONLY flag. 23 | # Pixelink GigE cameras can only have one application controlling the camera at any 24 | # time, so we use this falg to indicate that we don't intend to 'control' the camera, 25 | # we will just be reading camera settings 26 | ret = PxLApi.initialize(0, PxLApi.InitializeExFlags.MONITOR_ACCESS_ONLY) 27 | if not PxLApi.apiSuccess(ret[0]): 28 | print ("Could not find a camera!") 29 | return 30 | 31 | hCamera = ret[1] 32 | 33 | # 34 | # Step 2 35 | # Call getFeature. Like all pixelinkWrapper functions, getFeature 36 | # returns a tuple with number of elements. More specifically, 37 | # getFeature will return: 38 | # ret[0] - Return code 39 | # ret[1] - A bit mask of PxLApi.FeatureFlags 40 | # ret[2] - A list of paramters. The number of elements in the list varies 41 | # with the feature 42 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.TRIGGER) 43 | if PxLApi.apiSuccess(ret[0]): 44 | flags = ret[1] 45 | params = ret[2] 46 | 47 | # 48 | # Step 3 49 | # Interpret the resuts 50 | print("Camera Trigger:") 51 | if not flags & PxLApi.FeatureFlags.PRESENCE: 52 | print (" State: NOT SUPPORTED") 53 | else: 54 | state = 'DISABLED' if flags & PxLApi.FeatureFlags.OFF else \ 55 | 'CONTINUOUS' if flags & PxLApi.FeatureFlags.AUTO else \ 56 | 'ONE_TIME' if flags & PxLApi.FeatureFlags.ONEPUSH else \ 57 | 'MANUAL' 58 | type = 'HARDWARE' if params[1] == PxLApi.TriggerTypes.HARDWARE else \ 59 | 'SOFTWARE' if params[1] == PxLApi.TriggerTypes.SOFTWARE else \ 60 | 'ACTION' 61 | print (" State: %s" % state) 62 | print (" Type: %s" % type) 63 | if params[PxLApi.TriggerParams.MODE] == PxLApi.TriggerModes.MODE_0: 64 | print (" Description: Trigger a single frame, using current exposure") 65 | elif params[PxLApi.TriggerParams.MODE] == PxLApi.TriggerModes.MODE_1: 66 | print (" Description: Trigger a single frame, trigger duration defines exposure") 67 | elif params[PxLApi.TriggerParams.MODE] == PxLApi.TriggerModes.MODE_14: 68 | numFrames = params[PxLApi.TriggerParams.NUMBER] 69 | if numFrames == 0: 70 | print (" Description: Trigger frames until a StreamStop is issued") 71 | else: 72 | print (" Description: Trigger %d frames, using current exposure" % numFrames) 73 | else: 74 | print (" Description: Trigger mode %d" % params[PxLApi.TriggerParams.MODE]) 75 | 76 | else: 77 | print ("getFeature return code: %d" % ret[0]) 78 | 79 | # 80 | # Step 4 81 | # Release the camera 82 | PxLApi.uninitialize(hCamera) 83 | 84 | 85 | if __name__ == "__main__": 86 | main() 87 | -------------------------------------------------------------------------------- /samples/Windows/getFeature.py: -------------------------------------------------------------------------------- 1 | """ 2 | getFeature.py 3 | 4 | Simple sample application demostrating the use of the getFeature function 5 | in the pixelinkWrapper. 6 | """ 7 | 8 | from pixelinkWrapper import* 9 | 10 | """ 11 | Demostrate the getFeature function of the pixelinkWrapper, by getting 12 | FeatureId.TRIGGER, as this is one of the more 'sophisticatted' features 13 | """ 14 | def main(): 15 | 16 | # 17 | # Step 1 18 | # Grab a Pixelink camera. Note that if there is more than one camera 19 | # connected, this will just grab the first one found. If we wanted 20 | # a specific camera, than we could use getNumberCameras/initialize 21 | # 22 | # Note also, we chose to use the optional InitializeExFlags.MONITOR_ACCESS_ONLY flag. 23 | # Pixelink GigE cameras can only have one application controlling the camera at any 24 | # time, so we use this falg to indicate that we don't intend to 'control' the camera, 25 | # we will just be reading camera settings 26 | ret = PxLApi.initialize(0, PxLApi.InitializeExFlags.MONITOR_ACCESS_ONLY) 27 | if not PxLApi.apiSuccess(ret[0]): 28 | print ("Could not find a camera!") 29 | return 30 | 31 | hCamera = ret[1] 32 | 33 | # 34 | # Step 2 35 | # Call getFeature. Like all pixelinkWrapper functions, getFeature 36 | # returns a tuple with number of elements. More specifically, 37 | # getFeature will return: 38 | # ret[0] - Return code 39 | # ret[1] - A bit mask of PxLApi.FeatureFlags 40 | # ret[2] - A list of paramters. The number of elements in the list varies 41 | # with the feature 42 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.TRIGGER) 43 | if PxLApi.apiSuccess(ret[0]): 44 | flags = ret[1] 45 | params = ret[2] 46 | 47 | # 48 | # Step 3 49 | # Interpret the resuts 50 | print("Camera Trigger:") 51 | if not flags & PxLApi.FeatureFlags.PRESENCE: 52 | print (" State: NOT SUPPORTED") 53 | else: 54 | state = 'DISABLED' if flags & PxLApi.FeatureFlags.OFF else \ 55 | 'CONTINUOUS' if flags & PxLApi.FeatureFlags.AUTO else \ 56 | 'ONE_TIME' if flags & PxLApi.FeatureFlags.ONEPUSH else \ 57 | 'MANUAL' 58 | type = 'HARDWARE' if params[1] == PxLApi.TriggerTypes.HARDWARE else \ 59 | 'SOFTWARE' if params[1] == PxLApi.TriggerTypes.SOFTWARE else \ 60 | 'ACTION' 61 | print (" State: %s" % state) 62 | print (" Type: %s" % type) 63 | if params[PxLApi.TriggerParams.MODE] == PxLApi.TriggerModes.MODE_0: 64 | print (" Description: Trigger a single frame, using current exposure") 65 | elif params[PxLApi.TriggerParams.MODE] == PxLApi.TriggerModes.MODE_1: 66 | print (" Description: Trigger a single frame, trigger duration defines exposure") 67 | elif params[PxLApi.TriggerParams.MODE] == PxLApi.TriggerModes.MODE_14: 68 | numFrames = params[PxLApi.TriggerParams.NUMBER] 69 | if numFrames == 0: 70 | print (" Description: Trigger frames until a StreamStop is issued") 71 | else: 72 | print (" Description: Trigger %d frames, using current exposure" % numFrames) 73 | else: 74 | print (" Description: Trigger mode %d" % params[PxLApi.TriggerParams.MODE]) 75 | 76 | else: 77 | print ("getFeature return code: %d" % ret[0]) 78 | 79 | # 80 | # Step 4 81 | # Release the camera 82 | PxLApi.uninitialize(hCamera) 83 | 84 | 85 | if __name__ == "__main__": 86 | main() 87 | -------------------------------------------------------------------------------- /samples/Windows/commitSettingsAsDefault.py: -------------------------------------------------------------------------------- 1 | """ 2 | commitSettingsAsDefault.py 3 | 4 | Little utility program that will commit a cameras settings, to 5 | non volatile memory on the camera. Subsequently, the camera will use these same 6 | settings from a power-up. 7 | 8 | This same program can be used to commit the cameras current settings, or the factory 9 | default settings 10 | 11 | NOTE: This application assumes there is at most, one Pixelink camera 12 | connected to the system 13 | """ 14 | 15 | from pixelinkWrapper import* 16 | import sys 17 | import msvcrt 18 | 19 | 20 | def main(): 21 | 22 | # Step 1 Determine user options. 23 | if 0 != set_run_options(): 24 | usage() 25 | return 1 26 | 27 | # Step 2 Find and initialize a camera. 28 | ret = PxLApi.initialize(0) 29 | if(not(PxLApi.apiSuccess(ret[0]))): 30 | print("Could not Initialize the camera! Rc = %i" % ret[0]) 31 | return 1 32 | hCamera = ret[1] 33 | 34 | if(runOption_useFactoryDefaults): 35 | print("\nWARNING: This application will commit the cameras factory default settings\n" 36 | "so that they will be used as the power up defaults.\n" 37 | " -- Ok to proceed (y/n)?") 38 | else: 39 | print("\nWARNING: This application will commit the cameras current settings\n" 40 | "so that they will be used as the power up defaults.\n" 41 | " -- Ok to proceed (y/n)?") 42 | 43 | keyPressed = kbHit() 44 | 45 | if 'y' != keyPressed and 'Y' != keyPressed: 46 | # User aborted. 47 | PxLApi.uninitialize(hCamera) 48 | return 0 49 | 50 | # Step 3 If requested, load factory defaults. 51 | if runOption_useFactoryDefaults: 52 | ret = PxLApi.loadSettings(hCamera, PxLApi.DefaultMemoryChannel.FACTORY_DEFAULTS_MEMORY_CHANNEL) 53 | assert PxLApi.apiSuccess(ret[0]), "Cannot load factory settings" 54 | 55 | # Step 4 Save the current settings to the user channel. 56 | ret = PxLApi.saveSettings(hCamera, PxLApi.Settings.SETTINGS_USER) 57 | print("saveSettings returned %i" % ret[0]) 58 | 59 | # Step 5 Done. 60 | PxLApi.uninitialize(hCamera) 61 | return 0 62 | 63 | 64 | def set_run_options(): 65 | 66 | global runOption_useFactoryDefaults 67 | 68 | useFactoryDefaults = runOption_useFactoryDefaults 69 | 70 | if 1 < len(sys.argv): 71 | if "-f" == sys.argv[1] or "-F" == sys.argv[1]: 72 | useFactoryDefaults = True 73 | else: 74 | return 1 75 | 76 | runOption_useFactoryDefaults = useFactoryDefaults 77 | return 0 78 | 79 | """ 80 | Unbuffered keyboard input on command line. 81 | Keyboard input will be passed to the application without the user pressing 82 | the enter key. 83 | Note: IDLE does not support this functionality. 84 | """ 85 | def kbHit(): 86 | keyPressed = msvcrt.getch() 87 | if b'\xe0' == keyPressed: 88 | return str(keyPressed) 89 | return str(keyPressed, "utf-8") 90 | 91 | """ 92 | Usage instructions 93 | """ 94 | def usage(): 95 | print("\nSet the power on defaults for the connected camera. Without any parameters,\n" 96 | "the cameras current parameters will be used. If the '-f' option is specified\n" 97 | "then the factory default settings will be used.\n") 98 | print("Usage: %s [options]\n" % sys.argv[0]) 99 | print(" where options are:\n" 100 | " -f Use factory settings as power on defaults") 101 | 102 | 103 | if __name__ == "__main__": 104 | runOption_useFactoryDefaults = False # run options 105 | main() 106 | -------------------------------------------------------------------------------- /samples/Linux/measureGetNextFrameRate.py: -------------------------------------------------------------------------------- 1 | """ 2 | measureGetNextFrameRate.py 3 | 4 | Sample code to show a very simple frame grab. See the sample application 5 | 'getNextFrame' for a more robust frame grab example. 6 | 7 | This program simply calculates the frame rate of the camera (via frame grabs). 8 | """ 9 | 10 | from pixelinkWrapper import* 11 | from ctypes import* 12 | from select import select 13 | import sys 14 | import time 15 | import tty 16 | import termios 17 | 18 | 19 | def no_camera(rc): 20 | 21 | if rc == PxLApi.ReturnCode.ApiNoCameraError or rc == PxLApi.ReturnCode.ApiNoCameraAvailableError: 22 | return True 23 | 24 | return False 25 | 26 | 27 | def main(): 28 | 29 | getNextFramesPerItteration = 1 30 | 31 | # Just going to declare a very large buffer here 32 | # One that's large enough for any PixeLINK 4.0 camera 33 | frame = create_string_buffer(5000 * 5000 * 2) 34 | 35 | sys.stdin.flush() 36 | 37 | ret = PxLApi.initialize(0) 38 | if not(PxLApi.apiSuccess(ret[0])): 39 | print("Could not initialize the camera! rc = %i" % ret[0]) 40 | return 1 41 | 42 | hCamera = ret[1] 43 | 44 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 45 | if not(PxLApi.apiSuccess(ret[0])): 46 | print("Could not stream the camera! rc = %i" % ret[0]) 47 | PxLApi.uninitialize(hCamera) 48 | return 1 49 | 50 | print("Counting the number of images over a 20 second period...") 51 | 52 | frameCount = badFrameCount = 0 53 | startTime = currentTime = time.time() * 1000.0 # in milliseconds 54 | 55 | while 1: 56 | 57 | for i in range(getNextFramesPerItteration): 58 | ret = PxLApi.getNextFrame(hCamera, frame) 59 | if PxLApi.apiSuccess(ret[0]): 60 | frameCount += 1 61 | else: 62 | badFrameCount += 1 63 | if no_camera(ret[0]): 64 | print("Camera is Gone!! -- Aborting") 65 | return 1 # No point is continuing 66 | break # Do a time check to see if we are done. 67 | 68 | currentTime = time.time() * 1000.0 69 | 70 | if currentTime >= (startTime + 20000): 71 | break 72 | if currentTime <= (startTime + 200): 73 | getNextFramesPerItteration = getNextFramesPerItteration << 1 74 | 75 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 76 | 77 | print(" Received %i frames (%i bad), or %8.2f frames/second. %i getNextFrames/timecheck" % 78 | (frameCount+badFrameCount, badFrameCount, (frameCount+badFrameCount)/((currentTime - startTime) / 1000.0), 79 | getNextFramesPerItteration)) 80 | 81 | print("Press any key to exit") 82 | setUnbufKb(True) 83 | kbHit() 84 | setUnbufKb(False) 85 | print("\r") 86 | 87 | PxLApi.uninitialize(hCamera) 88 | 89 | return 0 90 | 91 | """ 92 | Unbuffered keyboard input on command line. 93 | Keyboard input will be passed to the application without the user pressing 94 | the enter key. 95 | Note: IDLE does not support this functionality. 96 | """ 97 | # A couple of useful global variables 98 | fd = sys.stdin.fileno() 99 | original_term_settings = termios.tcgetattr(fd) 100 | 101 | # Enable/disable unbuffered keyboard input 102 | def setUnbufKb(enable): 103 | if enable: 104 | tty.setraw(sys.stdin.fileno()) 105 | else: 106 | termios.tcsetattr(fd, termios.TCSADRAIN, original_term_settings) 107 | 108 | # Read hit button 109 | def kbHit(): 110 | return sys.stdin.read(1) 111 | 112 | 113 | if __name__ == "__main__": 114 | main() 115 | -------------------------------------------------------------------------------- /samples/Linux/commitSettingsAsDefault.py: -------------------------------------------------------------------------------- 1 | """ 2 | commitSettingsAsDefault.py 3 | 4 | Little utility program that will commit a cameras settings, to 5 | non volatile memory on the camera. Subsequently, the camera will use these same 6 | settings from a power-up. 7 | 8 | This same program can be used to commit the cameras current settings, or the factory 9 | default settings 10 | 11 | NOTE: This application assumes there is at most, one Pixelink camera 12 | connected to the system 13 | """ 14 | 15 | from pixelinkWrapper import* 16 | import sys 17 | import tty 18 | import termios 19 | 20 | 21 | def main(): 22 | 23 | # Step 1 Determine user options. 24 | if 0 != set_run_options(): 25 | usage() 26 | return 1 27 | 28 | # Step 2 Find and initialize a camera. 29 | ret = PxLApi.initialize(0) 30 | if(not(PxLApi.apiSuccess(ret[0]))): 31 | print("Could not Initialize the camera! Rc = %i" % ret[0]) 32 | return 1 33 | hCamera = ret[1] 34 | 35 | if(runOption_useFactoryDefaults): 36 | print("\nWARNING: This application will commit the cameras factory default settings\n" 37 | "so that they will be used as the power up defaults.\n" 38 | " -- Ok to proceed (y/n)?") 39 | else: 40 | print("\nWARNING: This application will commit the cameras current settings\n" 41 | "so that they will be used as the power up defaults.\n" 42 | " -- Ok to proceed (y/n)?") 43 | 44 | keyPressed = kbHit() 45 | 46 | if 'y' != keyPressed and 'Y' != keyPressed: 47 | # User aborted. 48 | PxLApi.uninitialize(hCamera) 49 | return 0 50 | 51 | # Step 3 If requested, load factory defaults. 52 | if runOption_useFactoryDefaults: 53 | ret = PxLApi.loadSettings(hCamera, PxLApi.DefaultMemoryChannel.FACTORY_DEFAULTS_MEMORY_CHANNEL) 54 | assert PxLApi.apiSuccess(ret[0]), "Cannot load factory settings" 55 | 56 | # Step 4 Save the current settings to the user channel. 57 | ret = PxLApi.saveSettings(hCamera, PxLApi.Settings.SETTINGS_USER) 58 | print("saveSettings returned %i" % ret[0]) 59 | 60 | # Step 5 Done. 61 | PxLApi.uninitialize(hCamera) 62 | return 0 63 | 64 | 65 | def set_run_options(): 66 | 67 | global runOption_useFactoryDefaults 68 | 69 | useFactoryDefaults = runOption_useFactoryDefaults 70 | 71 | if 1 < len(sys.argv): 72 | if "-f" == sys.argv[1] or "-F" == sys.argv[1]: 73 | useFactoryDefaults = True 74 | else: 75 | return 1 76 | 77 | runOption_useFactoryDefaults = useFactoryDefaults 78 | return 0 79 | 80 | """ 81 | Unbuffered keyboard input on command line. 82 | Keyboard input will be passed to the application without the user pressing 83 | the enter key. 84 | Note: IDLE does not support this functionality. 85 | """ 86 | def kbHit(): 87 | fd = sys.stdin.fileno() 88 | old_settings = termios.tcgetattr(fd) 89 | try: 90 | tty.setraw(sys.stdin.fileno()) 91 | ch = sys.stdin.read(1) 92 | finally: 93 | termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 94 | return ch 95 | 96 | """ 97 | Usage instructions 98 | """ 99 | def usage(): 100 | print("\nSet the power on defaults for the connected camera. Without any parameters,\n" 101 | "the cameras current parameters will be used. If the '-f' option is specified\n" 102 | "then the factory default settings will be used.\n") 103 | print("Usage: %s [options]\n" % sys.argv[0]) 104 | print(" where options are:\n" 105 | " -f Use factory settings as power on defaults") 106 | 107 | 108 | if __name__ == "__main__": 109 | runOption_useFactoryDefaults = False # run options 110 | main() 111 | -------------------------------------------------------------------------------- /samples/Linux/autoWhiteBalance.py: -------------------------------------------------------------------------------- 1 | """ 2 | autoWhiteBalance.py 3 | 4 | A simple little application to perform an auto white balance. 5 | 6 | Note1: This program does a 'directed' auto white balance. That is, it uses 7 | the FeatureId.AUTO_ROI to provide guiadance to the auto white balance algorithm, 8 | where to find 'white' in the image. If this feature is not used, then the 9 | camera will search the entire image, lookng for what it believes to be 'white'. 10 | 11 | Note2: The sample application 'whiteBalance' does not use the FeatureId.AUTO_ROI. 12 | 13 | Note3: The sample applicaiton 'autoExposure' shows how to cancel an auto operation. 14 | """ 15 | 16 | from pixelinkWrapper import* 17 | import time 18 | 19 | """ 20 | Simple function to abort an auto white balance 21 | """ 22 | def abort_auto_white_balance(hCamera): 23 | 24 | rgbGains = (1, 1, 1) # We need to set them to something -- unity is a nice simple value 25 | 26 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.WHITE_SHADING, PxLApi.FeatureFlags.MANUAL, rgbGains) 27 | if not(PxLApi.apiSuccess(ret[0])): 28 | print(" Error - setFeature to cancel AutoWB returned %i" % ret[0]) 29 | 30 | 31 | def main(): 32 | 33 | # Step 1 - Grab a camera. 34 | ret = PxLApi.initialize(0) 35 | if not(PxLApi.apiSuccess(ret[0])): 36 | print(" Error - initialize returned %i" % ret[0]) 37 | return 1 38 | 39 | hCamera = ret[1] 40 | 41 | # Step 2 - Get the current ROI 42 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.ROI) 43 | if not(PxLApi.apiSuccess(ret[0])): 44 | print(" Error - getFeature(FeatureId.ROI) returned %i" % ret[0]) 45 | PxLApi.uninitialize(hCamera) 46 | return 1 47 | 48 | params = ret[2] 49 | 50 | # Step 3 - Set the AUTO_ROI to a 256x256 window in the centre of the ROI 51 | params[0] = (params[2] - 256)/2 52 | params[1] = (params[3] - 256)/2 53 | params[2] = params[3] = 256 54 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.AUTO_ROI, PxLApi.FeatureFlags.MANUAL, params) 55 | if not(PxLApi.apiSuccess(ret[0])): 56 | print(" Error - setFeature(FeatureId.AUTO_ROI) returned %i" % ret[0]) 57 | PxLApi.uninitialize(hCamera) 58 | return 1 59 | 60 | # Step 4 - Perform a one-time, auto white balance 61 | params[0] = params[1] = params[2] = 1 62 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.WHITE_SHADING, PxLApi.FeatureFlags.ONEPUSH, params) 63 | if not(PxLApi.apiSuccess(ret[0])): 64 | print(" Error - setFeature(FeatureId.WHITE_SHADING) returned %i" % ret[0]) 65 | PxLApi.uninitialize(hCamera) 66 | return 1 67 | 68 | # Step 5 - Perform a one-time, auto white balance 69 | print("Waiting on White Balance to complete") 70 | 71 | for i in range(waitSeconds): 72 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.WHITE_SHADING) 73 | flags = ret[1] 74 | params = ret[2] 75 | if not(flags & PxLApi.FeatureFlags.ONEPUSH): 76 | break 77 | print("Interim balance --> R:%f, G:%f, B:%f" % (params[0], params[1], params[2])) 78 | time.sleep(1) 79 | waitedForSeconds = i 80 | 81 | if not(PxLApi.apiSuccess(ret[0])): 82 | print(" Error - getFeature(FeatureId.WHITE_SHADING) returned %i" % ret[0]) 83 | abort_auto_white_balance(hCamera) 84 | PxLApi.uninitialize(hCamera) 85 | return 1 86 | 87 | # The auto white balance completed successfully or with a warning -- or we got tired of waiting. 88 | if waitSeconds == (waitedForSeconds + 1): 89 | print("Tired of waiting on the white balance, aborting it") 90 | abort_auto_white_balance(hCamera) 91 | else: 92 | print("Final balance --> R:%f, G:%f, B:%f" % (params[0], params[1], params[2])) 93 | 94 | # Step 6 - Cleanup 95 | PxLApi.uninitialize(hCamera) 96 | 97 | return 0 98 | 99 | 100 | if __name__ == "__main__": 101 | waitSeconds = 10 # Wait this amount of time for a white balance to complete. 102 | main() 103 | -------------------------------------------------------------------------------- /samples/Windows/autoWhiteBalance.py: -------------------------------------------------------------------------------- 1 | """ 2 | autoWhiteBalance.py 3 | 4 | A simple little application to perform an auto white balance. 5 | 6 | Note1: This program does a 'directed' auto white balance. That is, it uses 7 | the FeatureId.AUTO_ROI to provide guiadance to the auto white balance algorithm, 8 | where to find 'white' in the image. If this feature is not used, then the 9 | camera will search the entire image, lookng for what it believes to be 'white'. 10 | 11 | Note2: The sample application 'whiteBalance' does not use the FeatureId.AUTO_ROI. 12 | 13 | Note3: The sample applicaiton 'autoExposure' shows how to cancel an auto operation. 14 | """ 15 | 16 | from pixelinkWrapper import* 17 | import time 18 | 19 | """ 20 | Simple function to abort an auto white balance 21 | """ 22 | def abort_auto_white_balance(hCamera): 23 | 24 | rgbGains = (1, 1, 1) # We need to set them to something -- unity is a nice simple value 25 | 26 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.WHITE_SHADING, PxLApi.FeatureFlags.MANUAL, rgbGains) 27 | if not(PxLApi.apiSuccess(ret[0])): 28 | print(" Error - setFeature to cancel AutoWB returned %i" % ret[0]) 29 | 30 | 31 | def main(): 32 | 33 | # Step 1 - Grab a camera. 34 | ret = PxLApi.initialize(0) 35 | if not(PxLApi.apiSuccess(ret[0])): 36 | print(" Error - initialize returned %i" % ret[0]) 37 | return 1 38 | 39 | hCamera = ret[1] 40 | 41 | # Step 2 - Get the current ROI 42 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.ROI) 43 | if not(PxLApi.apiSuccess(ret[0])): 44 | print(" Error - getFeature(FeatureId.ROI) returned %i" % ret[0]) 45 | PxLApi.uninitialize(hCamera) 46 | return 1 47 | 48 | params = ret[2] 49 | 50 | # Step 3 - Set the AUTO_ROI to a 256x256 window in the centre of the ROI 51 | params[0] = (params[2] - 256)/2 52 | params[1] = (params[3] - 256)/2 53 | params[2] = params[3] = 256 54 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.AUTO_ROI, PxLApi.FeatureFlags.MANUAL, params) 55 | if not(PxLApi.apiSuccess(ret[0])): 56 | print(" Error - setFeature(FeatureId.AUTO_ROI) returned %i" % ret[0]) 57 | PxLApi.uninitialize(hCamera) 58 | return 1 59 | 60 | # Step 4 - Perform a one-time, auto white balance 61 | params[0] = params[1] = params[2] = 1 62 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.WHITE_SHADING, PxLApi.FeatureFlags.ONEPUSH, params) 63 | if not(PxLApi.apiSuccess(ret[0])): 64 | print(" Error - setFeature(FeatureId.WHITE_SHADING) returned %i" % ret[0]) 65 | PxLApi.uninitialize(hCamera) 66 | return 1 67 | 68 | # Step 5 - Perform a one-time, auto white balance 69 | print("Waiting on White Balance to complete") 70 | 71 | for i in range(waitSeconds): 72 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.WHITE_SHADING) 73 | flags = ret[1] 74 | params = ret[2] 75 | if not(flags & PxLApi.FeatureFlags.ONEPUSH): 76 | break 77 | print("Interim balance --> R:%f, G:%f, B:%f" % (params[0], params[1], params[2])) 78 | time.sleep(1) 79 | waitedForSeconds = i 80 | 81 | if not(PxLApi.apiSuccess(ret[0])): 82 | print(" Error - getFeature(FeatureId.WHITE_SHADING) returned %i" % ret[0]) 83 | abort_auto_white_balance(hCamera) 84 | PxLApi.uninitialize(hCamera) 85 | return 1 86 | 87 | # The auto white balance completed successfully or with a warning -- or we got tired of waiting. 88 | if waitSeconds == (waitedForSeconds + 1): 89 | print("Tired of waiting on the white balance, aborting it") 90 | abort_auto_white_balance(hCamera) 91 | else: 92 | print("Final balance --> R:%f, G:%f, B:%f" % (params[0], params[1], params[2])) 93 | 94 | # Step 6 - Cleanup 95 | PxLApi.uninitialize(hCamera) 96 | 97 | return 0 98 | 99 | 100 | if __name__ == "__main__": 101 | waitSeconds = 10 # Wait this amount of time for a white balance to complete. 102 | main() 103 | -------------------------------------------------------------------------------- /samples/Linux/setFeature.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | setFeature.py 4 | 5 | Simple sample application demostrating the use of the setFeature 6 | function in the pixelinkWrapper 7 | """ 8 | 9 | from pixelinkWrapper import* 10 | 11 | """ 12 | Demostrate the setFeature function of the pixelinkWrapper, by setting 13 | FeatuerId.ROI. It also uses getCameraFeatures to demostrate how to 14 | determine feature limits 15 | """ 16 | def main(): 17 | 18 | # 19 | # Step 1 20 | # Grab a Pixelink camera. Note that if there is more than one camera 21 | # connected, this will just grab the first one found. If we wanted 22 | # a specific camera, than we could use getNumberCameras/initialize 23 | ret = PxLApi.initialize(0) 24 | if not PxLApi.apiSuccess(ret[0]): 25 | print (" Could not find a camera!") 26 | return 27 | 28 | hCamera = ret[1] 29 | 30 | # 31 | # Step 2 32 | # Call getCameraFeatures for FeatuerId.ROI. We do this so we can determine 33 | # the ROI limits. Like all pixelinkWrapper functions, getCameraFeatures 34 | # returns a tuple with number of elements. More specifically, 35 | # getCameraFeatures will return: 36 | # ret[0] - Return code 37 | # ret[1] - A list of features. Given that we are requesting on a specific 38 | # feature, there should only be one element in this list 39 | ret = PxLApi.getCameraFeatures(hCamera, PxLApi.FeatureId.ROI) 40 | if not PxLApi.apiSuccess(ret[0]): 41 | print (" Could not getCameraFeatuers on ROI, ret: %d!" % ret[0]) 42 | PxLApi.uninitialize(hCamera) 43 | return 44 | 45 | cameraFeatures = ret[1] 46 | assert 1 == cameraFeatures.uNumberOfFeatures 47 | maxWidth = cameraFeatures.Features[0].Params[PxLApi.RoiParams.WIDTH].fMaxValue 48 | maxHeight = cameraFeatures.Features[0].Params[PxLApi.RoiParams.HEIGHT].fMaxValue 49 | print (" This camera has a max ROI of %d x %d" % (maxWidth, maxHeight)) 50 | 51 | # 52 | # Step 3 53 | # Call setFeature for FeatuerId.ROI. 54 | # We will set the ROI to be half of the max, rougly centered 55 | params = [] 56 | params.insert (PxLApi.RoiParams.WIDTH, maxWidth / 2) 57 | params.insert (PxLApi.RoiParams.HEIGHT, maxHeight / 2) 58 | params.insert (PxLApi.RoiParams.LEFT, maxWidth / 4) 59 | params.insert (PxLApi.RoiParams.TOP, maxHeight / 4) 60 | 61 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.ROI, PxLApi.FeatureFlags.MANUAL, params) 62 | if not PxLApi.apiSuccess(ret[0]): 63 | print (" Could not setFeature on ROI, ret: %d!" % ret[0]) 64 | PxLApi.uninitialize(hCamera) 65 | return 66 | 67 | # 68 | # Step 4 69 | # Read back the ROI, as the camera may have had to adjust the ROI slightly 70 | # to accomodate sensor restrictions 71 | roundingRequired = PxLApi.ReturnCode.ApiSuccessParametersChanged == ret[0] 72 | 73 | # Call getFeature. Like all pixelinkWrapper functions, getFeature 74 | # returns a tuple with number of elements. More specifically, 75 | # getFeature will return: 76 | # ret[0] - Return code 77 | # ret[1] - A bit mask of PxLApi.FeatureFlags 78 | # ret[2] - A list of paramters. The number of elements in the list varies 79 | # with the feature 80 | ret = PxLApi.getFeature (hCamera, PxLApi.FeatureId.ROI) 81 | if PxLApi.apiSuccess(ret[0]): 82 | flags = ret[1] 83 | updatedParams = ret[2] 84 | print (" Cameras ROI set to %d x %d (%d, %d)" % \ 85 | (updatedParams[PxLApi.RoiParams.WIDTH], \ 86 | updatedParams[PxLApi.RoiParams.HEIGHT], \ 87 | updatedParams[PxLApi.RoiParams.LEFT], \ 88 | updatedParams[PxLApi.RoiParams.TOP])) 89 | 90 | if roundingRequired: 91 | print ( " Warning -- The camera had to make a small adjustment to the ROI") 92 | 93 | # 94 | # Step 5 95 | # Release the camera 96 | PxLApi.uninitialize(hCamera) 97 | 98 | 99 | if __name__ == "__main__": 100 | main() 101 | 102 | -------------------------------------------------------------------------------- /samples/Windows/setFeature.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | setFeature.py 4 | 5 | Simple sample application demostrating the use of the setFeature 6 | function in the pixelinkWrapper 7 | """ 8 | 9 | from pixelinkWrapper import* 10 | 11 | """ 12 | Demostrate the setFeature function of the pixelinkWrapper, by setting 13 | FeatuerId.ROI. It also uses getCameraFeatures to demostrate how to 14 | determine feature limits 15 | """ 16 | def main(): 17 | 18 | # 19 | # Step 1 20 | # Grab a Pixelink camera. Note that if there is more than one camera 21 | # connected, this will just grab the first one found. If we wanted 22 | # a specific camera, than we could use getNumberCameras/initialize 23 | ret = PxLApi.initialize(0) 24 | if not PxLApi.apiSuccess(ret[0]): 25 | print (" Could not find a camera!") 26 | return 27 | 28 | hCamera = ret[1] 29 | 30 | # 31 | # Step 2 32 | # Call getCameraFeatures for FeatuerId.ROI. We do this so we can determine 33 | # the ROI limits. Like all pixelinkWrapper functions, getCameraFeatures 34 | # returns a tuple with number of elements. More specifically, 35 | # getCameraFeatures will return: 36 | # ret[0] - Return code 37 | # ret[1] - A list of features. Given that we are requesting on a specific 38 | # feature, there should only be one element in this list 39 | ret = PxLApi.getCameraFeatures(hCamera, PxLApi.FeatureId.ROI) 40 | if not PxLApi.apiSuccess(ret[0]): 41 | print (" Could not getCameraFeatuers on ROI, ret: %d!" % ret[0]) 42 | PxLApi.uninitialize(hCamera) 43 | return 44 | 45 | cameraFeatures = ret[1] 46 | assert 1 == cameraFeatures.uNumberOfFeatures 47 | maxWidth = cameraFeatures.Features[0].Params[PxLApi.RoiParams.WIDTH].fMaxValue 48 | maxHeight = cameraFeatures.Features[0].Params[PxLApi.RoiParams.HEIGHT].fMaxValue 49 | print (" This camera has a max ROI of %d x %d" % (maxWidth, maxHeight)) 50 | 51 | # 52 | # Step 3 53 | # Call setFeature for FeatuerId.ROI. 54 | # We will set the ROI to be half of the max, rougly centered 55 | params = [] 56 | params.insert (PxLApi.RoiParams.WIDTH, maxWidth / 2) 57 | params.insert (PxLApi.RoiParams.HEIGHT, maxHeight / 2) 58 | params.insert (PxLApi.RoiParams.LEFT, maxWidth / 4) 59 | params.insert (PxLApi.RoiParams.TOP, maxHeight / 4) 60 | 61 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.ROI, PxLApi.FeatureFlags.MANUAL, params) 62 | if not PxLApi.apiSuccess(ret[0]): 63 | print (" Could not setFeature on ROI, ret: %d!" % ret[0]) 64 | PxLApi.uninitialize(hCamera) 65 | return 66 | 67 | # 68 | # Step 4 69 | # Read back the ROI, as the camera may have had to adjust the ROI slightly 70 | # to accomodate sensor restrictions 71 | roundingRequired = PxLApi.ReturnCode.ApiSuccessParametersChanged == ret[0] 72 | 73 | # Call getFeature. Like all pixelinkWrapper functions, getFeature 74 | # returns a tuple with number of elements. More specifically, 75 | # getFeature will return: 76 | # ret[0] - Return code 77 | # ret[1] - A bit mask of PxLApi.FeatureFlags 78 | # ret[2] - A list of paramters. The number of elements in the list varies 79 | # with the feature 80 | ret = PxLApi.getFeature (hCamera, PxLApi.FeatureId.ROI) 81 | if PxLApi.apiSuccess(ret[0]): 82 | flags = ret[1] 83 | updatedParams = ret[2] 84 | print (" Cameras ROI set to %d x %d (%d, %d)" % \ 85 | (updatedParams[PxLApi.RoiParams.WIDTH], \ 86 | updatedParams[PxLApi.RoiParams.HEIGHT], \ 87 | updatedParams[PxLApi.RoiParams.LEFT], \ 88 | updatedParams[PxLApi.RoiParams.TOP])) 89 | 90 | if roundingRequired: 91 | print ( " Warning -- The camera had to make a small adjustment to the ROI") 92 | 93 | # 94 | # Step 5 95 | # Release the camera 96 | PxLApi.uninitialize(hCamera) 97 | 98 | 99 | if __name__ == "__main__": 100 | main() 101 | 102 | -------------------------------------------------------------------------------- /samples/Linux/preview.py: -------------------------------------------------------------------------------- 1 | """ 2 | preview.py 3 | 4 | A simple application that previews the camera. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | import sys 9 | import tty 10 | import termios 11 | 12 | """ 13 | Start and stop preview. 14 | Preview gets stopped after a user presses a key. 15 | """ 16 | def set_preview_state(hCamera): 17 | 18 | # Start the preview (NOTE: camera must be streaming) 19 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.START) 20 | if ret[0] == PxLApi.ReturnCode.ApiNotSupportedOnLiteVersion: 21 | return ret 22 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 23 | 24 | # Run preview until the user presses a key.... 25 | print("Press any key to stop preview......") 26 | kbHit() 27 | 28 | # Stop the preview 29 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.STOP) 30 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 31 | 32 | return ret 33 | 34 | """ 35 | Start and stop preview using setPreviewStateEx with a callback function. 36 | Preview gets stopped after a user presses a key 37 | """ 38 | def set_preview_state_ex(hCamera): 39 | 40 | context = None 41 | # Start the preview 42 | ret = PxLApi.setPreviewStateEx(hCamera, PxLApi.PreviewState.START, context, changeFunction) 43 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 44 | 45 | # Run the preview until the user presses a key.... 46 | print("Press any key to stop preview with callback and exit......") 47 | kbHit() 48 | 49 | # Stop the preview 50 | ret = PxLApi.setPreviewStateEx(hCamera, PxLApi.PreviewState.START, context, changeFunction) 51 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 52 | 53 | 54 | def main(): 55 | 56 | # Grab the first camera we find 57 | ret = PxLApi.initialize(0) 58 | if PxLApi.apiSuccess(ret[0]): 59 | hCamera = ret[1] 60 | 61 | # Just use all of the camer's default settings. 62 | # Start the stream 63 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 64 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 65 | 66 | # Start and stop preview using setPreviewState 67 | ret = set_preview_state(hCamera) 68 | if ret[0] == PxLApi.ReturnCode.ApiNotSupportedOnLiteVersion: 69 | print("ERROR: Api Lite detected -- this application requires the standard Pixelink API") 70 | 71 | # Clean up by stopping the stream and unitializing the camera 72 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 73 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 74 | PxLApi.uninitialize(hCamera) 75 | return 1 76 | 77 | # Run preview with callback when the user presses a key 78 | print("Press any key to start preview with callback......") 79 | kbHit() 80 | # Start and stop preview using setPreviewStateEx 81 | set_preview_state_ex(hCamera) 82 | print("\r") 83 | 84 | # Stop the stream 85 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 86 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 87 | 88 | # Uninitialize the camera now that we're done with it. 89 | PxLApi.uninitialize(hCamera) 90 | 91 | return 0 92 | 93 | """ 94 | Unbuffered keyboard input on command line. 95 | Keyboard input will be passed to the application without the user pressing 96 | the enter key. 97 | Note: IDLE does not support this functionality. 98 | """ 99 | def kbHit(): 100 | fd = sys.stdin.fileno() 101 | old_settings = termios.tcgetattr(fd) 102 | try: 103 | tty.setraw(sys.stdin.fileno()) 104 | ch = sys.stdin.read(1) 105 | finally: 106 | termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 107 | return ch 108 | 109 | """ 110 | Callback function for setPreviewStateEx 111 | """ 112 | @PxLApi._changeFunction 113 | def changeFunction(hCamera, changeCode, context): 114 | print("\rCallback executed with changeCode = %i " % changeCode, end="") 115 | return 0 116 | 117 | 118 | if __name__ == "__main__": 119 | main() 120 | -------------------------------------------------------------------------------- /samples/Windows/previewWithTk.py: -------------------------------------------------------------------------------- 1 | """ 2 | previewWithTk.py 3 | 4 | Simple sample application demostrating the use of the API Preview function, 5 | embedded within a Tkinter window 6 | """ 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import ctypes.wintypes 10 | import tkinter as Tk 11 | import threading 12 | import time 13 | import win32api, win32con 14 | 15 | """ 16 | Preview control thread -- starts and stops the preview, as well as handles the Windows Dispatch 17 | of the preview window. 18 | """ 19 | def control_preview_thread(): 20 | user32 = windll.user32 21 | msg = ctypes.wintypes.MSG() 22 | pMsg = ctypes.byref(msg) 23 | 24 | # Create an arror cursor (see below) 25 | defaultCursor = win32api.LoadCursor(0,win32con.IDC_ARROW) 26 | 27 | # Get the current dimensions 28 | width = topWindow.winfo_width() 29 | height = topWindow.winfo_height() 30 | ret = PxLApi.setPreviewSettings(hCamera, "", PxLApi.WindowsPreview.WS_VISIBLE | PxLApi.WindowsPreview.WS_CHILD , 31 | 0, 0, width, height, topHwnd) 32 | 33 | # Start the preview (NOTE: camera must be streaming). Keep looping until the previewState is STOPed 34 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.START) 35 | while (PxLApi.PreviewState.START == previewState and PxLApi.apiSuccess(ret[0])): 36 | if user32.PeekMessageW(pMsg, 0, 0, 0, 1) != 0: 37 | # All messages are simpy forwarded onto to other Win32 event handlers. However, we do 38 | # set the cursor just to ensure that parent windows resize cursors do not persist within 39 | # the preview window 40 | win32api.SetCursor(defaultCursor) 41 | user32.TranslateMessage(pMsg) 42 | user32.DispatchMessageW(pMsg) 43 | 44 | # User has exited -- Stop the preview 45 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.STOP) 46 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 47 | 48 | """ 49 | Creates a new preview thread for each preview run 50 | """ 51 | def create_new_preview_thread(): 52 | 53 | # Creates a thread with preview control / meessage pump 54 | return threading.Thread(target=control_preview_thread, args=(), daemon=True) 55 | 56 | """ 57 | Start the preview (with message pump). 58 | Preview gets stopped when the top level window is closed. 59 | """ 60 | def start_preview(): 61 | # Controls preview thread 62 | global previewState 63 | 64 | # Declare control preview thread that can control preview and poll the message pump on Windows 65 | previewState = PxLApi.PreviewState.START 66 | previewThread = create_new_preview_thread() 67 | previewThread.start() 68 | 69 | """ 70 | Tkinter Window resize handler 71 | """ 72 | def winResizeHandler(event): 73 | # The user has resized the window. Also resize the preview so that the preview will scale to the new window size 74 | PxLApi.setPreviewSettings(hCamera, "", PxLApi.WindowsPreview.WS_VISIBLE | PxLApi.WindowsPreview.WS_CHILD , 0, 0, event.width, event.height, topHwnd) 75 | 76 | def main(): 77 | # For simplicity -- share some common (static) variables so they can be used in other threads 78 | global topWindow 79 | global menubar 80 | 81 | global hCamera 82 | global topHwnd 83 | 84 | # Step 1 85 | # Create our top level window, with a menu bar 86 | topWindow = Tk.Tk() 87 | topWindow.title("PixelinkPreview") 88 | topWindow.geometry("1024x768") 89 | 90 | menubar = Tk.Menu(topWindow) 91 | filemenu = Tk.Menu(menubar, tearoff=0) 92 | filemenu.add_command(label="Exit",command=topWindow.quit) 93 | menubar.add_cascade(label="File", menu=filemenu) 94 | topWindow.config(menu=menubar) 95 | 96 | # Step 2 97 | # Set up the camera, including starting the stream 98 | ret = PxLApi.initialize(0) 99 | if PxLApi.apiSuccess(ret[0]): 100 | hCamera = ret[1] 101 | 102 | # Just use all of the camers's current settings. 103 | # Start the stream 104 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 105 | if PxLApi.apiSuccess(ret[0]): 106 | 107 | # Step 3 108 | # Start the preview / message pump, as well as the TkInter window resize handler 109 | topHwnd = int(topWindow.frame(),0) 110 | 111 | start_preview() 112 | topWindow.bind('', winResizeHandler) 113 | 114 | # Step 4 115 | # Call the start the UI -- it will only return on Window exit 116 | topWindow.mainloop() 117 | 118 | # Step 5 119 | # The user has quit the appliation, shut down the preview and stream 120 | previewState = PxLApi.PreviewState.STOP 121 | 122 | # Give preview a bit of time to stop 123 | time.sleep(0.05) 124 | 125 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 126 | 127 | PxLApi.uninitialize(hCamera) 128 | 129 | 130 | if __name__ == "__main__": 131 | main() 132 | -------------------------------------------------------------------------------- /samples/Linux/lowLinkMemory.py: -------------------------------------------------------------------------------- 1 | """ 2 | lowUsbMemory.py 3 | 4 | Demonstrates how to detect / deal with systems configured with a small amount of link 5 | (USB or NetworkStack) memory. 6 | 7 | As per the INSTALL.INSTRUCTIONS.txt file that accompanies the Pixelink SDK, by default, 8 | many Linux systems may not be configured with enough link buffer memory to permit optimal 9 | streaming for a high performance camera, such as many models of the Pixelink cameras. 10 | This same TXT file offers advice on how you may reconfigure your system to allocate more 11 | link buffer memory. 12 | 13 | However, should you choose not to re-configure your system, you can use the Pixelink Python 14 | wrapper function 'PxLApi.setStreamState' to determine if your system's link memory requirements 15 | are less than optimal. In particular, if the PxLApi.setStreamState returns a response code of 16 | 'PxLApi.ReturnCode.ApiSucessLowMemory' when you attempt a PxLApi.StreamState.START or 17 | PxLApi.StreamState.PAUSE operation, then the Pixelink API has detected that your systems link 18 | memory allocation is sub-optimal. The Pixelink API has made some internal 'concessions' to 19 | accomodate. These concesions MAY result in some frame loss when the camera is streaming. More 20 | on this below. 21 | 22 | So, what should your application do when PxLApi.setStreamState returns 23 | 'PxLApi.ReturnCode.ApiSuccessLowMemory'?? 24 | There are several otions: 25 | 1. Do nothing. 26 | Meaning, the Pixelink API has already made some internal concessions to deal with 27 | the sub-optimal link buffer space. If while streaming, your camera continually flashes 28 | its LED green -- then no frame loss occuring. However, if you see a periodic red flash 29 | from the camera, then you are experiencing some frame loss that is probably the result 30 | of these concessions. In which case, you may want to consider one of the other options. 31 | 2. Use a 8-bit pixel format (if you're not already). 32 | The 12 and 16-bit pixel formats (MONO16, MONO12_PACKED, and BAYER16) 33 | produce larger images that require more link buffer memory 34 | 3. Reduce the region of interest (ROI) to reduce image size. 35 | 4. Use Pixel Addressing to reduce image size. 36 | 5. Reduce the frame rate. 37 | 38 | This sample, uses strategy #5 from above. 39 | """ 40 | 41 | from pixelinkWrapper import* 42 | 43 | def main(): 44 | 45 | currentFrameRate = 0.0 46 | minFrameRate = 0.0 47 | 48 | # We assume there's only one camera connected 49 | ret = PxLApi.initialize(0) 50 | if PxLApi.apiSuccess(ret[0]): 51 | hCamera = ret[1] 52 | 53 | ret = PxLApi.getCameraFeatures(hCamera, PxLApi.FeatureId.FRAME_RATE) 54 | if PxLApi.apiSuccess(ret[0]): 55 | cameraFeatures = ret[1] 56 | minFrameRate = cameraFeatures.Features[0].Params[0].fMinValue 57 | 58 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.FRAME_RATE) 59 | if not PxLApi.apiSuccess(ret[0]): 60 | print("Difficuty accessing PxLApi.FeatureId.FRAME_RATE, rc=%i" % ret[0]) 61 | PxLApi.uninitialize(hCamera) 62 | return 1 63 | 64 | params = ret[2] 65 | currentFrameRate = params[0] 66 | 67 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 68 | if not PxLApi.apiSuccess(ret[0]): 69 | print("Difficuty starting the stream, rc=%i" % ret[0]) 70 | PxLApi.uninitialize(hCamera) 71 | return 1 72 | 73 | while PxLApi.ReturnCode.ApiSuccessLowMemory == ret[0]: 74 | print("Sub-optimal link memory allocation detected at a frame rate of %5.2f fps" % currentFrameRate) 75 | if currentFrameRate == minFrameRate: 76 | break # We cannot reduce the frame rate any lower. 77 | 78 | # try restarting the stream at a lower frame rate 79 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 80 | if not PxLApi.apiSuccess(ret[0]): 81 | break 82 | 83 | # reduce the frame rate by 20%, being careful to not go lower than the minimum value 84 | currentFrameRate = (currentFrameRate * 0.8) 85 | if minFrameRate > currentFrameRate: 86 | currentFrameRate = minFrameRate 87 | params = [currentFrameRate,] 88 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.FRAME_RATE, PxLApi.FeatureFlags.MANUAL, params) 89 | if not PxLApi.apiSuccess(ret[0]): 90 | break 91 | 92 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 93 | if not PxLApi.apiSuccess(ret[0]): 94 | break 95 | 96 | if PxLApi.apiSuccess(ret[0]): 97 | 98 | if PxLApi.ReturnCode.ApiSuccessLowMemory != ret[0]: 99 | print("Camera can stream fine at a frame rate of %5.2f fps" % currentFrameRate) 100 | else: 101 | print("Cannot fully accomodate sub-optimal link memory allocations, " 102 | "try adjusting ROI, PIXEL_ADDRESSING, or PIXEL_FORMAT") 103 | 104 | else: 105 | print("Difficuty attempting to reduce the frame rate, rc=%i" % ret[0]) 106 | 107 | PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 108 | PxLApi.uninitialize(hCamera) 109 | 110 | return 0 111 | 112 | 113 | if __name__ == "__main__": 114 | main() 115 | -------------------------------------------------------------------------------- /samples/Windows/gpio.py: -------------------------------------------------------------------------------- 1 | """ 2 | gpio.py 3 | 4 | This demonstrates how to control a camera's general purpose input (GPI), and general purpose output (GPO). 5 | 6 | This sample works with all Firewire/USB/USB3/GigE/10GigE cameras, provided the camera has at least one GPI 7 | and a GPO. It also interrogates the camera to determine the camera’s specific GPIO capability/properties. 8 | 9 | If the camera has at least one GPI and a GPO, they will be set. Then, the program will poll the GPI value, 10 | reporting on the value on the console, and on the GPO. 11 | """ 12 | 13 | from pixelinkWrapper import* 14 | import msvcrt 15 | import time 16 | 17 | # A few useful defines 18 | GPIO_ON = True 19 | GPIO_OFF = False 20 | 21 | # The poll period of the GPI, in seconds 22 | POLL_PERIOD_SEC = 0.5 23 | 24 | """ 25 | Returns true if the camera has a GPI and a GPO 26 | """ 27 | def supports_gpio(hCamera): 28 | # GPIO index supporting GPI 29 | global gpiIndex 30 | 31 | # Step 1 32 | # Get info on the GPIO for this camera 33 | ret = PxLApi.getCameraFeatures(hCamera, PxLApi.FeatureId.GPIO) 34 | if not PxLApi.apiSuccess(ret[0]): 35 | return False 36 | gpioFeatureInfo = ret[1] 37 | 38 | # Step 2 39 | # Look at the feature info, and ensure the camera supports a GPI and a GPO 40 | if not gpioFeatureInfo.Features[0].uFlags & PxLApi.FeatureFlags.PRESENCE: # No GPIOs at all !! 41 | return False 42 | if gpioFeatureInfo.Features[0].Params[0].fMaxValue < 2.0: # We need at least 2 GPIO !! 43 | return False 44 | if gpioFeatureInfo.Features[0].Params[1].fMaxValue < PxLApi.GpioModes.INPUT: # Does not support GPI !! 45 | return False 46 | if gpioFeatureInfo.Features[0].Params[0].fMaxValue == 3.0: # For PL-X cameras 47 | gpiIndex = 3.0 48 | else: # For PL-D and other cameras 49 | gpiIndex = 1.0 50 | 51 | return True 52 | 53 | 54 | 55 | def setup_gpios(hCamera): 56 | 57 | gpioParams = [0] * PxLApi.GpioParams.NUM_PARAMS 58 | # Step 1 59 | # Set the GPI 60 | gpioParams[PxLApi.GpioParams.INDEX] = gpiIndex 61 | gpioParams[PxLApi.GpioParams.MODE] = PxLApi.GpioModes.INPUT 62 | gpioParams[PxLApi.GpioParams.POLARITY] = 0 63 | # Don't care about the other parameters 64 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.GPIO, PxLApi.FeatureFlags.MANUAL, gpioParams) 65 | if not PxLApi.apiSuccess(ret[0]): 66 | return ret 67 | 68 | # Step 2 69 | # Set the GPO (to normal mode) 70 | gpioParams[PxLApi.GpioParams.INDEX] = 2.0 71 | gpioParams[PxLApi.GpioParams.MODE] = PxLApi.GpioModes.NORMAL 72 | gpioParams[PxLApi.GpioParams.POLARITY] = 0 73 | # Don't care about the other parameters 74 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.GPIO, PxLApi.FeatureFlags.MANUAL, gpioParams) 75 | 76 | return ret 77 | 78 | 79 | def main(): 80 | 81 | gpioParams = [0] * PxLApi.GpioParams.NUM_PARAMS 82 | 83 | # Step 1 84 | # Find and initialize a camera 85 | ret = PxLApi.initialize(0) 86 | if not(PxLApi.apiSuccess(ret[0])): 87 | print("Could not Initialize the camera! Rc = %i" % ret[0]) 88 | return 1 89 | 90 | hCamera = ret[1] 91 | 92 | # Step 2 93 | # Ensure the camera has at least 2 gpios, and supports a GPI 94 | if not supports_gpio(hCamera): 95 | print("Camera does not support GPIO!") 96 | PxLApi.uninitialize(hCamera) 97 | return 1 98 | 99 | # Step 3 100 | # Set the camera up for one GPI and one GPO 101 | ret = setup_gpios(hCamera) 102 | if not PxLApi.apiSuccess(ret[0]): 103 | print("Could not setup the GPIOs! Rc = %i" % ret[0]) 104 | PxLApi.uninitialize(hCamera) 105 | return 1 106 | 107 | # Give the last GPI a value that will ensure our loop will print/assert the GPO on its first time through 108 | lastGpi = GPIO_ON 109 | 110 | # Step 4 111 | # Poll the GPI, reporting it's value on the console, and on the GPO 112 | print("Polling the GPI every %i ms, press any key to exit" % (POLL_PERIOD_SEC*1000)) 113 | while not msvcrt.kbhit(): 114 | # Read the GPI 115 | gpioParams[PxLApi.GpioParams.INDEX] = gpiIndex 116 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.GPIO, gpioParams) 117 | if not PxLApi.apiSuccess(ret[0]): 118 | print("\nCould not read the GPI! Rc = %i" % ret[0]) 119 | PxLApi.uninitialize(hCamera) 120 | return 1 121 | gpioParams = ret[2] 122 | 123 | if 0 == gpioParams[PxLApi.GpioModeInput.STATUS]: 124 | currentGpi = GPIO_OFF 125 | else: 126 | currentGpi = GPIO_ON 127 | 128 | # If the GPI changed, then set the GPO 129 | 130 | if currentGpi != lastGpi: 131 | 132 | gpioParams[PxLApi.GpioParams.INDEX] = 2.0 133 | gpioParams[PxLApi.GpioParams.MODE] = PxLApi.GpioModes.NORMAL 134 | gpioParams[PxLApi.GpioParams.POLARITY] = float(currentGpi) 135 | # Don't care about the other parameters 136 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.GPIO, PxLApi.FeatureFlags.MANUAL, gpioParams) 137 | if not PxLApi.apiSuccess(ret[0]): 138 | print("\nCould not write the GPO! Rc = %i" % ret[0]) 139 | PxLApi.uninitialize(hCamera) 140 | return 1 141 | 142 | lastGpi = currentGpi 143 | 144 | if GPIO_ON == currentGpi: 145 | currentGpiState = "On" 146 | else: 147 | currentGpiState = "Off" 148 | print("\rGPI is %s " % currentGpiState, end="", flush=True) 149 | 150 | time.sleep(POLL_PERIOD_SEC) # 500 ms 151 | 152 | PxLApi.uninitialize(hCamera) 153 | return 0 154 | 155 | 156 | if __name__ == "__main__": 157 | gpiIndex = 0.0 # GPIO index supporting GPI depending on the camera model 158 | main() -------------------------------------------------------------------------------- /samples/Linux/openCVSnapshot.py: -------------------------------------------------------------------------------- 1 | """ 2 | openCVSnapshot.py 3 | 4 | A demonstration of how to capture a camera image that can be 'imported' into openCV. 5 | 6 | OpenCV needs to be installed to run this sample (e.g.: 'pip install opencv-python') 7 | to locate the appropriate libaries. 8 | """ 9 | 10 | from pixelinkWrapper import* 11 | from ctypes import* 12 | import numpy 13 | import cv2 14 | import os 15 | 16 | # A few useful defines 17 | EXIT_SUCCESS = 0 18 | EXIT_FAILURE = 1 19 | 20 | PT_COLOR = 0 21 | PT_MONO = 1 22 | PT_OTHERWISE = 2 # Special cameras, like polarized and interleaved HDR 23 | 24 | """ 25 | IMPORTANT NOTE: 26 | This function will only return a meaningful value, if called while NOT streaming 27 | """ 28 | def getPixelType(hCamera): 29 | 30 | pixelType = PT_OTHERWISE 31 | # Take a simple minded approach; All Pixelink monochrome cameras support PxLApi.PixelFormat.MONO8, and all 32 | # Pixelink color cameas support PxLApi.PixelFormat.BAYER8. So, try setting each of these to see if it 33 | # works. 34 | 35 | # However, we should take care to restore the current pixel format. 36 | savedPixelFormat = 0 37 | newPixelFormat = 0 38 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT) 39 | if not PxLApi.apiSuccess(ret[0]): 40 | return pixelType 41 | 42 | params = ret[2] 43 | savedPixelFormat = int(params[0]) 44 | 45 | # Is it mono? 46 | newPixelFormat = PxLApi.PixelFormat.MONO8 47 | params = [newPixelFormat,] 48 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT, PxLApi.FeatureFlags.MANUAL, params) 49 | if not PxLApi.apiSuccess(ret[0]): 50 | # Nope, so is it color? 51 | newPixelFormat = PxLApi.PixelFormat.BAYER8 52 | params = [newPixelFormat,] 53 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT, PxLApi.FeatureFlags.MANUAL, params) 54 | if PxLApi.apiSuccess(ret[0]): 55 | # Yes, it IS color 56 | pixelType = PT_COLOR 57 | else: 58 | # Yes, it IS mono 59 | pixelType = PT_MONO 60 | 61 | # Restore the saved pixel format 62 | params = [savedPixelFormat,] 63 | PxLApi.setFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT, PxLApi.FeatureFlags.MANUAL, params) 64 | 65 | return pixelType 66 | 67 | 68 | def main(): 69 | # Step 1 70 | # Prepare the camera 71 | 72 | # Initialize any camera 73 | ret = PxLApi.initialize(0) 74 | if not PxLApi.apiSuccess(ret[0]): 75 | print("Error: Unable to initialize a camera") 76 | return EXIT_FAILURE 77 | hCamera = ret[1] 78 | 79 | # Step 2 80 | # Figure out if this is a mono or color camera, so that we know the type of 81 | # image we will be working with. 82 | pixelType = getPixelType(hCamera) 83 | if PT_OTHERWISE == pixelType: 84 | print("Error: We can't deal with this type of camera") 85 | PxLApi.uninitialize(hCamera) 86 | return EXIT_FAILURE 87 | 88 | # Just going to declare a very large buffer here 89 | # One that's large enough for any PixeLINK 4.0 camera 90 | rawFrame = create_string_buffer(5000 * 5000 * 2) 91 | 92 | # Step 3 93 | # Start the stream and Grab an image from the camera. 94 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 95 | if not PxLApi.apiSuccess(ret[0]): 96 | print("Error: Unable to start the stream on the camera") 97 | PxLApi.uninitialize(hCamera) 98 | return EXIT_FAILURE 99 | 100 | ret = PxLApi.getNextFrame(hCamera, rawFrame) 101 | frameDesc = ret[1] 102 | if PxLApi.apiSuccess(ret[0]): 103 | # Convert it to a formatedImage. Note that frame can be in any one of a large number of pixel 104 | # formats, so we will simplify things by converting all mono to mono8, and all color to rgb24 105 | if PT_MONO == pixelType: 106 | ret = PxLApi.formatImage(rawFrame, frameDesc, PxLApi.ImageFormat.RAW_MONO8) 107 | else: 108 | ret = PxLApi.formatImage(rawFrame, frameDesc, PxLApi.ImageFormat.RAW_BGR24) 109 | if PxLApi.apiSuccess(ret[0]): 110 | formatedImage = ret[1] 111 | 112 | # Step 4 113 | # 'convert' the formatedImage buffer to a numpy ndarray that OpenCV can manipulate 114 | npFormatedImage = numpy.full_like(formatedImage, formatedImage, order="C") # a numpy ndarray 115 | npFormatedImage.dtype = numpy.uint8 116 | # Reshape the numpy ndarray into multidimensional array 117 | imageHeight = int(frameDesc.Roi.fHeight) 118 | imageWidth = int(frameDesc.Roi.fWidth) 119 | # color has 3 channels, mono just 1 120 | if PT_MONO == pixelType: 121 | newShape = (imageHeight, imageWidth) 122 | else: 123 | newShape = (imageHeight, imageWidth, 3) 124 | npFormatedImage = numpy.reshape(npFormatedImage, newShape) 125 | 126 | # Step 5 127 | # Do OpenCV manipulations on the numpy ndarray here. 128 | # We will simply use OpenCV to save the image as a BMP 129 | # Create a folder to save snapshots if it does not exist 130 | if not os.path.exists("openCVSnapshot"): 131 | os.makedirs("openCVSnapshot") 132 | 133 | filepath = "openCVSnapshot/" + "snapshot.bmp" 134 | retVal = cv2.imwrite(filepath, npFormatedImage) 135 | if retVal: 136 | print("Saved image to 'openCVSnapshot/snapshot.bmp'") 137 | else: 138 | print("Error: Could not save image to 'openCVSnapshot/snapshot.bmp'") 139 | else: 140 | print("Error: Could not grab an image from the camera") 141 | 142 | # Step 6 143 | # Cleanup 144 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 145 | assert PxLApi.apiSuccess(ret[0]) 146 | ret = PxLApi.uninitialize(hCamera) 147 | assert PxLApi.apiSuccess(ret[0]) 148 | 149 | return EXIT_SUCCESS 150 | 151 | 152 | if __name__ == "__main__": 153 | main() 154 | -------------------------------------------------------------------------------- /samples/Windows/openCVSnapshot.py: -------------------------------------------------------------------------------- 1 | """ 2 | openCVSnapshot.py 3 | 4 | A demonstration of how to capture a camera image that can be 'imported' into openCV. 5 | 6 | OpenCV needs to be installed to run this sample (e.g.: 'pip install opencv-python') 7 | to locate the appropriate libaries. 8 | """ 9 | 10 | from pixelinkWrapper import* 11 | from ctypes import* 12 | import numpy 13 | import cv2 14 | import os 15 | 16 | # A few useful defines 17 | EXIT_SUCCESS = 0 18 | EXIT_FAILURE = 1 19 | 20 | PT_COLOR = 0 21 | PT_MONO = 1 22 | PT_OTHERWISE = 2 # Special cameras, like polarized and interleaved HDR 23 | 24 | """ 25 | IMPORTANT NOTE: 26 | This function will only return a meaningful value, if called while NOT streaming 27 | """ 28 | def getPixelType(hCamera): 29 | 30 | pixelType = PT_OTHERWISE 31 | # Take a simple minded approach; All Pixelink monochrome cameras support PxLApi.PixelFormat.MONO8, and all 32 | # Pixelink color cameas support PxLApi.PixelFormat.BAYER8. So, try setting each of these to see if it 33 | # works. 34 | 35 | # However, we should take care to restore the current pixel format. 36 | savedPixelFormat = 0 37 | newPixelFormat = 0 38 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT) 39 | if not PxLApi.apiSuccess(ret[0]): 40 | return pixelType 41 | 42 | params = ret[2] 43 | savedPixelFormat = int(params[0]) 44 | 45 | # Is it mono? 46 | newPixelFormat = PxLApi.PixelFormat.MONO8 47 | params = [newPixelFormat,] 48 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT, PxLApi.FeatureFlags.MANUAL, params) 49 | if not PxLApi.apiSuccess(ret[0]): 50 | # Nope, so is it color? 51 | newPixelFormat = PxLApi.PixelFormat.BAYER8 52 | params = [newPixelFormat,] 53 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT, PxLApi.FeatureFlags.MANUAL, params) 54 | if PxLApi.apiSuccess(ret[0]): 55 | # Yes, it IS color 56 | pixelType = PT_COLOR 57 | else: 58 | # Yes, it IS mono 59 | pixelType = PT_MONO 60 | 61 | # Restore the saved pixel format 62 | params = [savedPixelFormat,] 63 | PxLApi.setFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT, PxLApi.FeatureFlags.MANUAL, params) 64 | 65 | return pixelType 66 | 67 | 68 | def main(): 69 | # Step 1 70 | # Prepare the camera 71 | 72 | # Initialize any camera 73 | ret = PxLApi.initialize(0) 74 | if not PxLApi.apiSuccess(ret[0]): 75 | print("Error: Unable to initialize a camera") 76 | return EXIT_FAILURE 77 | hCamera = ret[1] 78 | 79 | # Step 2 80 | # Figure out if this is a mono or color camera, so that we know the type of 81 | # image we will be working with. 82 | pixelType = getPixelType(hCamera) 83 | if PT_OTHERWISE == pixelType: 84 | print("Error: We can't deal with this type of camera") 85 | PxLApi.uninitialize(hCamera) 86 | return EXIT_FAILURE 87 | 88 | # Just going to declare a very large buffer here 89 | # One that's large enough for any PixeLINK 4.0 camera 90 | rawFrame = create_string_buffer(5000 * 5000 * 2) 91 | 92 | # Step 3 93 | # Start the stream and Grab an image from the camera. 94 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 95 | if not PxLApi.apiSuccess(ret[0]): 96 | print("Error: Unable to start the stream on the camera") 97 | PxLApi.uninitialize(hCamera) 98 | return EXIT_FAILURE 99 | 100 | ret = PxLApi.getNextFrame(hCamera, rawFrame) 101 | frameDesc = ret[1] 102 | if PxLApi.apiSuccess(ret[0]): 103 | # Convert it to a formatedImage. Note that frame can be in any one of a large number of pixel 104 | # formats, so we will simplify things by converting all mono to mono8, and all color to rgb24 105 | if PT_MONO == pixelType: 106 | ret = PxLApi.formatImage(rawFrame, frameDesc, PxLApi.ImageFormat.RAW_MONO8) 107 | else: 108 | ret = PxLApi.formatImage(rawFrame, frameDesc, PxLApi.ImageFormat.RAW_BGR24) 109 | if PxLApi.apiSuccess(ret[0]): 110 | formatedImage = ret[1] 111 | 112 | # Step 4 113 | # 'convert' the formatedImage buffer to a numpy ndarray that OpenCV can manipulate 114 | npFormatedImage = numpy.full_like(formatedImage, formatedImage, order="C") # a numpy ndarray 115 | npFormatedImage.dtype = numpy.uint8 116 | # Reshape the numpy ndarray into multidimensional array 117 | imageHeight = int(frameDesc.Roi.fHeight) 118 | imageWidth = int(frameDesc.Roi.fWidth) 119 | # color has 3 channels, mono just 1 120 | if PT_MONO == pixelType: 121 | newShape = (imageHeight, imageWidth) 122 | else: 123 | newShape = (imageHeight, imageWidth, 3) 124 | npFormatedImage = numpy.reshape(npFormatedImage, newShape) 125 | 126 | # Step 5 127 | # Do OpenCV manipulations on the numpy ndarray here. 128 | # We will simply use OpenCV to save the image as a BMP 129 | # Create a folder to save snapshots if it does not exist 130 | if not os.path.exists("openCVSnapshot"): 131 | os.makedirs("openCVSnapshot") 132 | 133 | filepath = "openCVSnapshot/" + "snapshot.bmp" 134 | retVal = cv2.imwrite(filepath, npFormatedImage) 135 | if retVal: 136 | print("Saved image to 'openCVSnapshot/snapshot.bmp'") 137 | else: 138 | print("Error: Could not save image to 'openCVSnapshot/snapshot.bmp'") 139 | else: 140 | print("Error: Could not grab an image from the camera") 141 | 142 | # Step 6 143 | # Cleanup 144 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 145 | assert PxLApi.apiSuccess(ret[0]) 146 | ret = PxLApi.uninitialize(hCamera) 147 | assert PxLApi.apiSuccess(ret[0]) 148 | 149 | return EXIT_SUCCESS 150 | 151 | 152 | if __name__ == "__main__": 153 | main() 154 | -------------------------------------------------------------------------------- /samples/Windows/preview.py: -------------------------------------------------------------------------------- 1 | """ 2 | preview.py 3 | 4 | A simple application that previews the camera. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import ctypes.wintypes 10 | import time 11 | import threading 12 | import msvcrt 13 | 14 | """ 15 | Preview control thread function based on the setPreviewState function 16 | """ 17 | def control_preview_thread(hCamera): 18 | 19 | # The preview window will go 'Not Responding' if we do not poll the message pump, and 20 | # forward events onto it's handler on Windows. 21 | user32 = windll.user32 22 | msg = ctypes.wintypes.MSG() 23 | pMsg = ctypes.byref(msg) 24 | 25 | # Start the preview (NOTE: camera must be streaming) 26 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.START) 27 | 28 | while (PxLApi.PreviewState.START == previewState and PxLApi.apiSuccess(ret[0])): 29 | if user32.PeekMessageW(pMsg, 0, 0, 0, 1) != 0: 30 | user32.TranslateMessage(pMsg) 31 | user32.DispatchMessageW(pMsg) 32 | 33 | # Stop the preview 34 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.STOP) 35 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 36 | 37 | """ 38 | Preview control thread function based on the setPreviewStateEx function 39 | """ 40 | def control_preview_thread_with_callback(hCamera): 41 | 42 | context = None 43 | # The preview window will go 'Not Responding' if we do not poll the message pump, and 44 | # forward events onto it's handler on Windows. 45 | user32 = windll.user32 46 | msg = ctypes.wintypes.MSG() 47 | pMsg = ctypes.byref(msg) 48 | 49 | # Start the preview (NOTE: camera must be streaming) 50 | ret = PxLApi.setPreviewStateEx(hCamera, PxLApi.PreviewState.START, context, changeFunction) 51 | 52 | while (PxLApi.PreviewState.START == previewState and PxLApi.apiSuccess(ret[0])): 53 | if user32.PeekMessageW(pMsg, 0, 0, 0, 1) != 0: 54 | user32.TranslateMessage(pMsg) 55 | user32.DispatchMessageW(pMsg) 56 | 57 | # Stop the preview 58 | ret = PxLApi.setPreviewStateEx(hCamera, PxLApi.PreviewState.STOP, context, changeFunction) 59 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 60 | 61 | """ 62 | Creates a new preview thread for each preview run 63 | """ 64 | def create_new_preview_thread(hCamera, withCallback): 65 | if withCallback: 66 | # Creates a thread with preview control based on the setPreviewStateEx function 67 | return threading.Thread(target=control_preview_thread_with_callback, args=(hCamera,), daemon=True) 68 | 69 | # Creates a thread with preview control based on the setPreviewState function 70 | return threading.Thread(target=control_preview_thread, args=(hCamera,), daemon=True) 71 | 72 | """ 73 | Start and stop preview. 74 | Preview gets stopped after a user presses a key. 75 | """ 76 | def set_preview_state(hCamera): 77 | # Controls preview thread 78 | global previewState 79 | 80 | # Declare control preview thread that can control preview and poll the message pump on Windows 81 | previewThread = create_new_preview_thread(hCamera, False) 82 | 83 | # Run preview until the user presses a key.... 84 | previewState = PxLApi.PreviewState.START 85 | previewThread.start() 86 | print("Press any key to stop preview......") 87 | kbHit() 88 | previewState = PxLApi.PreviewState.STOP 89 | # Give preview time to stop 90 | time.sleep(0.05) 91 | 92 | """ 93 | Start and stop preview using setPreviewStateEx with a callback function. 94 | Preview gets stopped after a user presses a key 95 | """ 96 | def set_preview_state_ex(hCamera): 97 | # Controls preview thread 98 | global previewState 99 | 100 | # Declare control preview thread that can control preview and poll the message pump on Windows 101 | previewThread = create_new_preview_thread(hCamera, True) 102 | 103 | # Run the preview until the user presses a key.... 104 | previewState = PxLApi.PreviewState.START 105 | previewThread.start() 106 | print("Press any key to stop preview with callback and exit.......") 107 | kbHit() 108 | previewState = PxLApi.PreviewState.STOP 109 | # Give preview time to stop 110 | time.sleep(0.05) 111 | 112 | 113 | def main(): 114 | 115 | # Grab the first camera we find 116 | ret = PxLApi.initialize(0) 117 | if PxLApi.apiSuccess(ret[0]): 118 | hCamera = ret[1] 119 | 120 | # Just use all of the camer's default settings. 121 | # Start the stream 122 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 123 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 124 | 125 | # Start and stop preview using setPreviewState 126 | set_preview_state(hCamera) 127 | 128 | # Run the preview until the user presses a key.... 129 | print("Press any key to start preview with callback......") 130 | kbHit() 131 | 132 | # Start and stop preview using setPreviewStateEx 133 | set_preview_state_ex(hCamera) 134 | 135 | # Stop the stream 136 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 137 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 138 | 139 | # Uninitialize the camera now that we're done with it. 140 | PxLApi.uninitialize(hCamera) 141 | 142 | return 0 143 | 144 | """ 145 | Unbuffered keyboard input on command line. 146 | Keyboard input will be passed to the application without the user pressing 147 | the enter key. 148 | Note: IDLE does not support this functionality. 149 | """ 150 | def kbHit(): 151 | return msvcrt.getch() 152 | 153 | """ 154 | Callback function for setPreviewStateEx 155 | """ 156 | @PxLApi._changeFunction 157 | def changeFunction(hCamera, changeCode, context): 158 | print("Callback function executed with changeCode = %i " % changeCode) 159 | return 0 160 | 161 | 162 | if __name__ == "__main__": 163 | previewState = PxLApi.PreviewState.STOP # control preview thread 164 | main() 165 | -------------------------------------------------------------------------------- /samples/Linux/frameActions.py: -------------------------------------------------------------------------------- 1 | """ 2 | frameActions.py 3 | 4 | Demonstration application showing how to use Frame Action type Triggering 5 | 6 | Frame action triggering is particularly useful when you need to grab images 7 | from multiple cameras simultanesouly -- either at a time as directed by 8 | a host appliction (kind of like a multi-camera software trigger), or at 9 | a user specified time. 10 | 11 | This particular example requires there be 2 or more cameras connected, and 12 | that these cameras support PTP (Percersion Time Protocol V2, AKA IEEE1588), and 13 | that the time is synchronized between the cameras (all cameras are either a PTP 14 | Master or Slave). 15 | """ 16 | 17 | from pixelinkWrapper import* 18 | import time 19 | 20 | EXIT_SUCCESS = 0 21 | EXIT_FAILURE = 1 22 | 23 | ACTION_DELAY = 5.0 # 5 seconds 24 | 25 | @PxLApi._dataProcessFunction 26 | def frame_callback_func(hCamera, frameData, dataFormat, frameDesc, userData): 27 | 28 | # We will print out the frame time. If all of the cameras are identically configured, then the 29 | # frame time of each of the images should be identical. However, if the cameras are of different 30 | # models, or are configured differently, then the frame time will vary. The frame time is 31 | # 'latched' as the first pixel of the image is received from the imaging sensor, which 32 | # would be after the camera's exposure (AKA shutter) time. 33 | # 34 | # For example, say we had 2 identical models of camera, each configured identically except for 35 | # exposure; Camera A is using an exposure of 20 ms, while camera B is using an exposure of 120 ms. 36 | # In this example, you can expect the timestamps of the images returned from camera A and camera B 37 | # to differ by 100 ms. 38 | 39 | # Copy frame descriptor information 40 | frameDescriptor = frameDesc.contents 41 | print(" FrameCallbackFunction: camera=%d, exposure=%6.2f (ms) frameTime=%6.3f" % 42 | (gSerials[hCamera], frameDescriptor.Shutter.fValue * 1000, frameDescriptor.dFrameTime)) 43 | return PxLApi.ReturnCode.ApiSuccess 44 | 45 | 46 | def ptp_synchronized(hCamera): 47 | 48 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PTP) 49 | if PxLApi.apiSuccess(ret[0]): 50 | ptpParams = ret[2] 51 | if (ptpParams[PxLApi.PtpParams.STATUS] == PxLApi.PtpStatus.MASTER or \ 52 | ptpParams[PxLApi.PtpParams.STATUS] == PxLApi.PtpStatus.SLAVE): 53 | return True 54 | 55 | return False 56 | 57 | 58 | def main(): 59 | 60 | numPtpSynchedCameras = 0 61 | 62 | # Step 1 63 | # Ensure there at least 2 cameras connected 64 | ret = PxLApi.getNumberCameras() 65 | if not PxLApi.apiSuccess(ret[0]): 66 | print("ERROR: Could not find any cameras (%d)" % ret[0]) 67 | return EXIT_FAILURE 68 | 69 | numCameras = ret[1] 70 | if len(numCameras) < 2: 71 | print("ERROR: There must be at least 2 cameras connected") 72 | return EXIT_FAILURE 73 | 74 | triggerParams = [0] * PxLApi.TriggerParams.NUM_PARAMS 75 | 76 | # For each of the ptp synchronized cameras... 77 | myCameras = list() 78 | for cameraIdInfo in numCameras: 79 | 80 | # Step 2 81 | # Initialize the camera, and check to see if it is PTP synchronized 82 | ret = PxLApi.initialize(cameraIdInfo.CameraSerialNum) 83 | if PxLApi.apiSuccess(ret[0]): 84 | hCamera = ret[1] 85 | 86 | if ptp_synchronized(hCamera): 87 | numPtpSynchedCameras += 1 88 | gSerials.__setitem__(hCamera, cameraIdInfo.CameraSerialNum) 89 | 90 | # Step 3 91 | # Register a frame callback for this camera 92 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, 0, frame_callback_func) 93 | if not PxLApi.apiSuccess(ret[0]): # Error handling 94 | print("PxLSetCallback rc:%d" % ret[0]) 95 | 96 | # Step 4 97 | # Set up a Frame Action Trigger 98 | triggerParams[PxLApi.TriggerParams.TYPE] = PxLApi.TriggerTypes.ACTION 99 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.TRIGGER, PxLApi.FeatureFlags.MANUAL, triggerParams) 100 | if not PxLApi.apiSuccess(ret[0]): # Error handling 101 | print("PxLSetFeature Trigger rc:%d" % ret[0]) 102 | 103 | # Step 5 104 | # Start the stream 105 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 106 | 107 | myCameras.append(hCamera) # 'remember' this camera 108 | 109 | print("Found %d PTP synched cameras" % numPtpSynchedCameras) 110 | 111 | # Step 6 112 | # All ptp synchronized cameras are waiting for a frame event -- send one now. 113 | print(" You should see one image from each of %d cameras, immediatly..." % numPtpSynchedCameras) 114 | ret = PxLApi.setActions(PxLApi.ActionTypes.FRAME_TRIGGER, 0) 115 | 116 | # Step 7 117 | # All ptp synchronized cameras are waiting for a frame event -- send one that matures in ACTION_DELAY seconds. 118 | print(" You should see one image from each of %d cameras, after %3.1f seconds..." % (numPtpSynchedCameras, ACTION_DELAY)) 119 | ret = PxLApi.getCurrentTimestamp(hCamera) 120 | 121 | if PxLApi.apiSuccess(ret[0]): 122 | currentTime = ret[1] 123 | ret = PxLApi.setActions(PxLApi.ActionTypes.FRAME_TRIGGER, currentTime+ACTION_DELAY) 124 | 125 | # Delay waiting for the action 126 | time.sleep(ACTION_DELAY*2) 127 | 128 | # Step 8 129 | # Cleanup 130 | for i in range(len(myCameras)): 131 | PxLApi.setStreamState(myCameras[i], PxLApi.StreamState.STOP) 132 | PxLApi.setFeature(myCameras[i], PxLApi.FeatureId.TRIGGER, PxLApi.FeatureFlags.OFF, triggerParams) 133 | PxLApi.uninitialize(myCameras[i]) 134 | 135 | return EXIT_SUCCESS 136 | 137 | if __name__ == "__main__": 138 | # Use a global dictionary to keep track of camera serail numbers (by camera handle) 139 | gSerials = dict() 140 | main() 141 | -------------------------------------------------------------------------------- /samples/Windows/frameActions.py: -------------------------------------------------------------------------------- 1 | """ 2 | frameActions.py 3 | 4 | Demonstration application showing how to use Frame Action type Triggering 5 | 6 | Frame action triggering is particularly useful when you need to grab images 7 | from multiple cameras simultanesouly -- either at a time as directed by 8 | a host appliction (kind of like a multi-camera software trigger), or at 9 | a user specified time. 10 | 11 | This particular example requires there be 2 or more cameras connected, and 12 | that these cameras support PTP (Percersion Time Protocol V2, AKA IEEE1588), and 13 | that the time is synchronized between the cameras (all cameras are either a PTP 14 | Master or Slave). 15 | """ 16 | 17 | from pixelinkWrapper import* 18 | import time 19 | 20 | EXIT_SUCCESS = 0 21 | EXIT_FAILURE = 1 22 | 23 | ACTION_DELAY = 5.0 # 5 seconds 24 | 25 | @PxLApi._dataProcessFunction 26 | def frame_callback_func(hCamera, frameData, dataFormat, frameDesc, userData): 27 | 28 | # We will print out the frame time. If all of the cameras are identically configured, then the 29 | # frame time of each of the images should be identical. However, if the cameras are of different 30 | # models, or are configured differently, then the frame time will vary. The frame time is 31 | # 'latched' as the first pixel of the image is received from the imaging sensor, which 32 | # would be after the camera's exposure (AKA shutter) time. 33 | # 34 | # For example, say we had 2 identical models of camera, each configured identically except for 35 | # exposure; Camera A is using an exposure of 20 ms, while camera B is using an exposure of 120 ms. 36 | # In this example, you can expect the timestamps of the images returned from camera A and camera B 37 | # to differ by 100 ms. 38 | 39 | # Copy frame descriptor information 40 | frameDescriptor = frameDesc.contents 41 | print(" FrameCallbackFunction: camera=%d, exposure=%6.2f (ms) frameTime=%6.3f" % 42 | (gSerials[hCamera], frameDescriptor.Shutter.fValue * 1000, frameDescriptor.dFrameTime)) 43 | return PxLApi.ReturnCode.ApiSuccess 44 | 45 | 46 | def ptp_synchronized(hCamera): 47 | 48 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PTP) 49 | if PxLApi.apiSuccess(ret[0]): 50 | ptpParams = ret[2] 51 | if (ptpParams[PxLApi.PtpParams.STATUS] == PxLApi.PtpStatus.MASTER or \ 52 | ptpParams[PxLApi.PtpParams.STATUS] == PxLApi.PtpStatus.SLAVE): 53 | return True 54 | 55 | return False 56 | 57 | 58 | def main(): 59 | 60 | numPtpSynchedCameras = 0 61 | 62 | # Step 1 63 | # Ensure there at least 2 cameras connected 64 | ret = PxLApi.getNumberCameras() 65 | if not PxLApi.apiSuccess(ret[0]): 66 | print("ERROR: Could not find any cameras (%d)" % ret[0]) 67 | return EXIT_FAILURE 68 | 69 | numCameras = ret[1] 70 | if len(numCameras) < 2: 71 | print("ERROR: There must be at least 2 cameras connected") 72 | return EXIT_FAILURE 73 | 74 | triggerParams = [0] * PxLApi.TriggerParams.NUM_PARAMS 75 | 76 | # For each of the ptp synchronized cameras... 77 | myCameras = list() 78 | for cameraIdInfo in numCameras: 79 | 80 | # Step 2 81 | # Initialize the camera, and check to see if it is PTP synchronized 82 | ret = PxLApi.initialize(cameraIdInfo.CameraSerialNum) 83 | if PxLApi.apiSuccess(ret[0]): 84 | hCamera = ret[1] 85 | 86 | if ptp_synchronized(hCamera): 87 | numPtpSynchedCameras += 1 88 | gSerials.__setitem__(hCamera, cameraIdInfo.CameraSerialNum) 89 | 90 | # Step 3 91 | # Register a frame callback for this camera 92 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, 0, frame_callback_func) 93 | if not PxLApi.apiSuccess(ret[0]): # Error handling 94 | print("PxLSetCallback rc:%d" % ret[0]) 95 | 96 | # Step 4 97 | # Set up a Frame Action Trigger 98 | triggerParams[PxLApi.TriggerParams.TYPE] = PxLApi.TriggerTypes.ACTION 99 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.TRIGGER, PxLApi.FeatureFlags.MANUAL, triggerParams) 100 | if not PxLApi.apiSuccess(ret[0]): # Error handling 101 | print("PxLSetFeature Trigger rc:%d" % ret[0]) 102 | 103 | # Step 5 104 | # Start the stream 105 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 106 | 107 | myCameras.append(hCamera) # 'remember' this camera 108 | 109 | print("Found %d PTP synched cameras" % numPtpSynchedCameras) 110 | 111 | # Step 6 112 | # All ptp synchronized cameras are waiting for a frame event -- send one now. 113 | print(" You should see one image from each of %d cameras, immediatly..." % numPtpSynchedCameras) 114 | ret = PxLApi.setActions(PxLApi.ActionTypes.FRAME_TRIGGER, 0) 115 | 116 | # Step 7 117 | # All ptp synchronized cameras are waiting for a frame event -- send one that matures in ACTION_DELAY seconds. 118 | print(" You should see one image from each of %d cameras, after %3.1f seconds..." % (numPtpSynchedCameras, ACTION_DELAY)) 119 | ret = PxLApi.getCurrentTimestamp(hCamera) 120 | 121 | if PxLApi.apiSuccess(ret[0]): 122 | currentTime = ret[1] 123 | ret = PxLApi.setActions(PxLApi.ActionTypes.FRAME_TRIGGER, currentTime+ACTION_DELAY) 124 | 125 | # Delay waiting for the action 126 | time.sleep(ACTION_DELAY*2) 127 | 128 | # Step 8 129 | # Cleanup 130 | for i in range(len(myCameras)): 131 | PxLApi.setStreamState(myCameras[i], PxLApi.StreamState.STOP) 132 | PxLApi.setFeature(myCameras[i], PxLApi.FeatureId.TRIGGER, PxLApi.FeatureFlags.OFF, triggerParams) 133 | PxLApi.uninitialize(myCameras[i]) 134 | 135 | return EXIT_SUCCESS 136 | 137 | if __name__ == "__main__": 138 | # Use a global dictionary to keep track of camera serail numbers (by camera handle) 139 | gSerials = dict() 140 | main() 141 | -------------------------------------------------------------------------------- /samples/Windows/saveSettings.py: -------------------------------------------------------------------------------- 1 | """ 2 | saveSettings.py 3 | 4 | This demonstrates how save camera settings in non-volatile store, as well as restoring 5 | a camera back to using its factory default settings. 6 | 7 | More specifically, is howcases how to use: 8 | - PxLApi.saveSettings 9 | - PxLApi.loadSettings 10 | 11 | NOTE: This application assumes there is at most, one Pixelink camera connected to the system 12 | """ 13 | 14 | from pixelinkWrapper import* 15 | import msvcrt 16 | import time 17 | 18 | # A few useful constants 19 | WAIT_TIME = 30 # total wait time for a camera to finish a power cycle (in seconds) 20 | POLL_INTERVAL = 1 # Time between polls to see if a camera has finished a power cycle (in seconds) 21 | 22 | 23 | def main(): 24 | 25 | # Step 1 26 | # Find, and initialize, a camera 27 | ret = PxLApi.initialize(0) 28 | if not(PxLApi.apiSuccess(ret[0])): 29 | print("Could not Initialize the camera! rc = %i" % ret[0]) 30 | return 1 31 | hCamera = ret[1] 32 | 33 | print("\nWARNING: This application will restore the connected camera back to it's factory default settings") 34 | print(" Ok to proceed (y/n)? ") 35 | 36 | keyPressed = kbHit() 37 | 38 | if 'y' != keyPressed and 'Y' != keyPressed: 39 | # User aborted. 40 | PxLApi.uninitialize(hCamera) 41 | return 1 42 | 43 | # Step 2 44 | # Restore the camera back to it's factory default settings, and report the expsoure 45 | ret = PxLApi.loadSettings(hCamera, PxLApi.Settings.SETTINGS_FACTORY) 46 | assert PxLApi.apiSuccess(ret[0]) 47 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 48 | assert PxLApi.apiSuccess(ret[0]) 49 | params = ret[2] 50 | factoryDefaultExposure = params[0] 51 | print(" Exposure: %5.2f ms <-- factory default value." % (factoryDefaultExposure*1000)) 52 | 53 | # Step 3 54 | # Change the exposure. We'll choose a value that is 10% longer, and save the camera settings 55 | # to non-volatile store. 56 | currentExposure = factoryDefaultExposure * 1.1 57 | params[0] = currentExposure 58 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.EXPOSURE, PxLApi.FeatureFlags.MANUAL, params) 59 | assert PxLApi.apiSuccess(ret[0]) 60 | ret = PxLApi.saveSettings(hCamera, PxLApi.Settings.SETTINGS_USER) 61 | assert PxLApi.apiSuccess(ret[0]) 62 | 63 | # Step 4 64 | # Have the user power cycle the camera. 65 | # Do an uninitialize of the camera first, so some cleanup can be done. 66 | PxLApi.uninitialize(hCamera) 67 | print(" Exposure: %5.2f ms <-- user set value. Please power cycle the camera. Press a key " 68 | "when you are done." % (currentExposure*1000), flush=True) 69 | kbHit() 70 | print("\nWaiting for the camera to finish initializing", end="", flush=True) 71 | 72 | # Step 5 73 | # Wait for the camera to reappear, but don't wait forever 74 | waitTime = 0 75 | while waitTime < WAIT_TIME: 76 | ret = PxLApi.initialize(0) 77 | if PxLApi.apiSuccess(ret[0]): 78 | hCamera = ret[1] 79 | break 80 | print(".", end="", flush=True) 81 | # Recheck for the camera from time to time 82 | waitTime += POLL_INTERVAL 83 | time.sleep(POLL_INTERVAL) 84 | print("done") 85 | assert waitTime < WAIT_TIME 86 | 87 | # Step 6 88 | # Report the camera's exposure. It should still be the user set value 89 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 90 | assert PxLApi.apiSuccess(ret[0]) 91 | params = ret[2] 92 | currentExposure = params[0] 93 | print(" Exposure: %5.2f ms <-- non-volatile user set value." % (currentExposure*1000)) 94 | assert currentExposure != factoryDefaultExposure 95 | 96 | # Step 7 97 | # Restore the camera back to factory defaults, and then save these defaults to non-volatile store. 98 | ret = PxLApi.loadSettings(hCamera, PxLApi.Settings.SETTINGS_FACTORY) 99 | assert PxLApi.apiSuccess(ret[0]) 100 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 101 | assert PxLApi.apiSuccess(ret[0]) 102 | params = ret[2] 103 | factoryDefaultExposure = params[0] 104 | ret = PxLApi.saveSettings(hCamera, PxLApi.Settings.SETTINGS_USER) 105 | assert PxLApi.apiSuccess(ret[0]) 106 | 107 | # Step 8 108 | # Have the user power cycle the camera. 109 | # Do an uninitialize of the camera first, so some cleanup can be done. 110 | PxLApi.uninitialize(hCamera) 111 | print(" Exposure: %5.2f ms <-- factory default value. Please power cycle the camera and press a key " 112 | "when you are done. " % (factoryDefaultExposure*1000), flush=True) 113 | kbHit() 114 | print("\nWaiting for the camera to finish initializing", end="", flush=True) 115 | 116 | # Step 9 117 | # Wait for the camera to reappear, but don't wait forever 118 | waitTime = 0 119 | while waitTime < WAIT_TIME: 120 | ret = PxLApi.initialize(0) 121 | if PxLApi.apiSuccess(ret[0]): 122 | hCamera = ret[1] 123 | break 124 | print(".", end="", flush=True) 125 | # Recheck for the camera from time to time 126 | waitTime += POLL_INTERVAL 127 | time.sleep(POLL_INTERVAL) 128 | print("done") 129 | assert waitTime < WAIT_TIME 130 | 131 | # Step 10 132 | # Report the camera's exposure. It should still be the factory default value again 133 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 134 | assert PxLApi.apiSuccess(ret[0]) 135 | params = ret[2] 136 | currentExposure = params[0] 137 | print(" Exposure: %5.2f ms <-- non-volatile factory default value." % (currentExposure*1000)) 138 | assert currentExposure == factoryDefaultExposure 139 | 140 | # Step 11 141 | # Done. 142 | PxLApi.uninitialize(hCamera) 143 | 144 | return 0 145 | 146 | """ 147 | Unbuffered keyboard input on command line. 148 | Keyboard input will be passed to the application without the user pressing 149 | the enter key. 150 | Note: IDLE does not support this functionality. 151 | """ 152 | def kbHit(): 153 | keyPressed = msvcrt.getch() 154 | if b'\xe0' == keyPressed: 155 | return str(keyPressed) 156 | return str(keyPressed, "utf-8") 157 | 158 | if __name__ == "__main__": 159 | main() 160 | -------------------------------------------------------------------------------- /samples/Linux/saveSettings.py: -------------------------------------------------------------------------------- 1 | """ 2 | saveSettings.py 3 | 4 | This demonstrates how save camera settings in non-volatile store, as well as restoring 5 | a camera back to using its factory default settings. 6 | 7 | More specifically, is howcases how to use: 8 | - PxLApi.saveSettings 9 | - PxLApi.loadSettings 10 | 11 | NOTE: This application assumes there is at most, one Pixelink camera connected to the system 12 | """ 13 | 14 | from pixelinkWrapper import* 15 | import time 16 | import sys 17 | import tty 18 | import termios 19 | 20 | # A few useful constants 21 | WAIT_TIME = 30 # total wait time for a camera to finish a power cycle (in seconds) 22 | POLL_INTERVAL = 1 # Time between polls to see if a camera has finished a power cycle (in seconds) 23 | 24 | 25 | def main(): 26 | 27 | # Step 1 28 | # Find, and initialize, a camera 29 | ret = PxLApi.initialize(0) 30 | if not(PxLApi.apiSuccess(ret[0])): 31 | print("Could not Initialize the camera! rc = %i" % ret[0]) 32 | return 1 33 | hCamera = ret[1] 34 | 35 | print("\nWARNING: This application will restore the connected camera back to it's factory default settings") 36 | print(" Ok to proceed (y/n)? ") 37 | 38 | keyPressed = kbHit() 39 | 40 | if 'y' != keyPressed and 'Y' != keyPressed: 41 | # User aborted. 42 | PxLApi.uninitialize(hCamera) 43 | return 1 44 | 45 | # Step 2 46 | # Restore the camera back to it's factory default settings, and report the expsoure 47 | ret = PxLApi.loadSettings(hCamera, PxLApi.Settings.SETTINGS_FACTORY) 48 | assert PxLApi.apiSuccess(ret[0]) 49 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 50 | assert PxLApi.apiSuccess(ret[0]) 51 | params = ret[2] 52 | factoryDefaultExposure = params[0] 53 | print(" Exposure: %5.2f ms <-- factory default value." % (factoryDefaultExposure*1000)) 54 | 55 | # Step 3 56 | # Change the exposure. We'll choose a value that is 10% longer, and save the camera settings 57 | # to non-volatile store. 58 | currentExposure = factoryDefaultExposure * 1.1 59 | params[0] = currentExposure 60 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.EXPOSURE, PxLApi.FeatureFlags.MANUAL, params) 61 | assert PxLApi.apiSuccess(ret[0]) 62 | ret = PxLApi.saveSettings(hCamera, PxLApi.Settings.SETTINGS_USER) 63 | assert PxLApi.apiSuccess(ret[0]) 64 | 65 | # Step 4 66 | # Have the user power cycle the camera. 67 | # Do an uninitialize of the camera first, so some cleanup can be done. 68 | PxLApi.uninitialize(hCamera) 69 | print(" Exposure: %5.2f ms <-- user set value. Please power cycle the camera. Press a key " 70 | "when you are done." % (currentExposure*1000), flush=True) 71 | kbHit() 72 | print("\nWaiting for the camera to finish initializing..", end="", flush=True) 73 | 74 | # Step 5 75 | # Wait for the camera to reappear, but don't wait forever 76 | waitTime = 0 77 | while waitTime < WAIT_TIME: 78 | ret = PxLApi.initialize(0) 79 | if PxLApi.apiSuccess(ret[0]): 80 | hCamera = ret[1] 81 | break 82 | print(".", end="", flush=True) 83 | # Recheck for the camera from time to time 84 | waitTime += POLL_INTERVAL 85 | time.sleep(POLL_INTERVAL) 86 | print("done") 87 | assert waitTime < WAIT_TIME 88 | 89 | # Step 6 90 | # Report the camera's exposure. It should still be the user set value 91 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 92 | assert PxLApi.apiSuccess(ret[0]) 93 | params = ret[2] 94 | currentExposure = params[0] 95 | print(" Exposure: %5.2f ms <-- non-volatile user set value." % (currentExposure*1000)) 96 | assert currentExposure != factoryDefaultExposure 97 | 98 | # Step 7 99 | # Restore the camera back to factory defaults, and then save these defaults to non-volatile store. 100 | ret = PxLApi.loadSettings(hCamera, PxLApi.Settings.SETTINGS_FACTORY) 101 | assert PxLApi.apiSuccess(ret[0]) 102 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 103 | assert PxLApi.apiSuccess(ret[0]) 104 | params = ret[2] 105 | factoryDefaultExposure = params[0] 106 | ret = PxLApi.saveSettings(hCamera, PxLApi.Settings.SETTINGS_USER) 107 | assert PxLApi.apiSuccess(ret[0]) 108 | 109 | # Step 8 110 | # Have the user power cycle the camera. 111 | # Do an uninitialize of the camera first, so some cleanup can be done. 112 | PxLApi.uninitialize(hCamera) 113 | print(" Exposure: %5.2f ms <-- factory default value. Please power cycle the camera and press a key " 114 | "when you are done. " % (factoryDefaultExposure*1000), flush=True) 115 | kbHit() 116 | print("\nWaiting for the camera to finish initializing..", end="", flush=True) 117 | 118 | # Step 9 119 | # Wait for the camera to reappear, but don't wait forever 120 | waitTime = 0 121 | while waitTime < WAIT_TIME: 122 | ret = PxLApi.initialize(0) 123 | if PxLApi.apiSuccess(ret[0]): 124 | hCamera = ret[1] 125 | break 126 | print(".", end="", flush=True) 127 | # Recheck for the camera from time to time 128 | waitTime += POLL_INTERVAL 129 | time.sleep(POLL_INTERVAL) 130 | print("done") 131 | assert waitTime < WAIT_TIME 132 | 133 | # Step 10 134 | # Report the camera's exposure. It should still be the factory default value again 135 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.EXPOSURE) 136 | assert PxLApi.apiSuccess(ret[0]) 137 | params = ret[2] 138 | currentExposure = params[0] 139 | print(" Exposure: %5.2f ms <-- non-volatile factory default value." % (currentExposure*1000)) 140 | assert currentExposure == factoryDefaultExposure 141 | 142 | # Step 11 143 | # Done. 144 | PxLApi.uninitialize(hCamera) 145 | 146 | return 0 147 | 148 | """ 149 | Unbuffered keyboard input on command line. 150 | Keyboard input will be passed to the application without the user pressing 151 | the enter key. 152 | Note: IDLE does not support this functionality. 153 | """ 154 | def kbHit(): 155 | fd = sys.stdin.fileno() 156 | old_settings = termios.tcgetattr(fd) 157 | try: 158 | tty.setraw(sys.stdin.fileno()) 159 | ch = sys.stdin.read(1) 160 | finally: 161 | termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 162 | return ch 163 | 164 | 165 | if __name__ == "__main__": 166 | main() 167 | -------------------------------------------------------------------------------- /samples/Windows/previewWithPyQt5.py: -------------------------------------------------------------------------------- 1 | """ 2 | previewWithPyQt5.py 3 | 4 | Simple sample application demonstrating the use of the API Preview function, 5 | embedded within a PyQt5 windows 6 | 7 | PyQt5 needs to be installed to run this sample (e.g.: 'pip install PyQt5') 8 | to locate the appropriate libaries. 9 | """ 10 | from pixelinkWrapper import* 11 | from ctypes import* 12 | import ctypes.wintypes 13 | import threading 14 | import time 15 | import sys 16 | 17 | from PyQt5.QtWidgets import QApplication 18 | from PyQt5.QtWidgets import QMainWindow 19 | from PyQt5.QtWidgets import QWidget 20 | from PyQt5.QtWidgets import QMenu 21 | from PyQt5.QtWidgets import QAction 22 | from PyQt5.QtCore import QThread 23 | 24 | """ 25 | PyQt5 top-level window with a menu bar and a preview window 26 | """ 27 | class MainWindow(QMainWindow): 28 | # Create our top-level window with a menu bar and a preview window 29 | def __init__(self, parent=None): 30 | # Initializer 31 | super().__init__(parent) 32 | # Main Window's properties 33 | self.setWindowTitle("PixelinkPreview") 34 | self.setGeometry(0, 0, 1024, 768) 35 | # Create and set the central widget as 36 | self.previewWindow = PreviewWindow(self) 37 | self.setCentralWidget(self.previewWindow) 38 | # Set the menu bar with actions 39 | self._createActions() 40 | self._createMenuBar() 41 | # Start using the camera 42 | self._startCamera() 43 | 44 | def _createActions(self): 45 | self.exitAction = QAction("&Exit", self) 46 | self.exitAction.triggered.connect(self.exitApp) 47 | 48 | def _createMenuBar(self): 49 | menuBar = self.menuBar() 50 | fileMenu = menuBar.addMenu("&File") 51 | fileMenu.addAction(self.exitAction) 52 | 53 | def _startCamera(self): 54 | # Set up the camera and start the stream 55 | ret = PxLApi.initialize(0) 56 | if PxLApi.apiSuccess(ret[0]): 57 | self.hCamera = ret[1] 58 | # Just use all of the camera's current settings. 59 | # Start the stream and preview 60 | ret = PxLApi.setStreamState(self.hCamera, PxLApi.StreamState.START) 61 | if PxLApi.apiSuccess(ret[0]): 62 | self._startPreview() 63 | 64 | # Start preview (with message pump). Preview gets stopped when the top level window is closed. 65 | def _startPreview(self): 66 | self.previewWindow.previewState = PxLApi.PreviewState.START 67 | self.previewWindow.previewThread.start() 68 | 69 | def _stopCamera(self): 70 | # The user has quit the appliation, shut down the preview and stream 71 | self.previewWindow.previewState = PxLApi.PreviewState.STOP 72 | # Give preview a bit of time to stop 73 | time.sleep(0.05) 74 | 75 | PxLApi.setStreamState(self.hCamera, PxLApi.StreamState.STOP) 76 | 77 | PxLApi.uninitialize(self.hCamera) 78 | 79 | def exitApp(self): 80 | self.close() 81 | 82 | def closeEvent(self, event): 83 | # The user has quit the application, stop using the camera 84 | self._stopCamera() 85 | return super().closeEvent(event) 86 | 87 | """ 88 | PyQt5 Preview window with the API preview control 89 | """ 90 | class PreviewWindow(QWidget): 91 | 92 | def __init__(self, parent=None): 93 | super().__init__(parent) 94 | self.mainWindow = parent 95 | self.winId = int(self.winId()) 96 | self.previewState = PxLApi.PreviewState.STOP # default preview state 97 | self.previewThread = ControlPreview(self) 98 | 99 | # Window resize handler 100 | def resizeEvent(self, event): 101 | # The user has resized the window. Also resize the preview so that the preview will scale to the new window size 102 | hCamera = self.mainWindow.hCamera 103 | width = event.size().width() 104 | height = event.size().height() 105 | previewHwnd = self.winId 106 | PxLApi.setPreviewSettings(hCamera, "", PxLApi.WindowsPreview.WS_VISIBLE | PxLApi.WindowsPreview.WS_CHILD , 0, 0, width, height, previewHwnd) 107 | 108 | 109 | """ 110 | Preview control QThread -- starts and stops the preview, as well as handles the Windows Dispatch 111 | of the preview window. 112 | """ 113 | class ControlPreview(QThread): 114 | 115 | def __init__(self, parent=None): 116 | super().__init__() 117 | self.previewWindow = parent 118 | 119 | def run(self): 120 | # Run preview function 121 | self._runPreview() 122 | 123 | def _runPreview(self): 124 | user32 = windll.user32 125 | msg = ctypes.wintypes.MSG() 126 | pMsg = ctypes.byref(msg) 127 | 128 | # Get the current dimensions of the Preview Window 129 | hCamera = self.previewWindow.mainWindow.hCamera 130 | width = self.previewWindow.size().width() 131 | height = self.previewWindow.size().height() 132 | previewHwnd = self.previewWindow.winId 133 | 134 | # Start the stream in case the camera is not streaming 135 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 136 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 137 | 138 | # Set preview settings 139 | ret = PxLApi.setPreviewSettings(hCamera, "", PxLApi.WindowsPreview.WS_VISIBLE | PxLApi.WindowsPreview.WS_CHILD, 140 | 0, 0, width, height, previewHwnd) 141 | 142 | # Start the preview (NOTE: camera must be streaming). Keep looping until the previewState is STOPed 143 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.START) 144 | while (PxLApi.PreviewState.START == self.previewWindow.previewState and PxLApi.apiSuccess(ret[0])): 145 | if user32.PeekMessageW(pMsg, 0, 0, 0, 1) != 0: 146 | # All messages are simlpy forwarded onto to other Win32 event handlers. However, we do 147 | # set the cursor just to ensure that parent windows resize cursors do not persist within 148 | # the preview window 149 | user32.TranslateMessage(pMsg) 150 | user32.DispatchMessageW(pMsg) 151 | 152 | # User has exited -- Stop the preview 153 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.STOP) 154 | assert PxLApi.apiSuccess(ret[0]), "%i" % ret[0] 155 | 156 | 157 | if __name__ == '__main__': 158 | app = QApplication(sys.argv) 159 | mainWin = MainWindow() 160 | mainWin.show() 161 | sys.exit(app.exec_()) 162 | -------------------------------------------------------------------------------- /samples/Linux/softwareTriggerWithCallback.py: -------------------------------------------------------------------------------- 1 | """ 2 | softwareTriggerWithCallback.py 3 | 4 | A demonstration of a special software triggering mode. 5 | 6 | With normal software triggering on Pixelink cameras, a call to PxLApi.getNextFrame will cause the API to: 7 | 8 | 1) notify the camera to take an image 9 | 2) wait until the image is returned. 10 | 3) return the image 11 | 12 | If the camera were configured to have a 10 second exposure, the thread calling PxLApi.getNextFrame would be blocked 13 | inside PxLApi.getNextFrame for the entire 10 seconds. 14 | 15 | By using callbacks and calling PxLApi.getNextFrame in a special way, it's possible to emulate a hardware trigger. 16 | Calling PxLApi.getNextFrame with a None or 0 frame buffer: 17 | 18 | 1) notify the camera to take an image. 19 | 20 | and that's it. How do you get the image? It will be handed to you in an PxLApi.Callback.FRAME callback. 21 | 22 | Using this technique, it's possible to sofware trigger multiple cameras reasonably simultaneously. 23 | This technique is demonstrated here. 24 | 25 | This application will detect and connect to all PixeLINK 4.0 cameras, configure each for software triggering 26 | (assuming all cameras support triggering), set them all streaming, and then software trigger them at 27 | regular intervals. 28 | """ 29 | 30 | from pixelinkWrapper import* 31 | import threading 32 | import time 33 | 34 | SUCCESS = 0 35 | FAILURE = 1 36 | 37 | 38 | def prepare_camera_for_test(hCamera): 39 | 40 | ret = set_up_software_triggering(hCamera) 41 | if PxLApi.apiSuccess(ret[0]): 42 | # Set up PxLApi.Callback.FRAME callbacks for this camera 43 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, 0, image_callback_function) 44 | if PxLApi.apiSuccess(ret[0]): 45 | return PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 46 | return ret 47 | 48 | """ 49 | Given a camera handle, configure the camera for software triggering. 50 | """ 51 | def set_up_software_triggering(hCamera): 52 | 53 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.TRIGGER) 54 | if PxLApi.apiSuccess(ret[0]): 55 | assert len(ret[2]) >= PxLApi.TriggerParams.NUM_PARAMS 56 | 57 | flags = ret[1] 58 | params = ret[2] 59 | 60 | params[PxLApi.TriggerParams.MODE] = PxLApi.TriggerModes.MODE_0 61 | params[PxLApi.TriggerParams.TYPE] = PxLApi.TriggerTypes.SOFTWARE 62 | # Leave the rest of the params the way they are 63 | 64 | flags = enable_feature(flags, True) # enable triggering 65 | 66 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.TRIGGER, flags, params) 67 | 68 | return ret 69 | 70 | """ 71 | Sets flags to enable/disable a feature 72 | """ 73 | def enable_feature(flags, enable): 74 | if enable: 75 | flags = ~PxLApi.FeatureFlags.MOD_BITS | PxLApi.FeatureFlags.MANUAL 76 | else: 77 | flags = ~PxLApi.FeatureFlags.MOD_BITS | PxLApi.FeatureFlags.OFF 78 | return flags 79 | 80 | """ 81 | This PxLApi.Callback.FRAME callback function will be called when an image is available from the camera. 82 | 83 | Note that frame time is relative to when the camera started streaming, so you have to make sure that 84 | the cameras start streaming at approximately the same time. If you're single-stepping through this code 85 | in a debugger, that's likely not the case. 86 | """ 87 | @PxLApi._dataProcessFunction 88 | def image_callback_function(hCamera, frame, dataFormat, frameDesc, context): 89 | 90 | frameDescriptor = frameDesc.contents 91 | print("Callback on thread %s for camera %s, frameTime = %f" % (hex(id(threading.current_thread())), hex(hCamera), frameDescriptor.fFrameTime)) 92 | return SUCCESS 93 | 94 | 95 | def do_test(hCameras, numberOfCapturesToDo): 96 | 97 | # Cameras should be streaming now and ready. 98 | for numTimes in range(numberOfCapturesToDo): 99 | print("") 100 | # Fire a software trigger on all of the cameras as quickly as possible 101 | for i in range(len(hCameras)): 102 | 103 | # By passing in a None or 0 frame buffer, we're saying to a camera that is configured for software triggering 104 | # that we just want to quickly trigger the camera, and not wait for the image to be exposed and sent back to the host. 105 | # Just start taking the picture. 106 | # We'll receive the picture in the callback function we've registered. 107 | ret = PxLApi.getNextFrame(hCameras[i], None) 108 | if not PxLApi.apiSuccess(ret[0]): 109 | print("Error: PxLApi.getNextFrame returned %i" % ret[0]) 110 | else: 111 | frameDesc = ret[1] 112 | print("Software trigger sent to %s return %i" % (hex(hCameras[i]), ret[0])) 113 | 114 | # Note that the frame descriptor has not been modified. 115 | assert 0.0 == frameDesc.Shutter.fValue 116 | 117 | time.sleep(1) # Wait a second... 118 | 119 | 120 | def main(): 121 | 122 | returnCode = FAILURE 123 | 124 | # First determine how many cameras there are 125 | numberOfCameras = 0 126 | ret = PxLApi.getNumberCameras() 127 | if not PxLApi.apiSuccess(ret[0]): 128 | print("Error: Unable to determine the number of cameras") 129 | return FAILURE 130 | 131 | cameraIdInfo = ret[1] 132 | 133 | if 0 == len(cameraIdInfo): 134 | print("Error: No cameras connected") 135 | return FAILURE 136 | 137 | # Initialize each of the cameras 138 | hCameras = [] 139 | for i in range(len(cameraIdInfo)): 140 | ret = PxLApi.initialize(serialNumber=cameraIdInfo[i].CameraSerialNum) 141 | if not PxLApi.apiSuccess(ret[0]): 142 | print("Error: Unable to initialize camera %i" % cameraIdInfo[i].CameraSerialNum) 143 | if PxLApi.apiSuccess(ret[0]): 144 | hCamera = ret[1] 145 | ret = prepare_camera_for_test(hCamera) 146 | if PxLApi.apiSuccess(ret[0]): 147 | print("Camera %i has handle %i" % (cameraIdInfo[i].CameraSerialNum, hCamera)) 148 | hCameras.append(hCamera) 149 | else: 150 | print("Error: Unable to prepare camera %i" % cameraIdInfo[i].CameraSerialNum) 151 | PxLApi.uninitialize(hCamera) 152 | break 153 | 154 | # Did we initialize all of them successfully? 155 | if len(hCameras) == len(cameraIdInfo): 156 | numberOfCapturesToDo = 5 157 | do_test(hCameras, numberOfCapturesToDo) 158 | returnCode = SUCCESS 159 | 160 | for i in range(len(hCameras)): 161 | PxLApi.setCallback(hCameras[i], PxLApi.Callback.FRAME, 0, None) 162 | PxLApi.setStreamState(hCameras[i], PxLApi.StreamState.STOP) 163 | PxLApi.uninitialize(hCamera) 164 | 165 | return returnCode 166 | 167 | 168 | if __name__ == "__main__": 169 | main() 170 | -------------------------------------------------------------------------------- /samples/Windows/softwareTriggerWithCallback.py: -------------------------------------------------------------------------------- 1 | """ 2 | softwareTriggerWithCallback.py 3 | 4 | A demonstration of a special software triggering mode. 5 | 6 | With normal software triggering on Pixelink cameras, a call to PxLApi.getNextFrame will cause the API to: 7 | 8 | 1) notify the camera to take an image 9 | 2) wait until the image is returned. 10 | 3) return the image 11 | 12 | If the camera were configured to have a 10 second exposure, the thread calling PxLApi.getNextFrame would be blocked 13 | inside PxLApi.getNextFrame for the entire 10 seconds. 14 | 15 | By using callbacks and calling PxLApi.getNextFrame in a special way, it's possible to emulate a hardware trigger. 16 | Calling PxLApi.getNextFrame with a None or 0 frame buffer: 17 | 18 | 1) notify the camera to take an image. 19 | 20 | and that's it. How do you get the image? It will be handed to you in an PxLApi.Callback.FRAME callback. 21 | 22 | Using this technique, it's possible to sofware trigger multiple cameras reasonably simultaneously. 23 | This technique is demonstrated here. 24 | 25 | This application will detect and connect to all PixeLINK 4.0 cameras, configure each for software triggering 26 | (assuming all cameras support triggering), set them all streaming, and then software trigger them at 27 | regular intervals. 28 | """ 29 | 30 | from pixelinkWrapper import* 31 | import threading 32 | import time 33 | 34 | SUCCESS = 0 35 | FAILURE = 1 36 | 37 | 38 | def prepare_camera_for_test(hCamera): 39 | 40 | ret = set_up_software_triggering(hCamera) 41 | if PxLApi.apiSuccess(ret[0]): 42 | # Set up PxLApi.Callback.FRAME callbacks for this camera 43 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.FRAME, 0, image_callback_function) 44 | if PxLApi.apiSuccess(ret[0]): 45 | return PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 46 | return ret 47 | 48 | """ 49 | Given a camera handle, configure the camera for software triggering. 50 | """ 51 | def set_up_software_triggering(hCamera): 52 | 53 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.TRIGGER) 54 | if PxLApi.apiSuccess(ret[0]): 55 | assert len(ret[2]) >= PxLApi.TriggerParams.NUM_PARAMS 56 | 57 | flags = ret[1] 58 | params = ret[2] 59 | 60 | params[PxLApi.TriggerParams.MODE] = PxLApi.TriggerModes.MODE_0 61 | params[PxLApi.TriggerParams.TYPE] = PxLApi.TriggerTypes.SOFTWARE 62 | # Leave the rest of the params the way they are 63 | 64 | flags = enable_feature(flags, True) # enable triggering 65 | 66 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.TRIGGER, flags, params) 67 | 68 | return ret 69 | 70 | """ 71 | Sets flags to enable/disable a feature 72 | """ 73 | def enable_feature(flags, enable): 74 | if enable: 75 | flags = ~PxLApi.FeatureFlags.MOD_BITS | PxLApi.FeatureFlags.MANUAL 76 | else: 77 | flags = ~PxLApi.FeatureFlags.MOD_BITS | PxLApi.FeatureFlags.OFF 78 | return flags 79 | 80 | """ 81 | This PxLApi.Callback.FRAME callback function will be called when an image is available from the camera. 82 | 83 | Note that frame time is relative to when the camera started streaming, so you have to make sure that 84 | the cameras start streaming at approximately the same time. If you're single-stepping through this code 85 | in a debugger, that's likely not the case. 86 | """ 87 | @PxLApi._dataProcessFunction 88 | def image_callback_function(hCamera, frame, dataFormat, frameDesc, context): 89 | 90 | frameDescriptor = frameDesc.contents 91 | print("Callback on thread %s for camera %s, frameTime = %f" % (hex(id(threading.current_thread())), hex(hCamera), frameDescriptor.fFrameTime)) 92 | return SUCCESS 93 | 94 | 95 | def do_test(hCameras, numberOfCapturesToDo): 96 | 97 | # Cameras should be streaming now and ready. 98 | for numTimes in range(numberOfCapturesToDo): 99 | print("") 100 | # Fire a software trigger on all of the cameras as quickly as possible 101 | for i in range(len(hCameras)): 102 | 103 | # By passing in a None or 0 frame buffer, we're saying to a camera that is configured for software triggering 104 | # that we just want to quickly trigger the camera, and not wait for the image to be exposed and sent back to the host. 105 | # Just start taking the picture. 106 | # We'll receive the picture in the callback function we've registered. 107 | ret = PxLApi.getNextFrame(hCameras[i], None) 108 | if not PxLApi.apiSuccess(ret[0]): 109 | print("Error: PxLApi.getNextFrame returned %i" % ret[0]) 110 | else: 111 | frameDesc = ret[1] 112 | print("Software trigger sent to %s return %i" % (hex(hCameras[i]), ret[0])) 113 | 114 | # Note that the frame descriptor has not been modified. 115 | assert 0.0 == frameDesc.Shutter.fValue 116 | 117 | time.sleep(1) # Wait a second... 118 | 119 | 120 | def main(): 121 | 122 | returnCode = FAILURE 123 | 124 | # First determine how many cameras there are 125 | numberOfCameras = 0 126 | ret = PxLApi.getNumberCameras() 127 | if not PxLApi.apiSuccess(ret[0]): 128 | print("Error: Unable to determine the number of cameras") 129 | return FAILURE 130 | 131 | cameraIdInfo = ret[1] 132 | 133 | if 0 == len(cameraIdInfo): 134 | print("Error: No cameras connected") 135 | return FAILURE 136 | 137 | # Initialize each of the cameras 138 | hCameras = [] 139 | for i in range(len(cameraIdInfo)): 140 | ret = PxLApi.initialize(serialNumber=cameraIdInfo[i].CameraSerialNum) 141 | if not PxLApi.apiSuccess(ret[0]): 142 | print("Error: Unable to initialize camera %i" % cameraIdInfo[i].CameraSerialNum) 143 | if PxLApi.apiSuccess(ret[0]): 144 | hCamera = ret[1] 145 | ret = prepare_camera_for_test(hCamera) 146 | if PxLApi.apiSuccess(ret[0]): 147 | print("Camera %i has handle %i" % (cameraIdInfo[i].CameraSerialNum, hCamera)) 148 | hCameras.append(hCamera) 149 | else: 150 | print("Error: Unable to prepare camera %i" % cameraIdInfo[i].CameraSerialNum) 151 | PxLApi.uninitialize(hCamera) 152 | break 153 | 154 | # Did we initialize all of them successfully? 155 | if len(hCameras) == len(cameraIdInfo): 156 | numberOfCapturesToDo = 5 157 | do_test(hCameras, numberOfCapturesToDo) 158 | returnCode = SUCCESS 159 | 160 | for i in range(len(hCameras)): 161 | PxLApi.setCallback(hCameras[i], PxLApi.Callback.FRAME, 0, None) 162 | PxLApi.setStreamState(hCameras[i], PxLApi.StreamState.STOP) 163 | PxLApi.uninitialize(hCamera) 164 | 165 | return returnCode 166 | 167 | 168 | if __name__ == "__main__": 169 | main() 170 | -------------------------------------------------------------------------------- /samples/Linux/gpio.py: -------------------------------------------------------------------------------- 1 | """ 2 | gpio.py 3 | 4 | This demonstrates how to control a camera's general purpose input (GPI), and general purpose output (GPO). 5 | 6 | This sample works with all Firewire/USB/USB3/GigE/10GigE cameras, provided the camera has at least one GPI 7 | and a GPO. It also interrogates the camera to determine the camera’s specific GPIO capability/properties. 8 | 9 | If the camera has at least one GPI and a GPO, they will be set. Then, the program will poll the GPI value, 10 | reporting on the value on the console, and on the GPO. 11 | """ 12 | 13 | from pixelinkWrapper import* 14 | from select import select 15 | import sys 16 | import time 17 | import tty 18 | import termios 19 | 20 | # A few useful defines 21 | GPIO_ON = True 22 | GPIO_OFF = False 23 | 24 | # The poll period of the GPI, in seconds 25 | POLL_PERIOD_SEC = 0.5 26 | 27 | """ 28 | Returns true if the camera has a GPI and a GPO 29 | """ 30 | def supports_gpio(hCamera): 31 | # GPIO index supporting GPI 32 | global gpiIndex 33 | 34 | # Step 1 35 | # Get info on the GPIO for this camera 36 | ret = PxLApi.getCameraFeatures(hCamera, PxLApi.FeatureId.GPIO) 37 | if not PxLApi.apiSuccess(ret[0]): 38 | return False 39 | gpioFeatureInfo = ret[1] 40 | 41 | # Step 2 42 | # Look at the feature info, and ensure the camera supports a GPI and a GPO 43 | if not gpioFeatureInfo.Features[0].uFlags & PxLApi.FeatureFlags.PRESENCE: # No GPIOs at all !! 44 | return False 45 | if gpioFeatureInfo.Features[0].Params[0].fMaxValue < 2.0: # We need at least 2 GPIO !! 46 | return False 47 | if gpioFeatureInfo.Features[0].Params[1].fMaxValue < PxLApi.GpioModes.INPUT: # Does not support GPI !! 48 | return False 49 | if gpioFeatureInfo.Features[0].Params[0].fMaxValue == 3.0: # For PL-X cameras 50 | gpiIndex = 3.0 51 | else: # For PL-D and other cameras 52 | gpiIndex = 1.0 53 | 54 | return True 55 | 56 | 57 | def setup_gpios(hCamera): 58 | 59 | gpioParams = [0] * PxLApi.GpioParams.NUM_PARAMS 60 | # Step 1 61 | # Set the GPI 62 | gpioParams[PxLApi.GpioParams.INDEX] = gpiIndex 63 | gpioParams[PxLApi.GpioParams.MODE] = PxLApi.GpioModes.INPUT 64 | gpioParams[PxLApi.GpioParams.POLARITY] = 0 65 | # Don't care about the other parameters 66 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.GPIO, PxLApi.FeatureFlags.MANUAL, gpioParams) 67 | if not PxLApi.apiSuccess(ret[0]): 68 | return ret 69 | 70 | # Step 2 71 | # Set the GPO (to normal mode) 72 | gpioParams[PxLApi.GpioParams.INDEX] = 2.0 73 | gpioParams[PxLApi.GpioParams.MODE] = PxLApi.GpioModes.NORMAL 74 | gpioParams[PxLApi.GpioParams.POLARITY] = 0 75 | # Don't care about the other parameters 76 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.GPIO, PxLApi.FeatureFlags.MANUAL, gpioParams) 77 | 78 | return ret 79 | 80 | 81 | def main(): 82 | 83 | gpioParams = [0] * PxLApi.GpioParams.NUM_PARAMS 84 | 85 | # Step 1 86 | # Find and initialize a camera 87 | ret = PxLApi.initialize(0) 88 | if not(PxLApi.apiSuccess(ret[0])): 89 | print("Could not Initialize the camera! Rc = %i" % ret[0]) 90 | return 1 91 | 92 | hCamera = ret[1] 93 | 94 | # Step 2 95 | # Ensure the camera has at least 2 gpios, and supports a GPI 96 | if not supports_gpio(hCamera): 97 | print("Camera does not support GPIO!") 98 | PxLApi.uninitialize(hCamera) 99 | return 1 100 | 101 | # Step 3 102 | # Set the camera up for one GPI and one GPO 103 | ret = setup_gpios(hCamera) 104 | if not PxLApi.apiSuccess(ret[0]): 105 | print("Could not setup the GPIOs! Rc = %i" % ret[0]) 106 | PxLApi.uninitialize(hCamera) 107 | return 1 108 | 109 | # Give the last GPI a value that will ensure our loop will print/assert the GPO on its first time through 110 | lastGpi = GPIO_ON 111 | 112 | # Step 4 113 | # Poll the GPI, reporting it's value on the console, and on the GPO 114 | print("Polling the GPI every %i ms, press any key to exit" % (POLL_PERIOD_SEC*1000)) 115 | setUnbufKb(True) 116 | while not kbhit(): 117 | # Read the GPI 118 | gpioParams[PxLApi.GpioParams.INDEX] = gpiIndex 119 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.GPIO, gpioParams) 120 | if not PxLApi.apiSuccess(ret[0]): 121 | print("\nCould not read the GPI! Rc = %i" % ret[0]) 122 | PxLApi.uninitialize(hCamera) 123 | return 1 124 | gpioParams = ret[2] 125 | 126 | if 0 == gpioParams[PxLApi.GpioModeInput.STATUS]: 127 | currentGpi = GPIO_OFF 128 | else: 129 | currentGpi = GPIO_ON 130 | 131 | # If the GPI changed, then set the GPO 132 | 133 | if currentGpi != lastGpi: 134 | 135 | gpioParams[PxLApi.GpioParams.INDEX] = 2.0 136 | gpioParams[PxLApi.GpioParams.MODE] = PxLApi.GpioModes.NORMAL 137 | gpioParams[PxLApi.GpioParams.POLARITY] = float(currentGpi) 138 | # Don't care about the other parameters 139 | ret = PxLApi.setFeature(hCamera, PxLApi.FeatureId.GPIO, PxLApi.FeatureFlags.MANUAL, gpioParams) 140 | if not PxLApi.apiSuccess(ret[0]): 141 | print("\nCould not write the GPO! Rc = %i" % ret[0]) 142 | PxLApi.uninitialize(hCamera) 143 | return 1 144 | 145 | lastGpi = currentGpi 146 | 147 | if GPIO_ON == currentGpi: 148 | currentGpiState = "On" 149 | else: 150 | currentGpiState = "Off" 151 | print("\rGPI is %s " % currentGpiState, end="", flush=True) 152 | 153 | time.sleep(POLL_PERIOD_SEC) # 500 ms 154 | 155 | setUnbufKb(False) 156 | print("\r") 157 | PxLApi.uninitialize(hCamera) 158 | return 0 159 | 160 | """ 161 | Unbuffered non-blocking keyboard input on command line. 162 | Keyboard input will be passed to the application without the user pressing 163 | the enter key. 164 | Note: IDLE does not support this functionality. 165 | """ 166 | # A couple of useful global variables 167 | fd = sys.stdin.fileno() 168 | original_term_settings = termios.tcgetattr(fd) 169 | 170 | # Enable/disable unbuffered keyboard input 171 | def setUnbufKb(enable): 172 | if enable: 173 | tty.setraw(sys.stdin.fileno()) 174 | else: 175 | termios.tcsetattr(fd, termios.TCSADRAIN, original_term_settings) 176 | 177 | # Unbuffered button hit 178 | def kbhit(): 179 | btnHit = False 180 | rlist = select([sys.stdin], [], [], 0) 181 | if rlist[0] != []: 182 | sys.stdin.read(1) 183 | btnHit = True 184 | return btnHit 185 | 186 | 187 | if __name__ == "__main__": 188 | gpiIndex = 0.0 # GPIO index supporting GPI depending on the camera model 189 | main() 190 | -------------------------------------------------------------------------------- /samples/Linux/getMultipleSnapshots.py: -------------------------------------------------------------------------------- 1 | """ 2 | getMultipleSnapshots.py 3 | 4 | Sample code to capture images from a Pixelink camera and save the encoded images to a folder as files. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import os 10 | import time 11 | 12 | SUCCESS = 0 13 | FAILURE = 1 14 | 15 | """ 16 | Get a snapshot from the camera, and save it to a file. 17 | """ 18 | def get_snapshot(hCamera, imageFormat, fileName): 19 | 20 | assert 0 != hCamera 21 | assert fileName 22 | 23 | # Determine the size of buffer we'll need to hold an image from the camera 24 | rawImageSize = determine_raw_image_size(hCamera) 25 | if 0 == rawImageSize: 26 | return FAILURE 27 | 28 | # Create a buffer to hold the raw image 29 | rawImage = create_string_buffer(rawImageSize) 30 | 31 | if 0 != len(rawImage): 32 | # Capture a raw image. The raw image buffer will contain image data on success. 33 | ret = get_raw_image(hCamera, rawImage) 34 | if PxLApi.apiSuccess(ret[0]): 35 | frameDescriptor = ret[1] 36 | # 37 | # Do any image processing here 38 | # 39 | 40 | assert 0 != len(rawImage) 41 | assert frameDescriptor 42 | # Encode the raw image into something displayable 43 | ret = PxLApi.formatImage(rawImage, frameDescriptor, imageFormat) 44 | if SUCCESS == ret[0]: 45 | formatedImage = ret[1] 46 | # Save formated image into a file 47 | if save_image_to_file(fileName, formatedImage) == SUCCESS: 48 | return SUCCESS 49 | 50 | return FAILURE 51 | 52 | """ 53 | Query the camera for region of interest (ROI), decimation, and pixel format 54 | Using this information, we can calculate the size of a raw image 55 | 56 | Returns 0 on failure 57 | """ 58 | def determine_raw_image_size(hCamera): 59 | 60 | assert 0 != hCamera 61 | 62 | # Get region of interest (ROI) 63 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.ROI) 64 | params = ret[2] 65 | roiWidth = params[PxLApi.RoiParams.WIDTH] 66 | roiHeight = params[PxLApi.RoiParams.HEIGHT] 67 | 68 | # Query pixel addressing 69 | # assume no pixel addressing (in case it is not supported) 70 | pixelAddressingValueX = 1 71 | pixelAddressingValueY = 1 72 | 73 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PIXEL_ADDRESSING) 74 | if PxLApi.apiSuccess(ret[0]): 75 | params = ret[2] 76 | if PxLApi.PixelAddressingParams.NUM_PARAMS == len(params): 77 | # Camera supports symmetric and asymmetric pixel addressing 78 | pixelAddressingValueX = params[PxLApi.PixelAddressingParams.X_VALUE] 79 | pixelAddressingValueY = params[PxLApi.PixelAddressingParams.Y_VALUE] 80 | else: 81 | # Camera supports only symmetric pixel addressing 82 | pixelAddressingValueX = params[PxLApi.PixelAddressingParams.VALUE] 83 | pixelAddressingValueY = params[PxLApi.PixelAddressingParams.VALUE] 84 | 85 | # We can calulate the number of pixels now. 86 | numPixels = (roiWidth / pixelAddressingValueX) * (roiHeight / pixelAddressingValueY) 87 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT) 88 | 89 | # Knowing pixel format means we can determine how many bytes per pixel. 90 | params = ret[2] 91 | pixelFormat = int(params[0]) 92 | 93 | # And now the size of the frame 94 | pixelSize = PxLApi.getBytesPerPixel(pixelFormat) 95 | 96 | return int(numPixels * pixelSize) 97 | 98 | """ 99 | Capture an image from the camera. 100 | 101 | NOTE: PxLApi.getNextFrame is a blocking call. 102 | i.e. PxLApi.getNextFrame won't return until an image is captured. 103 | So, if you're using hardware triggering, it won't return until the camera is triggered. 104 | 105 | Returns a return code with success and frame descriptor information or API error 106 | """ 107 | def get_raw_image(hCamera, rawImage): 108 | 109 | assert 0 != hCamera 110 | assert 0 != len(rawImage) 111 | 112 | MAX_NUM_TRIES = 4 113 | 114 | # Get an image 115 | # NOTE: PxLApi.getNextFrame can return ApiCameraTimeoutError on occasion. 116 | # How you handle this depends on your situation and how you use your camera. 117 | # For this sample app, we'll just retry a few times. 118 | ret = (PxLApi.ReturnCode.ApiUnknownError,) 119 | 120 | for i in range(MAX_NUM_TRIES): 121 | ret = PxLApi.getNextFrame(hCamera, rawImage) 122 | if PxLApi.apiSuccess(ret[0]): 123 | break 124 | 125 | return ret 126 | 127 | """ 128 | Save the encoded image buffer to a file 129 | This overwrites any existing file 130 | 131 | Returns SUCCESS or FAILURE 132 | """ 133 | def save_image_to_file(fileName, formatedImage): 134 | 135 | assert fileName 136 | assert 0 != len(formatedImage) 137 | 138 | # Create a folder to save snapshots if it does not exist 139 | if not os.path.exists("getMultipleSnapshots"): 140 | os.makedirs("getMultipleSnapshots") 141 | 142 | filepath = "getMultipleSnapshots/" + fileName 143 | # Open a file for binary write 144 | file = open(filepath, "wb") 145 | if None == file: 146 | return FAILURE 147 | numBytesWritten = file.write(formatedImage) 148 | file.close() 149 | 150 | if numBytesWritten == len(formatedImage): 151 | return SUCCESS 152 | 153 | return FAILURE 154 | 155 | 156 | def main(): 157 | 158 | # Tell the camera we want to start using it. 159 | # NOTE: We're assuming there's only one camera. 160 | ret = PxLApi.initialize(0) 161 | if not PxLApi.apiSuccess(ret[0]): 162 | return 1 163 | hCamera = ret[1] 164 | 165 | # Put camera into streaming state so we can capture an image 166 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 167 | if not PxLApi.apiSuccess(ret[0]): 168 | return 1 169 | 170 | # Get the snapshots and save them to a folder as files 171 | for i in range(5): 172 | filenameJpg = "image" + str(i) + ".jpg" 173 | retVal = get_snapshot(hCamera, PxLApi.ImageFormat.JPEG, filenameJpg) 174 | if SUCCESS == retVal: 175 | print("Saved image to 'getMultipleSnapshots/%s'" % filenameJpg) 176 | else: 177 | print("Could not save image to 'getMultipleSnapshots/%s'" % filenameJpg) 178 | time.sleep(2) 179 | 180 | # Done capturing, so no longer need the camera streaming images. 181 | # Note: If ret is used for this call, it will lose frame descriptor information. 182 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 183 | if not PxLApi.apiSuccess(ret[0]): 184 | return 1 185 | 186 | # Tell the camera we're done with it. 187 | PxLApi.uninitialize(hCamera) 188 | 189 | if SUCCESS != retVal: 190 | return 1 191 | 192 | return 0 193 | 194 | 195 | if __name__ == "__main__": 196 | main() 197 | -------------------------------------------------------------------------------- /samples/Windows/getMultipleSnapshots.py: -------------------------------------------------------------------------------- 1 | """ 2 | getMultipleSnapshots.py 3 | 4 | Sample code to capture images from a Pixelink camera and save the encoded images to a folder as files. 5 | """ 6 | 7 | from pixelinkWrapper import* 8 | from ctypes import* 9 | import os 10 | import time 11 | 12 | SUCCESS = 0 13 | FAILURE = 1 14 | 15 | """ 16 | Get a snapshot from the camera, and save it to a file. 17 | """ 18 | def get_snapshot(hCamera, imageFormat, fileName): 19 | 20 | assert 0 != hCamera 21 | assert fileName 22 | 23 | # Determine the size of buffer we'll need to hold an image from the camera 24 | rawImageSize = determine_raw_image_size(hCamera) 25 | if 0 == rawImageSize: 26 | return FAILURE 27 | 28 | # Create a buffer to hold the raw image 29 | rawImage = create_string_buffer(rawImageSize) 30 | 31 | if 0 != len(rawImage): 32 | # Capture a raw image. The raw image buffer will contain image data on success. 33 | ret = get_raw_image(hCamera, rawImage) 34 | if PxLApi.apiSuccess(ret[0]): 35 | frameDescriptor = ret[1] 36 | # 37 | # Do any image processing here 38 | # 39 | 40 | assert 0 != len(rawImage) 41 | assert frameDescriptor 42 | # Encode the raw image into something displayable 43 | ret = PxLApi.formatImage(rawImage, frameDescriptor, imageFormat) 44 | if SUCCESS == ret[0]: 45 | formatedImage = ret[1] 46 | # Save formated image into a file 47 | if save_image_to_file(fileName, formatedImage) == SUCCESS: 48 | return SUCCESS 49 | 50 | return FAILURE 51 | 52 | """ 53 | Query the camera for region of interest (ROI), decimation, and pixel format 54 | Using this information, we can calculate the size of a raw image 55 | 56 | Returns 0 on failure 57 | """ 58 | def determine_raw_image_size(hCamera): 59 | 60 | assert 0 != hCamera 61 | 62 | # Get region of interest (ROI) 63 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.ROI) 64 | params = ret[2] 65 | roiWidth = params[PxLApi.RoiParams.WIDTH] 66 | roiHeight = params[PxLApi.RoiParams.HEIGHT] 67 | 68 | # Query pixel addressing 69 | # assume no pixel addressing (in case it is not supported) 70 | pixelAddressingValueX = 1 71 | pixelAddressingValueY = 1 72 | 73 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PIXEL_ADDRESSING) 74 | if PxLApi.apiSuccess(ret[0]): 75 | params = ret[2] 76 | if PxLApi.PixelAddressingParams.NUM_PARAMS == len(params): 77 | # Camera supports symmetric and asymmetric pixel addressing 78 | pixelAddressingValueX = params[PxLApi.PixelAddressingParams.X_VALUE] 79 | pixelAddressingValueY = params[PxLApi.PixelAddressingParams.Y_VALUE] 80 | else: 81 | # Camera supports only symmetric pixel addressing 82 | pixelAddressingValueX = params[PxLApi.PixelAddressingParams.VALUE] 83 | pixelAddressingValueY = params[PxLApi.PixelAddressingParams.VALUE] 84 | 85 | # We can calulate the number of pixels now. 86 | numPixels = (roiWidth / pixelAddressingValueX) * (roiHeight / pixelAddressingValueY) 87 | ret = PxLApi.getFeature(hCamera, PxLApi.FeatureId.PIXEL_FORMAT) 88 | 89 | # Knowing pixel format means we can determine how many bytes per pixel. 90 | params = ret[2] 91 | pixelFormat = int(params[0]) 92 | 93 | # And now the size of the frame 94 | pixelSize = PxLApi.getBytesPerPixel(pixelFormat) 95 | 96 | return int(numPixels * pixelSize) 97 | 98 | """ 99 | Capture an image from the camera. 100 | 101 | NOTE: PxLApi.getNextFrame is a blocking call. 102 | i.e. PxLApi.getNextFrame won't return until an image is captured. 103 | So, if you're using hardware triggering, it won't return until the camera is triggered. 104 | 105 | Returns a return code with success and frame descriptor information or API error 106 | """ 107 | def get_raw_image(hCamera, rawImage): 108 | 109 | assert 0 != hCamera 110 | assert 0 != len(rawImage) 111 | 112 | MAX_NUM_TRIES = 4 113 | 114 | # Get an image 115 | # NOTE: PxLApi.getNextFrame can return ApiCameraTimeoutError on occasion. 116 | # How you handle this depends on your situation and how you use your camera. 117 | # For this sample app, we'll just retry a few times. 118 | ret = (PxLApi.ReturnCode.ApiUnknownError,) 119 | 120 | for i in range(MAX_NUM_TRIES): 121 | ret = PxLApi.getNextFrame(hCamera, rawImage) 122 | if PxLApi.apiSuccess(ret[0]): 123 | break 124 | 125 | return ret 126 | 127 | """ 128 | Save the encoded image buffer to a file 129 | This overwrites any existing file 130 | 131 | Returns SUCCESS or FAILURE 132 | """ 133 | def save_image_to_file(fileName, formatedImage): 134 | 135 | assert fileName 136 | assert 0 != len(formatedImage) 137 | 138 | # Create a folder to save snapshots if it does not exist 139 | if not os.path.exists("getMultipleSnapshots"): 140 | os.makedirs("getMultipleSnapshots") 141 | 142 | filepath = "getMultipleSnapshots/" + fileName 143 | # Open a file for binary write 144 | file = open(filepath, "wb") 145 | if None == file: 146 | return FAILURE 147 | numBytesWritten = file.write(formatedImage) 148 | file.close() 149 | 150 | if numBytesWritten == len(formatedImage): 151 | return SUCCESS 152 | 153 | return FAILURE 154 | 155 | 156 | def main(): 157 | 158 | # Tell the camera we want to start using it. 159 | # NOTE: We're assuming there's only one camera. 160 | ret = PxLApi.initialize(0) 161 | if not PxLApi.apiSuccess(ret[0]): 162 | return 1 163 | hCamera = ret[1] 164 | 165 | # Put camera into streaming state so we can capture an image 166 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 167 | if not PxLApi.apiSuccess(ret[0]): 168 | return 1 169 | 170 | # Get the snapshots and save them to a folder as files 171 | for i in range(5): 172 | filenamePng = "image" + str(i) + ".png" 173 | retVal = get_snapshot(hCamera, PxLApi.ImageFormat.PNG, filenamePng) 174 | if SUCCESS == retVal: 175 | print("Saved image to 'getMultipleSnapshots/%s'" % filenamePng) 176 | else: 177 | print("Could not save image to 'getMultipleSnapshots/%s'" % filenamePng) 178 | time.sleep(2) 179 | 180 | # Done capturing, so no longer need the camera streaming images. 181 | # Note: If ret is used for this call, it will lose frame descriptor information. 182 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 183 | if not PxLApi.apiSuccess(ret[0]): 184 | return 1 185 | 186 | # Tell the camera we're done with it. 187 | PxLApi.uninitialize(hCamera) 188 | 189 | if SUCCESS != retVal: 190 | return 1 191 | 192 | return 0 193 | 194 | 195 | if __name__ == "__main__": 196 | main() 197 | -------------------------------------------------------------------------------- /samples/Linux/callback.py: -------------------------------------------------------------------------------- 1 | """ 2 | callback.py 3 | 4 | Demonstrates how to use callbacks with Callback.PREVIEW 5 | The callback function here does not modify the image data. 6 | """ 7 | 8 | from pixelinkWrapper import* 9 | import time 10 | import threading 11 | 12 | 13 | def get_pixel_format_as_string(dataFormat): 14 | switcher = { 15 | PxLApi.PixelFormat.MONO8: "MONO8", 16 | PxLApi.PixelFormat.MONO16: "MONO16", 17 | PxLApi.PixelFormat.YUV422: "YUV422", 18 | PxLApi.PixelFormat.BAYER8_GRBG: "BAYER8_GRBG", 19 | PxLApi.PixelFormat.BAYER16_GRBG: "BAYER16_GRBG", 20 | PxLApi.PixelFormat.RGB24: "RGB24", 21 | PxLApi.PixelFormat.RGB48: "RGB48", 22 | PxLApi.PixelFormat.BAYER8_RGGB: "BAYER8_RGGB", 23 | PxLApi.PixelFormat.BAYER8_GBRG: "BAYER8_GBRG", 24 | PxLApi.PixelFormat.BAYER8_BGGR: "BAYER8_BGGR", 25 | PxLApi.PixelFormat.BAYER16_RGGB: "BAYER16_RGGB", 26 | PxLApi.PixelFormat.BAYER16_GBRG: "BAYER16_GBRG", 27 | PxLApi.PixelFormat.BAYER16_BGGR: "BAYER16_BGGR", 28 | PxLApi.PixelFormat.MONO12_PACKED: "MONO12_PACKED", 29 | PxLApi.PixelFormat.BAYER12_GRBG_PACKED: "BAYER12_GRBG_PACKED", 30 | PxLApi.PixelFormat.BAYER12_RGGB_PACKED: "BAYER12_RGGB_PACKED", 31 | PxLApi.PixelFormat.BAYER12_GBRG_PACKED: "BAYER12_GBRG_PACKED", 32 | PxLApi.PixelFormat.BAYER12_BGGR_PACKED: "BAYER12_BGGR_PACKED", 33 | PxLApi.PixelFormat.RGB24_NON_DIB: "RGB24_NON_DIB", 34 | PxLApi.PixelFormat.RGB48_DIB: "RGB48_DIB", 35 | PxLApi.PixelFormat.MONO12_PACKED_MSFIRST: "MONO12_PACKED_MSFIRST", 36 | PxLApi.PixelFormat.BAYER12_GRBG_PACKED_MSFIRST: "BAYER12_GRBG_PACKED_MSFIRST", 37 | PxLApi.PixelFormat.BAYER12_RGGB_PACKED_MSFIRST: "BAYER12_RGGB_PACKED_MSFIRST", 38 | PxLApi.PixelFormat.BAYER12_GBRG_PACKED_MSFIRST: "BAYER12_GBRG_PACKED_MSFIRST", 39 | PxLApi.PixelFormat.BAYER12_BGGR_PACKED_MSFIRST: "BAYER12_BGGR_PACKED_MSFIRST", 40 | PxLApi.PixelFormat.MONO10_PACKED_MSFIRST: "MONO10_PACKED_MSFIRST", 41 | PxLApi.PixelFormat.BAYER10_GRBG_PACKED_MSFIRST: "BAYER10_GRBG_PACKED_MSFIRST", 42 | PxLApi.PixelFormat.BAYER10_RGGB_PACKED_MSFIRST: "BAYER10_RGGB_PACKED_MSFIRST", 43 | PxLApi.PixelFormat.BAYER10_GBRG_PACKED_MSFIRST: "BAYER10_GBRG_PACKED_MSFIRST", 44 | PxLApi.PixelFormat.BAYER10_BGGR_PACKED_MSFIRST: "BAYER10_BGGR_PACKED_MSFIRST", 45 | PxLApi.PixelFormat.STOKES4_12: "STOKES4_12", 46 | PxLApi.PixelFormat.POLAR4_12: "POLAR4_12", 47 | PxLApi.PixelFormat.POLAR_RAW4_12: "POLAR_RAW4_12", 48 | PxLApi.PixelFormat.HSV4_12: "HSV4_12", 49 | PxLApi.PixelFormat.BGR24_NON_DIB: "BGR24_NON_DIB" 50 | } 51 | return switcher.get(dataFormat, "Unknown data format") 52 | 53 | """ 54 | Callback function called by the API just before an image is displayed in the preview window. 55 | N.B. This is called by the API on a thread created in the API. 56 | """ 57 | @PxLApi._dataProcessFunction 58 | def callback_format_preview(hCamera, frameData, dataFormat, frameDesc, userData): 59 | # Copy frame descriptor information 60 | frameDescriptor = frameDesc.contents 61 | # Find image dimensions 62 | width = int(frameDescriptor.Roi.fWidth / frameDescriptor.PixelAddressingValue.fHorizontal) 63 | height = int(frameDescriptor.Roi.fHeight / frameDescriptor.PixelAddressingValue.fVertical) 64 | bytesPerPixel = PxLApi.getBytesPerPixel(dataFormat) 65 | 66 | 67 | print("callback_format_image: hCamera = {0}, frameData = {1}".format(hex(hCamera), 68 | hex(id(frameData)))) 69 | print(" dataFormat = {0} {1}, FrameDesc = {2}".format(dataFormat, 70 | get_pixel_format_as_string(dataFormat), 71 | hex(id(frameDesc)))) 72 | print(" userData = {0}, threadId = {1}".format(hex(userData), hex(id(threading.current_thread())))) 73 | print(" imageData = {0} {1} {2} {3} {4} {5} {6} {7}\n".format(hex(frameData[0]), hex(frameData[1]), hex(frameData[2]), 74 | hex(frameData[3]), hex(frameData[4]), hex(frameData[5]), 75 | hex(frameData[6]), hex(frameData[7]))) 76 | 77 | # Just to see the effect of the callback, increase intensity of the middle to 100% 78 | startRow = int((height/5)*2) 79 | endRow = int((height/5)*3) 80 | startCol = int((width/5)*2) 81 | endCol = int((width/5)*3) 82 | 83 | # Find the first pixel that needs to be modified 84 | for i in range(startRow, endRow): 85 | pixel = int(bytesPerPixel * ((startRow * frameDescriptor.Roi.fWidth) + startCol)) 86 | for j in range(startCol, endCol): 87 | for k in range(bytesPerPixel): 88 | index = pixel + k 89 | frameData[index] = 0xff 90 | pixel += bytesPerPixel 91 | startRow += 1 92 | 93 | return 0 94 | 95 | 96 | def do_callback_on_preview(hCamera): 97 | # Set the callback function 98 | print("=====================================================\n") 99 | print("do_callback_on_preview\n") 100 | userData = 3735928559 101 | print("Registering PREVIEW callback with userData {0}\n".format(hex(userData))) 102 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.PREVIEW, userData, callback_format_preview) 103 | if(not(PxLApi.apiSuccess(ret[0]))): 104 | print("ERROR setting callback function: {0}".format(ret[0])) 105 | return 106 | 107 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.START) 108 | if(not(PxLApi.apiSuccess(ret[0]))): 109 | print("ERROR setting stream state function: {0}".format(ret[0])) 110 | return 111 | 112 | # We will start getting our callback called after we start previewing 113 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.START) 114 | if(not(PxLApi.apiSuccess(ret[0]))): 115 | print("ERROR setting preview state function: {0}".format(ret[0])) 116 | return 117 | 118 | time.sleep(10) # Sleep 10 seconds 119 | 120 | # Stop previewing 121 | ret = PxLApi.setPreviewState(hCamera, PxLApi.PreviewState.STOP) 122 | if(not(PxLApi.apiSuccess(ret[0]))): 123 | print("ERROR setting preview state function: {0}".format(ret[0])) 124 | return 125 | 126 | ret = PxLApi.setStreamState(hCamera, PxLApi.StreamState.STOP) 127 | 128 | # Disable callback on preview by setting the callback function to 0 or None 129 | ret = PxLApi.setCallback(hCamera, PxLApi.Callback.PREVIEW, userData, 0) 130 | 131 | 132 | def main(): 133 | 134 | ret = PxLApi.initialize(0) 135 | if(not(PxLApi.apiSuccess(ret[0]))): 136 | print("ERROR: {0}\n".format(ret[0])) 137 | return 1 138 | hCamera = ret[1] 139 | print("\nMain thread id = {}\n".format(hex(id(threading.current_thread())))) 140 | 141 | # do_callback_on_format_image(hCamera) /* Callback.FORMAT_IMAGE is not supported */ 142 | do_callback_on_preview(hCamera) 143 | 144 | PxLApi.uninitialize(hCamera) 145 | return 0 146 | 147 | if __name__ == "__main__": 148 | main() 149 | --------------------------------------------------------------------------------