### Install Dependencies Source: https://github.com/theimagingsource/ic4-examples/blob/master/python/qt6/demoapp/README.md Run this command to install all necessary Python packages for the application. ```bash pip install -r ./requirements.txt ``` -------------------------------- ### Install Requirements Source: https://github.com/theimagingsource/ic4-examples/blob/master/python/camera-specific/DolP-Segmentation/README.md Command to install necessary Python packages for the DoLP segmentation example. ```bash $ pip install -r requirements.txt ``` -------------------------------- ### Run compiled example Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/README.md Execute the built binary to verify camera detection. ```bash ~/ic4-examples/cpp/device-handling/device-enumeration $ ./build/device-enumeration ``` -------------------------------- ### Include Qt Setup Script Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/qt6/common/qt6-dialogs/CMakeLists.txt Includes a script for setting up Qt. This is a common practice for Qt projects using CMake. ```cmake set(QT_REQUIRED_TOP_LEVEL ${PROJECT_IS_TOP_LEVEL}) include( ../setup_qt.cmake ) ``` -------------------------------- ### CMakeLists.txt for Device List Changed Example Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/device-handling/device-list-changed/CMakeLists.txt This CMakeLists.txt file configures the build for the device-list-changed example. It finds the ic4 package, adds an executable, specifies include directories and libraries, and sets the C++ standard. ```cmake cmake_minimum_required(VERSION 3.10) project("device-list-changed") find_package( ic4 REQUIRED ) add_executable( device-list-changed "src/device-list-changed.cpp" ) target_include_directories( device-list-changed PRIVATE "../../common" ) target_link_libraries( device-list-changed PRIVATE ic4::core ) set_target_properties( device-list-changed PROPERTIES CXX_STANDARD 14 ) ic4_copy_runtime_to_target(device-list-changed) ``` -------------------------------- ### Start Data Stream with Sink Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/record-mp4-h264/README.md Start the data stream by calling Grabber::streamSetup, passing the newly created sink. This directs the image data from the device to the sink for processing. ```cpp grabber.streamSetup(std::move(sink)); ``` -------------------------------- ### Run Python Application Source: https://github.com/theimagingsource/ic4-examples/blob/master/python/qt6/demoapp/README.md Execute the main Python script to start the ic4-demoapp. ```bash python3 ./demoapp.py ``` -------------------------------- ### Start Stream to QueueSink Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/save-bmp-on-trigger/README.md Creates a QueueSink with the listener and starts the data stream. ```cpp auto listener = std::make_shared(); auto sink = QueueSink::create(listener); grabber->streamSetup(sink); grabber->streamStart(); std::cout << "Press any key to trigger an image, or 'q' to quit." << std::endl; ``` -------------------------------- ### Install IC Imaging Control 4 dependencies Source: https://github.com/theimagingsource/ic4-examples/blob/master/python/README.md Install the required packages for the IC Imaging Control 4 API and third-party integrations using pip. ```bash $ python3 -m pip install imagingcontrol4 imagingcontrol4pyside6 $ python3 -m pip install numpy opencv-python PySide6 ``` -------------------------------- ### Capture and Save Single Images with SnapSink (C++) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt This C++ example demonstrates capturing single image frames using SnapSink. It includes error handling for sink creation and stream setup. Ensure the ic4 library is linked. ```cpp #include #include int main() { ic4::initLibrary(); std::atexit(ic4::exitLibrary); auto devices = ic4::DeviceEnum::enumDevices(); ic4::Grabber grabber; grabber.deviceOpen(devices[0]); ic4::Error err; // Create snap sink auto sink = ic4::SnapSink::create(err); if (!sink) { std::cerr << "Failed to create sink: " << err.message() << std::endl; return -1; } // Start stream if (!grabber.streamSetup(sink, ic4::StreamSetupOption::AcquisitionStart, err)) { std::cerr << "Failed to setup stream: " << err.message() << std::endl; return -2; } // Snap images for (int i = 0; i < 5; ++i) { auto image_buffer = sink->snapSingle(1000, err); if (!image_buffer) { std::cerr << "Failed to snap: " << err.message() << std::endl; continue; } // Save as JPEG ic4::SaveJpegOptions options = { 90 }; // quality_pct std::string filename = "image_" + std::to_string(i) + ".jpg"; ic4::imageBufferSaveAsJpeg(*image_buffer, filename, options, err); std::cout << "Saved " << filename << std::endl; } grabber.streamStop(); grabber.deviceClose(); return 0; } ``` -------------------------------- ### Configure Hardware Trigger Mode in Python Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Use this snippet to set up cameras for hardware or software triggers, essential for synchronized multi-camera setups. Ensure the imagingcontrol4 library is installed. ```python import imagingcontrol4 as ic4 class TriggerListener(ic4.QueueSinkListener): def __init__(self, save_path: str): self.save_path = save_path self.counter = 0 def sink_connected(self, sink: ic4.QueueSink, image_type: ic4.ImageType, min_buffers_required: int) -> bool: return True def frames_queued(self, sink: ic4.QueueSink): buffer = sink.pop_output_buffer() filename = f"{self.save_path}_{self.counter}.bmp" buffer.save_as_bmp(filename) print(f"Saved triggered image: {filename}") self.counter += 1 with ic4.Library.init_context(): grabber = ic4.Grabber(ic4.DeviceEnum.devices()[0]) map = grabber.device_property_map # Reset to defaults map.try_set_value(ic4.PropId.USER_SET_SELECTOR, "Default") map.try_set_value(ic4.PropId.USER_SET_LOAD, 1) # Configure trigger map.try_set_value(ic4.PropId.TRIGGER_SELECTOR, "FrameStart") map.set_value(ic4.PropId.TRIGGER_MODE, "On") # Optional: Set trigger source (Line1, Software, etc.) # map.set_value(ic4.PropId.TRIGGER_SOURCE, "Line1") listener = TriggerListener("./triggered_image") sink = ic4.QueueSink(listener) grabber.stream_setup(sink) print("Waiting for triggers...") print("Press Enter to issue software trigger, 'q' + Enter to quit") while True: user_input = input() if user_input == 'q': break # Execute software trigger map.execute_command(ic4.PropId.TRIGGER_SOFTWARE) # Cleanup grabber.stream_stop() map.set_value(ic4.PropId.TRIGGER_MODE, "Off") grabber.device_close() ``` -------------------------------- ### CMake Project Configuration Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/CMakeLists.txt Sets up the CMake build environment for the project. Ensures the ic4 library is available and includes example subdirectories. ```cmake cmake_minimum_required(VERSION 3.16) project( ic4-examples-cpp ) find_package( ic4 CONFIG REQUIRED ) add_subdirectory( advanced-camera-features/action-command-broadcast-trigger ) add_subdirectory( advanced-camera-features/connect-chunkdata ) add_subdirectory( advanced-camera-features/event-exposure-end ) add_subdirectory( advanced-camera-features/event-line1-edge ) add_subdirectory( device-handling/device-enumeration ) add_subdirectory( device-handling/device-list-changed ) add_subdirectory( device-handling/device-lost ) add_subdirectory( image-acquisition/record-mp4-h264 ) add_subdirectory( image-acquisition/save-bmp-on-trigger ) add_subdirectory( image-acquisition/save-jpeg-file ) add_subdirectory( image-acquisition/measure-fps ) add_subdirectory( qt6 ) find_package( OpenCV CONFIG ) if( OpenCV_FOUND ) add_subdirectory( thirdparty-integration/imagebuffer-opencv-snap ) endif() ``` -------------------------------- ### Configure Hardware Trigger Mode in C# Source: https://context7.com/theimagingsource/ic4-examples/llms.txt This C# example demonstrates how to enable and use hardware triggers for image acquisition. Ensure the ic4 library is referenced. ```csharp using ic4; ic4.Library.Init(); var grabber = new ic4.Grabber(); grabber.DeviceOpen(ic4.DeviceEnum.Devices.First()); var propertyMap = grabber.DevicePropertyMap; // Configure trigger mode try { propertyMap.SetValue(ic4.PropId.TriggerSelector, "FrameStart"); } catch { } propertyMap.SetValue(ic4.PropId.TriggerMode, "On"); var sink = new ic4.QueueSink(); int imageCount = 0; sink.FramesQueued += (sender, e) => { if (sink.TryPopOutputBuffer(out ic4.ImageBuffer buffer)) { buffer.SaveAsBitmap($"triggered_{imageCount}.bmp"); Console.WriteLine($"Saved triggered image {imageCount}"); buffer.Dispose(); imageCount++; } }; grabber.StreamSetup(sink, StreamSetupOption.AcquisitionStart); Console.WriteLine("Press Enter for software trigger, 'q' + Enter to quit"); while (Console.ReadLine() != "q") { propertyMap.ExecuteCommand(ic4.PropId.TriggerSoftware); } grabber.StreamStop(); propertyMap.SetValue(ic4.PropId.TriggerMode, "Off"); grabber.DeviceClose(); ``` -------------------------------- ### Begin Video File Recording Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/record-mp4-h264/README.md Start a new video file by calling VideoWriter::beginFile. Provide the file name, buffer format, and playback rate. The image type and frame rate are obtained beforehand. ```cpp video_writer->beginFile("record-mp4-h264.mp4", buffer_info, frame_rate); ``` -------------------------------- ### Install opencv-python Source: https://github.com/theimagingsource/ic4-examples/blob/master/python/thirdparty-integration/README.md Use this command to install the opencv-python package into your Python environment. ```bash pip install opencv-python ``` -------------------------------- ### Create VideoWriter for MP4 H264 Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/record-mp4-h264/README.md Create a VideoWriter object specifying the desired file type and encoder. This example creates MP4 files with H264 encoding. ```cpp auto video_writer = ic4::VideoWriter::create( ic4::VideoWriter::kTypeMP4, ic4::VideoWriter::kCodecH264); ``` -------------------------------- ### Capture and Save Single Images with SnapSink (C#) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt This C# example shows how to capture single image frames using SnapSink. It utilizes the `using var` syntax for automatic disposal of the buffer. Ensure the ic4 namespace is imported. ```csharp using ic4; ic4.Library.Init(); var grabber = new ic4.Grabber(); grabber.DeviceOpen(ic4.DeviceEnum.Devices.First()); // Create snap sink var sink = new ic4.SnapSink(); // Start stream grabber.StreamSetup(sink, StreamSetupOption.AcquisitionStart); // Snap images for (int i = 0; i < 5; i++) { using var buffer = sink.SnapSingle(1000); // Save as BMP buffer.SaveAsBitmap($"image_{i}.bmp"); // Save as JPEG buffer.SaveAsJpeg($"image_{i}.jpg", 90); Console.WriteLine($"Saved image {i}"); } grabber.StreamStop(); grabber.DeviceClose(); ``` -------------------------------- ### CMakeLists.txt for Device Enumeration Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/device-handling/device-enumeration/CMakeLists.txt This CMakeLists.txt file configures a C++ project to use the ic4 library for device enumeration. Ensure the ic4 package is installed and discoverable by CMake. ```cmake cmake_minimum_required(VERSION 3.10) project("device-enumeration") find_package( ic4 REQUIRED ) add_executable( device-enumeration "src/device-enumeration.cpp" ) target_include_directories( device-enumeration PRIVATE "../../common" ) target_link_libraries( device-enumeration PRIVATE ic4::core ) set_target_properties( device-enumeration PROPERTIES CXX_STANDARD 14 ) ic4_copy_runtime_to_target(device-enumeration) ``` -------------------------------- ### Build C++ Executable with IC4 Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/save-jpeg-file/CMakeLists.txt This CMakeLists.txt file configures a C++ executable that uses the IC4 library. Ensure IC4 is installed and findable by CMake. ```cmake cmake_minimum_required(VERSION 3.10) project("save-image-file") find_package( ic4 REQUIRED ) add_executable( save-jpeg-file "src/save-jpeg-file.cpp" ) target_include_directories( save-jpeg-file PRIVATE "../../common" ) target_link_libraries( save-jpeg-file PRIVATE ic4::core ) set_target_properties( save-jpeg-file PROPERTIES CXX_STANDARD 14 ) ic4_copy_runtime_to_target(save-jpeg-file) ``` -------------------------------- ### Handle Device Lost Event in C# Source: https://context7.com/theimagingsource/ic4-examples/llms.txt This C# example demonstrates registering an event handler for device disconnections. The event fires when a camera is unplugged or becomes unavailable. ```csharp using ic4; ic4.Library.Init(); var grabber = new ic4.Grabber(); grabber.DeviceOpen(ic4.DeviceEnum.Devices.First()); // Register device lost event grabber.DeviceLost += (sender, e) => { Console.WriteLine("DEVICE LOST! Camera disconnected."); }; Console.WriteLine($"Opened: {grabber.DeviceInfo.ModelName}"); Console.WriteLine("Disconnect camera to trigger event. Press Enter to exit."); Console.ReadLine(); grabber.DeviceClose(); ``` -------------------------------- ### CMake Configuration for Save BMP Example Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/save-bmp-on-trigger/CMakeLists.txt Configures the CMake build system for the save-bmp-on-trigger project. It finds the ic4 package, defines the executable, sets include directories and link libraries, and specifies the C++ standard. ```cmake cmake_minimum_required(VERSION 3.10) project("save-bmp-on-trigger") find_package( ic4 REQUIRED ) add_executable( save-bmp-on-trigger "src/save-bmp-on-trigger.cpp" ) target_include_directories( save-bmp-on-trigger PRIVATE "../../common" ) target_link_libraries( save-bmp-on-trigger PRIVATE ic4::core ) set_target_properties( save-bmp-on-trigger PROPERTIES CXX_STANDARD 14 ) ic4_copy_runtime_to_target(save-bmp-on-trigger) ``` -------------------------------- ### Handle Device Lost Event in C++ Source: https://context7.com/theimagingsource/ic4-examples/llms.txt This C++ example shows how to register a handler for the device lost event, which is triggered upon camera disconnection. Ensure ic4 library is linked. ```cpp #include #include static void device_lost_handler(ic4::Grabber& grabber) { std::cout << "DEVICE LOST! Camera disconnected." << std::endl; } int main() { ic4::initLibrary(); std::atexit(ic4::exitLibrary); auto devices = ic4::DeviceEnum::enumDevices(); ic4::Grabber grabber; grabber.deviceOpen(devices[0]); // Register device lost handler auto token = grabber.eventAddDeviceLost(device_lost_handler); std::cout << "Opened: " << grabber.deviceInfo().modelName() << std::endl; std::cout << "Disconnect camera to trigger event. Press Enter to exit." << std::endl; std::getchar(); // Unregister handler grabber.eventRemoveDeviceLost(token); return 0; } ``` -------------------------------- ### Open a Device with Grabber Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Demonstrates how to enumerate available devices and open a connection using the Grabber class. ```python import imagingcontrol4 as ic4 with ic4.Library.init_context(): # Get available devices device_list = ic4.DeviceEnum.devices() if not device_list: print("No devices found") exit() # Select first device dev_info = device_list[0] # Method 1: Create grabber and open device separately grabber = ic4.Grabber() grabber.device_open(dev_info) # Access device info print(f"Opened: {grabber.device_info.model_name}") # Method 2: Open device in constructor grabber2 = ic4.Grabber(dev_info) # Close device when done grabber.device_close() grabber2.device_close() ``` ```cpp #include #include int main() { ic4::initLibrary(); std::atexit(ic4::exitLibrary); auto device_list = ic4::DeviceEnum::enumDevices(); if (device_list.empty()) { std::cerr << "No devices found" << std::endl; return -1; } ic4::Error err; ic4::Grabber grabber; // Open with error handling if (!grabber.deviceOpen(device_list[0], err)) { std::cerr << "Failed to open device: " << err.message() << std::endl; return -2; } std::cout << "Opened: " << grabber.deviceInfo().modelName() << std::endl; grabber.deviceClose(); return 0; } ``` ```csharp using ic4; ic4.Library.Init(); var deviceList = ic4.DeviceEnum.Devices.ToList(); if (deviceList.Count == 0) { Console.WriteLine("No devices found"); return; } var grabber = new ic4.Grabber(); grabber.DeviceOpen(deviceList[0]); Console.WriteLine($"Opened: {grabber.DeviceInfo.ModelName}"); // Check device state if (grabber.IsDeviceValid) { Console.WriteLine("Device is valid"); } grabber.DeviceClose(); ``` -------------------------------- ### Initialize IC4 Library (Python) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Initializes the IC4 library. Use the context manager for automatic cleanup. Logging is configured to INFO level and output to STDERR. ```python import imagingcontrol4 as ic4 # Method 1: Manual initialization and cleanup ic4.Library.init(api_log_level=ic4.LogLevel.INFO, log_targets=ic4.LogTarget.STDERR) try: # Your code here pass finally: ic4.Library.exit() # Method 2: Context manager (recommended) with ic4.Library.init_context(api_log_level=ic4.LogLevel.INFO, log_targets=ic4.LogTarget.STDERR): # Your code here - library automatically cleaned up on exit pass ``` -------------------------------- ### Qt6/PySide6 GUI Integration Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Build desktop applications with live video display using Qt6 widgets and pre-built dialogs. Requires PySide6 and imagingcontrol4 libraries. ```python from PySide6.QtWidgets import QApplication, QMainWindow, QDialog import imagingcontrol4 as ic4 class CameraWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setWindowTitle("IC4 Qt6 Camera Viewer") self.resize(1024, 768) # Create grabber self.grabber = ic4.Grabber() # Show device selection dialog dlg = ic4.pyside6.DeviceSelectionDialog(self.grabber, self) if dlg.exec() != QDialog.Accepted: return # Create display widget display_widget = ic4.pyside6.DisplayWidget() self.setCentralWidget(display_widget) # Configure display display = display_widget.as_display() display.set_render_position(ic4.DisplayRenderPosition.STRETCH_CENTER) # Reset camera to defaults try: self.grabber.device_property_map.set_value(ic4.PropId.USER_SET_SELECTOR, "Default") self.grabber.device_property_map.execute_command(ic4.PropId.USER_SET_LOAD) except ic4.IC4Exception: pass # Start live stream to display self.grabber.stream_setup(None, display) if __name__ == "__main__": from sys import argv app = QApplication(argv) app.setStyle("fusion") with ic4.Library.init_context(): window = CameraWindow() window.show() app.exec() ``` -------------------------------- ### Open Video Capture Device Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/save-bmp-on-trigger/README.md Initializes the video capture device using a helper function. ```cpp auto device_list = DeviceEnum::enumerate(); if (device_list.empty()) { std::cout << "No device found" << std::endl; return 1; } auto device = device_list[0]; std::cout << "Using device: " << device.modelName() << std::endl; auto grabber = std::make_shared(); grabber->deviceOpen(device); if (!grabber->deviceIsOpen()) { std::cout << "Failed to open device" << std::endl; return 1; } ``` -------------------------------- ### CMake build configuration for event-line1-edge Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/advanced-camera-features/event-line1-edge/CMakeLists.txt Defines the project structure and dependencies for the event-line1-edge executable. Requires the ic4 package to be installed and available in the environment. ```cmake cmake_minimum_required(VERSION 3.10) project("event-line1-edge") find_package( ic4 REQUIRED ) add_executable( event-line1-edge "src/event-line1-edge.cpp" ) target_include_directories( event-line1-edge PRIVATE "../../common" ) target_link_libraries( event-line1-edge PRIVATE ic4::core ) set_target_properties( event-line1-edge PROPERTIES CXX_STANDARD 14 ) ic4_copy_runtime_to_target(event-line1-edge) ``` -------------------------------- ### CMake Project Configuration Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/camera-specific/dolp-segmentation/CMakeLists.txt Configures the project, finds required packages, and sets up build targets for a Qt6 and ic4 application. ```cmake cmake_minimum_required(VERSION 3.16) project(dolpsegmentation) set(PROJECT_NAME dolpsegmentation) # set( CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL" ) find_package( ic4 REQUIRED ) # This path probably will not be valid on your system. # If cmake complains about not able to find Qt6, point it into your Qt6 installation directory. list(APPEND CMAKE_PREFIX_PATH "c:/source/qt/qt6/6.5.2/msvc2019_64/lib/cmake/") list(APPEND CMAKE_PREFIX_PATH "C:/Qt/6.6.0/msvc2019_64/") set(QT_REQUIRED_TOP_LEVEL ${PROJECT_IS_TOP_LEVEL}) include( ../../qt6/common/setup_qt.cmake ) find_package(Qt6 REQUIRED COMPONENTS Core Widgets) if( NOT TARGET qt6-dialogs ) add_subdirectory(../../qt6/common/qt6-dialogs ${CMAKE_BINARY_DIR}/qt6-dialogs) endif() # qt_standard_project_setup() qt_add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp sliderctrl.h main.rc ) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Widgets Qt6::Core ic4::core qt6-dialogs ) if (WIN32) target_link_libraries(${PROJECT_NAME} PRIVATE shell32 ) set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE ON CXX_STANDARD 17 ) ic4_copy_runtime_to_target(${PROJECT_NAME}) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND "${Qt6_DIR}/../../../bin/windeployqt.exe" --verbose 0 --no-compiler-runtime --no-translations --no-system-d3d-compiler --no-opengl-sw $ COMMENT "Deploying Qt..." ) endif() ``` -------------------------------- ### Initialize IC4 Library (C#) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Initializes the IC4 library. Ensure proper cleanup is handled by the application's lifecycle. ```csharp using ic4; class Program { static void Main(string[] args) { ic4.Library.Init(); // Your code here } } ``` -------------------------------- ### Configure Camera Properties Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Shows how to access the PropertyMap to modify camera settings such as resolution, frame rate, and exposure. ```python import imagingcontrol4 as ic4 with ic4.Library.init_context(): grabber = ic4.Grabber(ic4.DeviceEnum.devices()[0]) map = grabber.device_property_map # Reset to default settings map.try_set_value(ic4.PropId.USER_SET_SELECTOR, "Default") map.try_set_value(ic4.PropId.USER_SET_LOAD, 1) # Configure resolution map.try_set_value(ic4.PropId.WIDTH, 1920) map.try_set_value(ic4.PropId.HEIGHT, 1080) # Configure frame rate map.try_set_value(ic4.PropId.ACQUISITION_FRAME_RATE, 30.0) # Configure exposure map.set_value(ic4.PropId.EXPOSURE_AUTO, "Off") map.set_value(ic4.PropId.EXPOSURE_TIME, 10000.0) # 10ms in microseconds # Read property values width = map[ic4.PropId.WIDTH].value height = map[ic4.PropId.HEIGHT].value fps = map[ic4.PropId.ACQUISITION_FRAME_RATE].value exp = map.get_value_float(ic4.PropId.EXPOSURE_TIME) print(f"Resolution: {width}x{height}") print(f"Frame Rate: {fps} fps") print(f"Exposure: {exp} us") # Get property range width_prop = map[ic4.PropId.WIDTH] print(f"Width range: {width_prop.minimum} - {width_prop.maximum}") grabber.device_close() ``` ```cpp #include #include int main() { ic4::initLibrary(); std::atexit(ic4::exitLibrary); auto devices = ic4::DeviceEnum::enumDevices(); ic4::Grabber grabber; grabber.deviceOpen(devices[0]); auto& map = grabber.devicePropertyMap(); // Configure resolution map.setValue(ic4::PropId::Width, 1920); map.setValue(ic4::PropId::Height, 1080); // Configure exposure map.setValue(ic4::PropId::ExposureAuto, "Off"); map.setValue(ic4::PropId::ExposureTime, 10000.0); // Read values auto width = map.find(ic4::PropId::Width).getValue(); auto height = map.find(ic4::PropId::Height).getValue(); auto frameRate = map.find(ic4::PropId::AcquisitionFrameRate).getValue(); std::cout << "Resolution: " << width << "x" << height << std::endl; std::cout << "Frame Rate: " << frameRate << " fps" << std::endl; grabber.deviceClose(); return 0; } ``` ```csharp using ic4; ic4.Library.Init(); var grabber = new ic4.Grabber(); grabber.DeviceOpen(ic4.DeviceEnum.Devices.First()); var propertyMap = grabber.DevicePropertyMap; // Reset to defaults (ignore errors if not supported) try { propertyMap.SetValue(ic4.PropId.UserSetSelector, "Default"); propertyMap.ExecuteCommand(ic4.PropId.UserSetLoad); } catch { } // Configure settings propertyMap.SetValue(ic4.PropId.Width, 1920); propertyMap.SetValue(ic4.PropId.Height, 1080); propertyMap.SetValue(ic4.PropId.ExposureAuto, "Off"); propertyMap.SetValue(ic4.PropId.ExposureTime, 10000.0); Console.WriteLine($"Resolution: {propertyMap.GetValueLong(ic4.PropId.Width)}x{propertyMap.GetValueLong(ic4.PropId.Height)}"); grabber.DeviceClose(); ``` -------------------------------- ### Enumerate Devices (C++) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Enumerates all connected devices and devices by interface. Prints model, serial, and version details. Requires IC4 library to be initialized. ```cpp #include #include int main() { ic4::initLibrary(); std::atexit(ic4::exitLibrary); // Enumerate all devices auto device_list = ic4::DeviceEnum::enumDevices(); std::cout << "Found " << device_list.size() << " devices:" << std::endl; for (auto&& dev_info : device_list) { std::cout << " Model: " << dev_info.modelName() << " Serial: " << dev_info.serial() << " Version: " << dev_info.version() << std::endl; } // Enumerate by interface auto interface_list = ic4::DeviceEnum::enumInterfaces(); for (auto&& itf : interface_list) { std::cout << "Interface: " << itf.interfaceDisplayName() << std::endl; auto devices = itf.enumDevices(); for (auto&& dev : devices) { std::cout << " " << dev.modelName() << std::endl; } } return 0; } ``` -------------------------------- ### Build CMake project Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/README.md Compile the application using the generated build files. ```bash ~/ic4-examples/cpp/device-handling/device-enumeration $ cmake --build build/ [ 50%] Building CXX object CMakeFiles/device-enumeration.dir/src/device-enumeration.cpp.o [100%] Linking CXX executable device-enumeration [100%] Built target device-enumeration ``` -------------------------------- ### Enumerate Devices (Python) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Enumerates all connected devices and devices by interface. Prints model, serial, and interface details. Requires IC4 library to be initialized. ```python import imagingcontrol4 as ic4 def enumerate_devices(): # Get flat list of all connected devices device_list = ic4.DeviceEnum.devices() if len(device_list) == 0: print("No devices found") return print(f"Found {len(device_list)} devices:") for device_info in device_list: print(f" Model: {device_info.model_name}") print(f" Serial: {device_info.serial}") print(f" Interface: {device_info.interface.display_name}") # Enumerate by interface for more detail interface_list = ic4.DeviceEnum.interfaces() for itf in interface_list: print(f"Interface: {itf.display_name}") print(f" Transport Layer: {itf.transport_layer_name}") print(f" Type: {itf.transport_layer_type}") for dev in itf.devices: print(f" Device: {dev.model_name} ({dev.serial})") with ic4.Library.init_context(): enumerate_devices() ``` -------------------------------- ### Capture and Save Single Images with SnapSink (Python) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Use SnapSink to capture individual frames on demand. This is ideal for still image capture applications where you need to grab single images. Ensure the imagingcontrol4 library is installed. ```python import imagingcontrol4 as ic4 with ic4.Library.init_context(): grabber = ic4.Grabber(ic4.DeviceEnum.devices()[0]) # Create a snap sink for manual buffer capture sink = ic4.SnapSink() # Start data stream from device to sink grabber.stream_setup(sink) # Snap and save multiple images for i in range(5): # Grab the next image buffer (1000ms timeout) buffer = sink.snap_single(1000) # Save as JPEG with quality setting buffer.save_as_jpeg(f"image_{i}.jpeg", quality_pct=90) # Save as BMP buffer.save_as_bmp(f"image_{i}.bmp") # Save as PNG buffer.save_as_png(f"image_{i}.png") # Access buffer metadata print(f"Frame {buffer.meta_data.device_frame_number}") print(f" Timestamp: {buffer.meta_data.device_timestamp_ns} ns") print(f" Size: {buffer.image_type.width}x{buffer.image_type.height}") grabber.stream_stop() grabber.device_close() ``` -------------------------------- ### Access Chunk Data and Metadata in Python Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Demonstrates how to enable chunk mode and extract per-frame metadata such as exposure time using a QueueSinkListener. ```python import imagingcontrol4 as ic4 import time class ChunkDataListener(ic4.QueueSinkListener): def __init__(self, prop_map: ic4.PropertyMap): self.prop_map = prop_map def sink_connected(self, sink: ic4.QueueSink, image_type: ic4.ImageType, min_buffers_required: int) -> bool: return True def frames_queued(self, sink: ic4.QueueSink): try: buffer = sink.pop_output_buffer() # Connect chunk data from buffer to property map self.prop_map.connect_chunkdata(buffer) # Read chunk properties exposure = self.prop_map.get_value_float(ic4.PropId.CHUNK_EXPOSURE_TIME) print(f"ChunkExposureTime = {exposure} us") except ic4.IC4Exception as ex: print(f"Error: {ex.message}") finally: # Disconnect to release buffer for reuse self.prop_map.connect_chunkdata(None) with ic4.Library.init_context(): grabber = ic4.Grabber(ic4.DeviceEnum.devices()[0]) prop_map = grabber.device_property_map # Check for chunk support try: prop_map.find_float(ic4.PropId.CHUNK_EXPOSURE_TIME) except: print("ChunkExposureTime not supported") exit() # Enable chunk mode prop_map.set_value(ic4.PropId.CHUNK_MODE_ACTIVE, True) prop_map.set_value(ic4.PropId.CHUNK_SELECTOR, "ExposureTime") prop_map.try_set_value(ic4.PropId.CHUNK_ENABLE, True) # Configure exposure prop_map.set_value(ic4.PropId.EXPOSURE_AUTO, "Off") prop_map.set_value(ic4.PropId.EXPOSURE_TIME, 5000) # 5ms listener = ChunkDataListener(prop_map) sink = ic4.QueueSink(listener) grabber.stream_setup(sink) print("Streaming with chunk data for 3 seconds...") time.sleep(3) grabber.stream_stop() grabber.device_close() ``` -------------------------------- ### Integrate IC4 Image Buffers with OpenCV (Python) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Integrate IC4 image buffers with OpenCV for advanced image processing. This example demonstrates zero-copy wrapping of IC4 buffers into NumPy arrays for use with OpenCV functions. ```python import imagingcontrol4 as ic4 import cv2 import numpy as np with ic4.Library.init_context(): grabber = ic4.Grabber(ic4.DeviceEnum.devices()[0]) cv2.namedWindow("IC4 + OpenCV") sink = ic4.SnapSink() grabber.stream_setup(sink) for i in range(10): print("Press any key in OpenCV window to capture...") cv2.waitKey(0) # Snap image buffer = sink.snap_single(1000) # Wrap as numpy array (zero-copy) np_array = buffer.numpy_wrap() # Display original cv2.imshow("IC4 + OpenCV", np_array) cv2.waitKey(1000) # Apply OpenCV processing (in-place modifies buffer memory) cv2.blur(np_array, (25, 25), np_array) # Display processed cv2.imshow("IC4 + OpenCV", np_array) cv2.destroyAllWindows() grabber.stream_stop() grabber.device_close() ``` -------------------------------- ### Configure Camera Trigger Settings Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/save-bmp-on-trigger/README.md Resets camera settings to factory defaults and enables FrameStart trigger mode. ```cpp auto& prop_map = grabber->devicePropertyMap(); // Load factory defaults prop_map.setValue("UserSetSelector", "Default"); prop_map.executeCommand("UserSetLoad"); // Configure trigger prop_map.setValue("TriggerSelector", "FrameStart"); prop_map.setValue("TriggerMode", "On"); prop_map.setValue("TriggerSource", "Software"); ``` -------------------------------- ### Integrate IC4 Image Buffers with OpenCV (C++) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Integrate IC4 image buffers with OpenCV for advanced image processing using C++. This example shows zero-copy wrapping of IC4 buffers into cv::Mat objects. ```cpp #include #include #include #include int main() { ic4::initLibrary(); auto devices = ic4::DeviceEnum::enumDevices(); ic4::Grabber grabber; grabber.deviceOpen(devices[0]); cv::namedWindow("display"); // Create sink that converts to BGR8 for OpenCV auto sink = ic4::SnapSink::create(ic4::PixelFormat::BGR8); grabber.streamSetup(sink); for (int i = 0; i < 5; ++i) { std::cout << "Press any key to capture..." << std::endl; cv::waitKey(0); auto buffer = sink->snapSingle(1000); // Wrap buffer as cv::Mat (zero-copy) auto mat = ic4interop::OpenCV::wrap(*buffer); cv::imshow("display", mat); cv::waitKey(1000); // Process with OpenCV cv::blur(mat, mat, cv::Size(25, 25)); cv::imshow("display", mat); } grabber.streamStop(); ic4::exitLibrary(); return 0; } ``` -------------------------------- ### Define Static Library Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/qt6/common/qt6-dialogs/CMakeLists.txt Defines a static library named 'qt6-dialogs' and lists its source files and resources. Ensure all listed files exist. ```cmake add_library(qt6-dialogs STATIC ${QT6DIALOGS_RESOURCES} controls/Event.h controls/FormGroupBox.h controls/IPConfigGroupBox.cpp controls/IPConfigGroupBox.h controls/PropertyInfoBox.h controls/SwitchDriverGroupBox.cpp controls/SwitchDriverGroupBox.h controls/PropertyTreeWidget.cpp controls/PropertyTreeWidget.h controls/PropertyControls.h controls/PropertyControls.cpp controls/props/PropIntControl.h controls/props/PropIntSpinBox.h controls/props/PropEnumerationControl.h controls/props/PropControlBase.h controls/props/PropStringControl.h controls/props/PropCommandControl.h controls/props/PropBooleanControl.h controls/props/PropFloatControl.h controls/props/PropCategoryControl.h DeviceSelectionDialog.h DeviceSelectionDialog.cpp PropertyDialog.h PropertyDialog.cpp ) ``` -------------------------------- ### Enumerate Devices (C#) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Enumerates all connected devices and devices by interface. Prints model, serial, version, and interface details. Requires IC4 library to be initialized. ```csharp using System; using System.Linq; ic4.Library.Init(); // Enumerate all devices var deviceList = ic4.DeviceEnum.Devices.ToList(); Console.WriteLine($"Found {deviceList.Count} devices:"); foreach (var deviceInfo in deviceList) { Console.WriteLine($" Model: {deviceInfo.ModelName}"); Console.WriteLine($" Serial: {deviceInfo.Serial}"); Console.WriteLine($" Version: {deviceInfo.Version}"); } // Enumerate by interface var interfaceList = ic4.DeviceEnum.Interfaces.ToList(); foreach (var itf in interfaceList) { Console.WriteLine($"Interface: {itf.DisplayName}"); Console.WriteLine($" Transport Layer: {itf.TransportLayerName}"); Console.WriteLine($" Type: {itf.TransportLayerType}"); foreach (var dev in itf.Devices) { Console.WriteLine($" Device: {dev.ModelName} ({dev.Serial})"); } } ``` -------------------------------- ### Synchronize GigE Cameras with Action Commands (Python) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Use GigE Vision action commands to trigger multiple cameras simultaneously over the network. Ensure DEVICE_KEY, GROUP_KEY, and GROUP_MASK match camera configurations. ```python import imagingcontrol4 as ic4 import time with ic4.Library.init_context(): # Filter for GigE Vision interfaces only all_interfaces = ic4.DeviceEnum.interfaces() gige_interfaces = [itf for itf in all_interfaces if itf.transport_layer_type == ic4.TransportLayerType.GIGEVISION] if not gige_interfaces: print("No GigE Vision interfaces found") exit() itf = gige_interfaces[0] if not itf.devices: print("No GigE cameras found") exit() # Action command parameters (must match camera configuration) DEVICE_KEY = 0x00000123 GROUP_KEY = 0x00000456 GROUP_MASK = 0x00000001 # Configure interface for action command broadcast itf.property_map.set_value(ic4.PropId.ACTION_DEVICE_KEY, DEVICE_KEY) itf.property_map.set_value(ic4.PropId.ACTION_GROUP_KEY, GROUP_KEY) itf.property_map.set_value(ic4.PropId.ACTION_GROUP_MASK, GROUP_MASK) itf.property_map.set_value("ActionScheduledTimeEnable", False) grabbers = [] # Configure each camera for action command triggering for idx, dev in enumerate(itf.devices): grabber = ic4.Grabber() grabber.device_open(dev) map = grabber.device_property_map # Configure action command settings map.set_value(ic4.PropId.ACTION_SELECTOR, 0) map.set_value(ic4.PropId.ACTION_DEVICE_KEY, DEVICE_KEY) map.set_value(ic4.PropId.ACTION_GROUP_KEY, GROUP_KEY) map.set_value(ic4.PropId.ACTION_GROUP_MASK, GROUP_MASK) # Enable trigger from Action0 map.set_value(ic4.PropId.TRIGGER_MODE, "On") map.set_value(ic4.PropId.TRIGGER_SOURCE, "Action0") # Setup stream with simple listener class Listener(ic4.QueueSinkListener): def __init__(self, cam_idx): self.cam_idx = cam_idx def sink_connected(self, sink, image_type, min_buffers_required): return True def frames_queued(self, sink): buffer = sink.pop_output_buffer() print(f"Camera {self.cam_idx}: Frame {buffer.meta_data.device_frame_number}") sink = ic4.QueueSink(Listener(idx)) grabber.stream_setup(sink) grabbers.append(grabber) print(f"Configured {len(grabbers)} cameras for synchronized capture") # Send action commands to trigger all cameras simultaneously for i in range(5): print(f"Sending action command {i+1}...") itf.property_map.execute_command("ActionCommand") time.sleep(0.5) # Cleanup for grabber in grabbers: grabber.stream_stop() grabber.device_close() ``` -------------------------------- ### Initialize IC4 Library (C++) Source: https://context7.com/theimagingsource/ic4-examples/llms.txt Initializes the IC4 library and registers a cleanup function using std::atexit for automatic cleanup upon program exit. ```cpp #include #include int main() { // Initialize library ic4::initLibrary(); // Register cleanup function std::atexit(ic4::exitLibrary); // Your code here return 0; } ``` -------------------------------- ### Create QueueSink Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/image-acquisition/record-mp4-h264/README.md Create a QueueSink by passing an instance of your QueueSinkListener to QueueSink::create. This sink is used to access image buffers from the video capture device. ```cpp auto listener = std::make_unique(do_write_frames); auto sink = ic4::QueueSink::create(std::move(listener)); ``` -------------------------------- ### Configure CMake project Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/README.md Generate build files for the project using CMake in the command line. ```bash ~/ic4-examples/cpp/device-handling/device-enumeration $ cmake -B build/ . -- The C compiler identification is GNU 13.2.0 -- The CXX compiler identification is GNU 13.2.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done (...) -- Configuring done (1.3s) -- Generating done (0.0s) -- Build files have been written to: ~/ic4-examples/cpp/device-handling/device-enumeration/build ``` -------------------------------- ### CMake Build Configuration for Event Exposure Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/advanced-camera-features/event-exposure-end/CMakeLists.txt This CMake script sets up the build environment for the event-exposure-end executable. It finds the IC4 package, adds the executable source file, specifies include directories, links against the IC4 core library, sets the C++ standard, and copies runtime components. ```cmake cmake_minimum_required(VERSION 3.10) project("event-exposure-end") find_package( ic4 REQUIRED ) add_executable( event-exposure-end "src/event-exposure-end.cpp" ) target_include_directories( event-exposure-end PRIVATE "../../common" ) target_link_libraries( event-exposure-end PRIVATE ic4::core ) set_target_properties( event-exposure-end PROPERTIES CXX_STANDARD 14 ) ic4_copy_runtime_to_target(event-exposure-end) ``` -------------------------------- ### CMake build configuration for High-Speed Capture Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/qt6/high-speed-capture/CMakeLists.txt Configures the project to link against ic4 and Qt6, ensuring necessary components are present and setting up Windows-specific deployment commands. ```cmake cmake_minimum_required(VERSION 3.16) project(high-speed-capture) find_package( ic4 CONFIG REQUIRED ) set(QT_REQUIRED_TOP_LEVEL ${PROJECT_IS_TOP_LEVEL}) include( ../common/setup_qt.cmake ) if( NOT Qt6_FOUND ) if(PROJECT_IS_TOP_LEVEL) message( FATAL_ERROR "HighSpeedCapture depends on Qt6") else() message( WARNING "The HighSpeedCapture example needs at least Qt6") endif() return() endif() find_package(Qt6 REQUIRED COMPONENTS Concurrent) if( NOT TARGET qt6-dialogs ) add_subdirectory(../common/qt6-dialogs ${CMAKE_BINARY_DIR}/demoapp-qt6-dialogs) endif() add_executable(high-speed-capture "HighSpeedCaptureDialog.h" "HighSpeedCaptureDialog.cpp" "main.cpp" ) target_link_libraries(high-speed-capture PRIVATE Qt6::Core Qt6::Widgets Qt6::Concurrent) target_link_libraries(high-speed-capture PRIVATE ic4::core qt6-dialogs ) set_target_properties(high-speed-capture PROPERTIES CXX_STANDARD 17 ) if (WIN32) set_target_properties(high-speed-capture PROPERTIES WIN32_EXECUTABLE ON ) ic4_copy_runtime_to_target(high-speed-capture) add_windeployqt_custom_command(high-speed-capture) # Adds a POST_BUILD call to windeployqt.exe endif () ``` -------------------------------- ### Add Qt Resources Source: https://github.com/theimagingsource/ic4-examples/blob/master/cpp/qt6/common/qt6-dialogs/CMakeLists.txt Compiles Qt resource files (.qrc) into C++ code. This makes resources available to the application. ```cmake qt_add_resources(QT6DIALOGS_RESOURCES qt6dialogs.qrc) ```