### Install OpenCV (Ubuntu Apt) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Install OpenCV development files and Python bindings on Ubuntu using apt-get. This is necessary for samples that utilize OpenCV. ```bash sudo apt-get install libopencv-dev sudo apt-get install python3-opencv ``` -------------------------------- ### Install OpenCV (Python) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Install OpenCV for Python if your samples depend on it. This is an optional but recommended step for computer vision tasks. ```bash pip install opencv-python ``` -------------------------------- ### Install Mech-Eye API (Python) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Use this command to install the Mech-Eye API for Python. Ensure your Python version is compatible. ```bash pip install MechEyeAPI ``` -------------------------------- ### Install Mech-Eye SDK (Ubuntu) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/area_scan_3d_camera/README.md Install the Mech-Eye SDK on Ubuntu using dpkg. Ensure you use the correct .deb file for your system architecture (amd64 or arm64). ```bash sudo dpkg -i 'Mech-Eye_API_x.x.x_amd64.deb' ``` ```bash sudo dpkg -i 'Mech-Eye_API_x.x.x_arm64.deb' ``` -------------------------------- ### Install Mech-Eye SDK (Ubuntu AMD64) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Install the Mech-Eye SDK on Ubuntu systems with an AMD64 architecture using the provided .deb package. Ensure you have uninstalled any previous versions. ```bash sudo dpkg -i 'Mech-Eye_API_x.x.x_amd64.deb' ``` -------------------------------- ### Install Mech-Eye API (Ubuntu Bash) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Install the Mech-Eye API for Python on Ubuntu using pip3. This command requires root privileges. ```bash sudo pip3 install MechEyeApi ``` -------------------------------- ### Install Mech-Eye SDK (Ubuntu ARM64) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Install the Mech-Eye SDK on Ubuntu systems with an ARM64 architecture using the provided .deb package. Ensure you have uninstalled any previous versions. ```bash sudo dpkg -i 'Mech-Eye_API_x.x.x_arm64.deb' ``` -------------------------------- ### Upgrade g++ (Ubuntu) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/area_scan_3d_camera/README.md Upgrade g++ to version 12 or above on Ubuntu by adding a PPA, installing the desired version, and configuring alternatives. ```bash sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install g++-13 ``` ```bash ls usr/bin/g++* ``` ```bash sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 10 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 20 ``` ```bash sudo update-alternatives --config g++ ``` ```bash g++ --version ``` -------------------------------- ### Acquire Profiles Asynchronously with Callback Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Implement a custom callback class to receive ProfileBatch objects asynchronously. Register the callback before starting acquisition and trigger the software to begin data collection. ```python from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect, confirm_capture from multiprocessing import Lock from time import sleep mutex = Lock() class MyCallback(AcquisitionCallbackBase): def __init__(self, width): super().__init__() self.profile_batch = ProfileBatch(width) def run(self, batch): with mutex: if not batch.get_error_status().is_ok(): show_error(batch.get_error_status()) else: self.profile_batch.append(batch) profiler = Profiler() if find_and_connect(profiler) and confirm_capture(): user_set = profiler.current_user_set() show_error(user_set.set_int_value(CallbackRetrievalTimeout.name, 60000)) _, data_width = user_set.get_int_value(DataPointsPerProfile.name) callback = MyCallback(data_width) show_error(profiler.register_acquisition_callback(callback)) profiler.start_acquisition() profiler.trigger_software() while True: with mutex: if not callback.profile_batch.is_empty(): break sleep(0.5) profiler.stop_acquisition() print(f"Collected {callback.profile_batch.height()} profiles via callback.") profiler.disconnect() ``` -------------------------------- ### Get Camera Intrinsics Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Retrieve camera intrinsics, including the depth camera matrix (fx, fy, cx, cy), which is essential for manual point cloud reprojection. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, print_camera_intrinsics camera = Camera() if find_and_connect(camera): intrinsics = CameraIntrinsics() show_error(camera.get_camera_intrinsics(intrinsics)) print_camera_intrinsics(intrinsics) # Output: # Depth camera matrix: fx=1500.0, fy=1500.0, cx=1024.0, cy=768.0 camera.disconnect() ``` -------------------------------- ### Get Camera Intrinsics Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Retrieves camera intrinsic parameters, including the depth camera matrix (fx, fy, cx, cy), which are essential for manual point cloud reprojection. ```APIDOC ## Get Camera Intrinsics ### Description `camera.get_camera_intrinsics()` populates a `CameraIntrinsics` struct containing the depth camera matrix (fx, fy, cx, cy) needed for manual point cloud reprojection. ### Method ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, print_camera_intrinsics camera = Camera() if find_and_connect(camera): intrinsics = CameraIntrinsics() show_error(camera.get_camera_intrinsics(intrinsics)) print_camera_intrinsics(intrinsics) # Output: # Depth camera matrix: fx=1500.0, fy=1500.0, cx=1024.0, cy=768.0 camera.disconnect() ``` ``` -------------------------------- ### Navigate to Sample Directory Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Change to the directory containing the Mech-Eye profiler samples before running them. Replace 'xxx/profiler' with the actual path. ```bash cd xxx/profiler ``` -------------------------------- ### Navigate to Sample Directory (Windows) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/area_scan_3d_camera/README.md Change the current directory to the location of the area scan 3D camera sample on Windows. ```sh cd xxx/area_scan_3d_camera ``` -------------------------------- ### Add and Select g++ Alternatives (Ubuntu) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Manage multiple g++ versions on Ubuntu by adding them as alternatives and selecting the desired version. This is crucial for compiling samples that require a specific g++ version. ```bash sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt install g++-13 ``` ```bash ls usr/bin/g++* ``` ```bash sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 10 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 20 ``` ```bash sudo update-alternatives --config g++ ``` ```bash g++ --version ``` -------------------------------- ### Connect to Profiler Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Use `find_and_connect` for user-guided discovery or `Profiler.connect(ip)` for direct IP connection. Ensure necessary imports are included. ```python from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect profiler = Profiler() if find_and_connect(profiler): info = ProfilerInfo() show_error(profiler.get_profiler_info(info)) print(f"Connected to: {info.model}, S/N={info.sensor_sn}, IP={info.ip_address}") profiler.disconnect() print("Disconnected.") ``` -------------------------------- ### Connect and Capture All Data Types Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Demonstrates connecting to the camera, retrieving its resolutions, and capturing 2D images and 3D depth maps. Pixel-level access to image and depth data is shown by indexing into the buffers directly. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, print_camera_resolution, confirm_capture_3d camera = Camera() if find_and_connect(camera): resolution = CameraResolutions() show_error(camera.get_camera_resolutions(resolution)) print_camera_resolution(resolution) # 2D image frame2d = Frame2D() show_error(camera.capture_2d(frame2d)) color_map = frame2d.get_color_image() row, col = 222, 222 rgb = color_map[row * color_map.width() + col] print(f"RGB at ({row},{col}): R={rgb.r}, G={rgb.g}, B={rgb.b}") if confirm_capture_3d(): # Depth map frame3d = Frame3D() show_error(camera.capture_3d(frame3d)) depth_map = frame3d.get_depth_map() depth = depth_map[row * depth_map.width() + col] print(f"Depth at ({row},{col}): {depth.z:.2f} mm") # Point cloud pc = frame3d.get_untextured_point_cloud() pt = pc[row * depth_map.width() + col] print(f"Point at ({row},{col}): X={pt.x:.2f}, Y={pt.y:.2f}, Z={pt.z:.2f} mm") camera.disconnect() ``` -------------------------------- ### Run Mech-Eye Sample (Ubuntu) Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Execute a Mech-Eye sample script on Ubuntu using python3 with root privileges. Replace 'sample_name' with the specific sample file name. ```python sudo python3 sample_name.py ``` -------------------------------- ### Run Mech-Eye Sample Source: https://github.com/mechmindrobotics/mecheye_python_samples/blob/master/profiler/README.md Execute a Mech-Eye sample script. Replace 'sample_name' with the specific sample file name. ```python python sample_name.py ``` -------------------------------- ### Save Virtual Device File Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Create a `.mraw` snapshot of the camera's current state and acquisition for offline analysis using Mech-Eye Viewer. This operation may take a few minutes. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() if find_and_connect(camera): print("Saving virtual device file (may take a few minutes)...") show_error( camera.save_virtual_device_file("Camera.mraw"), "Virtual device file saved as Camera.mraw" ) camera.disconnect() ``` -------------------------------- ### Set Scanning Parameters (3D, 2D, ROI) Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Configure camera parameters like exposure, ROI, and modes using `UserSet` methods. Call `save_all_parameters_to_device()` to persist changes. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() if find_and_connect(camera): user_set = camera.current_user_set() # 3D: single exposure at 5 ms show_error(user_set.set_float_array_value(Scanning3DExposureSequence.name, [5])) # 3D ROI: top-left (0,0), 500x500 px roi = ROI(0, 0, 500, 500) show_error(user_set.set_roi_value(Scanning3DROI.name, roi)) # 2D: timed exposure at 100 ms show_error(user_set.set_enum_value(Scanning2DExposureMode.name, Scanning2DExposureMode.Value_Timed)) show_error(user_set.set_float_value(Scanning2DExposureTime.name, 100)) # Verify readback _, exposure_mode = user_set.get_enum_value_string(Scanning2DExposureMode.name) _, exposure_time = user_set.get_float_value(Scanning2DExposureTime.name) print(f"2D mode: {exposure_mode}, time: {exposure_time} ms") # Persist to device show_error(user_set.save_all_parameters_to_device(), "Parameters saved.") camera.disconnect() ``` -------------------------------- ### Discover and Connect to Mech-Eye Cameras Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Discovers all reachable cameras on the network and establishes a connection to the camera at index 0. Ensure cameras are powered on and connected to the network. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import print_camera_info camera = Camera() # Discover all cameras on the network camera_infos = Camera.discover_cameras() if not camera_infos: print("No cameras found.") exit() for i, info in enumerate(camera_infos): print(f"Camera index: {i}") print_camera_info(info) # Connect to camera at index 0 status = camera.connect(camera_infos[0]) if not status.is_ok(): show_error(status) exit() print("Connected successfully.") camera.disconnect() print("Disconnected.") ``` -------------------------------- ### Manage User Sets with Profiler Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt This snippet demonstrates how to manage user sets (named parameter groups) using the Profiler's UserSetManager. It includes listing available sets, selecting a set, and persisting current parameters to the device. ```python from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect profiler = Profiler() if find_and_connect(profiler): mgr = profiler.user_set_manager() _, user_sets = mgr.get_all_user_set_names() print("Available user sets:", user_sets) _, current = profiler.current_user_set().get_name() print("Current user set:", current) # Switch to the first available user set show_error(mgr.select_user_set(user_sets[0]), f"Switched to '{user_sets[0]}'") # Persist current parameters show_error(profiler.current_user_set().save_all_parameters_to_device(), "Saved parameters.") profiler.disconnect() ``` -------------------------------- ### Trigger Multiple Profilers Simultaneously Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt This sample demonstrates how to trigger multiple Mecheye profilers concurrently by spawning a separate process for each. Each process connects independently and performs acquisition. ```python import multiprocessing import cv2 from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect_multi_profiler, confirm_capture, save_point_cloud from time import sleep def capture_task(ip_address, sensor_sn): profiler = Profiler() if not profiler.connect(ip_address).is_ok(): return user_set = profiler.current_user_set() _, data_width = user_set.get_int_value(DataPointsPerProfile.name) _, line_count = user_set.get_int_value(ScanLineCount.name) profile_batch = ProfileBatch(data_width) profiler.start_acquisition() profiler.trigger_software() while profile_batch.height() < line_count: batch = ProfileBatch(data_width) if profiler.retrieve_batch_data(batch).is_ok(): profile_batch.append(batch) sleep(0.2) profiler.stop_acquisition() cv2.imwrite(f"depth_{sensor_sn}.png", profile_batch.get_depth_map().data()) cv2.imwrite(f"intensity_{sensor_sn}.png", profile_batch.get_intensity_image().data()) profiler.disconnect() if __name__ == "__main__": multiprocessing.set_start_method("spawn") profilers = find_and_connect_multi_profiler() if profilers and confirm_capture(): processes = [] for p in profilers: info = ProfilerInfo() show_error(p.get_profiler_info(info)) proc = multiprocessing.Process(target=capture_task, args=(info.ip_address, info.sensor_sn)) processes.append(proc) proc.start() for proc in processes: proc.join() ``` -------------------------------- ### Enable Blind Spot Filtering Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt This snippet shows how to enable blind spot filtering by setting the `EnableBlindSpotFiltering` parameter to `True` in the profiler's UserSet. This helps remove erroneous data points before saving. ```python from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect, confirm_capture import cv2 profiler = Profiler() if find_and_connect(profiler) and confirm_capture(): user_set = profiler.current_user_set() # Enable blind spot filtering show_error(user_set.set_bool_value(EnableBlindSpotFiltering.name, True)) _, data_width = user_set.get_int_value(DataPointsPerProfile.name) profile_batch = ProfileBatch(data_width) # ... perform acquisition (see trigger samples for full loop) ... cv2.imwrite("depth_filtered.tiff", profile_batch.get_depth_map().data()) cv2.imwrite("intensity_filtered.png", profile_batch.get_intensity_image().data()) profiler.disconnect() ``` -------------------------------- ### Save and Load Virtual Device Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Saves a snapshot of the camera's current state and acquisition settings to a `.mraw` file, which can be used for offline analysis and debugging. ```APIDOC ## Save Virtual Device ### Description `camera.save_virtual_device_file()` saves a `.mraw` snapshot of the camera state and current acquisition. This file can be replayed offline with Mech-Eye Viewer. ### Method ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() if find_and_connect(camera): print("Saving virtual device file (may take a few minutes)...") show_error( camera.save_virtual_device_file("Camera.mraw"), "Virtual device file saved as Camera.mraw" ) camera.disconnect() ``` ``` -------------------------------- ### Software Triggered Acquisition Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Configure software trigger and fixed rate for acquisition. Call `start_acquisition` and `trigger_software`, then poll `retrieve_batch_data` until all scan lines are collected. Save depth, intensity, and point cloud data. ```python from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect, confirm_capture, save_point_cloud import cv2 from time import sleep profiler = Profiler() if find_and_connect(profiler) and confirm_capture(): user_set = profiler.current_user_set() # Configure trigger and scan parameters show_error(user_set.set_enum_value(ExposureMode.name, ExposureMode.Value_Timed)) show_error(user_set.set_int_value(ExposureTime.name, 100)) show_error(user_set.set_enum_value(DataAcquisitionTriggerSource.name, DataAcquisitionTriggerSource.Value_Software)) show_error(user_set.set_enum_value(LineScanTriggerSource.name, LineScanTriggerSource.Value_FixedRate)) show_error(user_set.set_float_value(SoftwareTriggerRate.name, 1000)) show_error(user_set.set_int_value(ScanLineCount.name, 1600)) show_error(user_set.set_int_value(LaserPower.name, 100)) _, data_width = user_set.get_int_value(DataPointsPerProfile.name) _, line_count = user_set.get_int_value(ScanLineCount.name) profile_batch = ProfileBatch(data_width) profiler.start_acquisition() profiler.trigger_software() profile_batch.reserve(line_count) while profile_batch.height() < line_count: batch = ProfileBatch(data_width) status = profiler.retrieve_batch_data(batch) if status.is_ok(): profile_batch.append(batch) sleep(0.2) else: show_error(status) break profiler.stop_acquisition() if profile_batch.check_flag(ProfileBatch.BatchFlag_Incomplete): print(f"Incomplete batch: {profile_batch.valid_height()} valid profiles") cv2.imwrite("depth.tiff", profile_batch.get_depth_map().data()) cv2.imwrite("intensity.png", profile_batch.get_intensity_image().data()) save_point_cloud(profile_batch=profile_batch, user_set=user_set, save_ply=True, save_csv=True, is_organized=True) profiler.disconnect() ``` -------------------------------- ### Capture Point Cloud with Normals (On-Camera and Local) Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Normal vectors can be calculated on-camera via capture_3d_with_normal() or locally after a standard capture_3d(). Both paths use save_untextured_point_cloud_with_normals() to write a PLY with embedded normals. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, confirm_capture_3d camera = Camera() frame_3d = Frame3D() if find_and_connect(camera): if confirm_capture_3d(): # Method 1: normals computed on the camera if camera.capture_3d_with_normal(frame_3d).is_ok(): show_error( frame_3d.save_untextured_point_cloud_with_normals( FileFormat_PLY, "PointCloud_CameraNormals.ply" ) ) # Method 2: normals computed locally on the host if camera.capture_3d(frame_3d).is_ok(): show_error( frame_3d.save_untextured_point_cloud_with_normals( FileFormat_PLY, "PointCloud_LocalNormals.ply" ) ) camera.disconnect() ``` -------------------------------- ### Print MechEye Profiler Info and Status Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Retrieve and display profiler information (model, serial, firmware, IP) using `ProfilerInfo` and `ProfilerStatus`. Connect to the profiler first using `find_and_connect`. ```python from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect, print_profiler_info, print_profiler_status profiler = Profiler() if find_and_connect(profiler): info = ProfilerInfo() show_error(profiler.get_profiler_info(info)) print_profiler_info(info) # Output: Model: Mech-Eye LNX 8030, Sensor S/N: GXF..., Firmware: 2.4.0 status = ProfilerStatus() show_error(profiler.get_profiler_status(status)) print_profiler_status(status) # Output: Controller temp: 42.1°C, Sensor temp: 38.5°C profiler.disconnect() ``` -------------------------------- ### Use Virtual Device for MechEye Profiler Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Utilize `VirtualProfiler` with a `.mraw` file for offline development and replay. The API mirrors the `Profiler` class. Ensure the `.mraw` file path is UTF-8 encoded. ```python from mecheye.shared import * from mecheye.profiler import * import cv2 from time import sleep try: profiler = VirtualProfiler("test.mraw") # UTF-8 encoded path user_set = profiler.current_user_set() _, data_width = user_set.get_int_value(DataPointsPerProfile.name) _, line_count = user_set.get_int_value(ScanLineCount.name) total_batch = ProfileBatch(data_width) profiler.start_acquisition() total_batch.reserve(line_count) while total_batch.height() < line_count: batch = ProfileBatch(data_width) status = profiler.retrieve_batch_data(batch) if status.is_ok(): total_batch.append(batch) sleep(0.1) else: show_error(status) break profiler.stop_acquisition() cv2.imwrite("DepthMap.tiff", total_batch.get_depth_map().data()) cv2.imwrite("IntensityImage.png", total_batch.get_intensity_image().data()) print("Saved depth map and intensity image from virtual device.") except IOError as e: print(f"Error opening virtual device: {e}") ``` -------------------------------- ### Manage User Sets Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Demonstrates CRUD operations on named parameter groups (user sets) using UserSetManager. This includes listing, adding, selecting, and persisting user sets for different scanning scenarios. ```APIDOC ## Manage User Sets ### Description `UserSetManager` provides CRUD operations on named parameter groups (user sets). Enumerate, add, select, and persist sets for different scanning scenarios. ### Method ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() if find_and_connect(camera): mgr = camera.user_set_manager() # List all user sets _, user_sets = mgr.get_all_user_set_names() print("User sets:", user_sets) # Output: User sets: ['Default', 'HighRes', 'FastScan'] # Get current user set name _, current_name = mgr.current_user_set().get_name() print("Current:", current_name) # Add and switch to a new user set show_error(mgr.add_user_set("NewUserSet"), "Added NewUserSet") show_error(mgr.select_user_set("NewUserSet"), "Switched to NewUserSet") # Save current parameters to the selected user set show_error(mgr.current_user_set().save_all_parameters_to_device(), "Saved parameters.") camera.disconnect() ``` ``` -------------------------------- ### Capture Point Cloud with HDR Exposure Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Setting Scanning3DExposureSequence to multiple values enables HDR 3D acquisition, merging exposures to handle high-contrast surfaces. Requires saving both untextured and textured point clouds. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, confirm_capture_3d camera = Camera() frame = Frame2DAnd3D() if find_and_connect(camera): if confirm_capture_3d(): # Set HDR exposure sequence: 5 ms and 10 ms user_set = camera.current_user_set() show_error(user_set.set_float_array_value( Scanning3DExposureSequence.name, [5, 10] )) show_error(camera.capture_2d_and_3d(frame)) show_error( frame.frame_3d().save_untextured_point_cloud(FileFormat_PLY, "PointCloud_HDR.ply"), "Saved PointCloud_HDR.ply" ) show_error( frame.save_textured_point_cloud(FileFormat_PLY, "TexturedPointCloud_HDR.ply"), "Saved TexturedPointCloud_HDR.ply" ) camera.disconnect() ``` -------------------------------- ### Print Camera Info and Status Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Fetch and display camera information such as model, serial number, firmware version, IP address, and operational status including temperature readings. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, print_camera_info, print_camera_status camera = Camera() if find_and_connect(camera): info = CameraInfo() show_error(camera.get_camera_info(info)) print_camera_info(info) # Output: Model: Mech-Eye PRO M, S/N: GXF...., Firmware: 2.4.0 status = CameraStatus() show_error(camera.get_camera_status(status)) print_camera_status(status) # Output: CPU temp: 45.2°C, GPU temp: 43.0°C camera.disconnect() ``` -------------------------------- ### Print Camera Info and Status Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Fetches and displays camera information such as model, serial number, firmware version, IP address, and internal temperature readings. ```APIDOC ## Print Camera Info and Status ### Description `CameraInfo` holds model, serial number, firmware version, and IP. `CameraStatus` holds temperature readings. Both are retrieved with dedicated `get_*` methods. ### Method ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, print_camera_info, print_camera_status camera = Camera() if find_and_connect(camera): info = CameraInfo() show_error(camera.get_camera_info(info)) print_camera_info(info) # Output: Model: Mech-Eye PRO M, S/N: GXF...., Firmware: 2.4.0 status = CameraStatus() show_error(camera.get_camera_status(status)) print_camera_status(status) # Output: CPU temp: 45.2°C, GPU temp: 43.0°C camera.disconnect() ``` ``` -------------------------------- ### Perform Hand-Eye Calibration Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Automate the extrinsic parameter computation for robot-camera systems. Requires initializing with mounting mode and board model, adding multiple robot poses with detected board features, and then calculating the transformation. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() calibration = HandEyeCalibration() if find_and_connect(camera): # Initialize: eye-to-hand mounting, BDB-5 board show_error(calibration.initialize_calibration( camera, HandEyeCalibration.CameraMountingMode_EyeToHand, HandEyeCalibration.CalibrationBoardModel_BDB_5 )) # For each robot pose (minimum 15), add the pose and detect board features robot_pose = HandEyeTransformation( x=200.0, y=150.0, z=500.0, # translation (mm) qw=0.999, qx=0.0, qy=0.035, qz=0.0 # quaternion ) color_image = Color2DImage() status = calibration.add_pose_and_detect(camera, robot_pose, color_image) if status.is_ok(): print("Pose added and board detected.") # After collecting enough poses, compute extrinsics camera_to_base = HandEyeTransformation() status = calibration.calculate_extrinsics(camera, camera_to_base) if status.is_ok(): print("Extrinsic parameters:\n", camera_to_base.to_string()) camera.disconnect() ``` -------------------------------- ### Capture Simultaneously from Multiple Cameras Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Uses `multiprocessing` to run acquisition processes in parallel for each camera. Ensure cameras are discoverable on the network. ```python import cv2 import multiprocessing from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect_multi_camera, confirm_capture_3d def capture_task(ip_address, serial_number): camera = Camera() if not camera.connect(ip_address).is_ok(): return frame = Frame2DAnd3D() show_error(camera.capture_2d_and_3d(frame)) cv2.imwrite(f"2DImage_{serial_number}.png", frame.frame_2d().get_color_image().data()) cv2.imwrite(f"DepthMap_{serial_number}.tiff", frame.frame_3d().get_depth_map().data()) show_error(frame.save_textured_point_cloud(FileFormat_PLY, f"TexturedPointCloud_{serial_number}.ply")) camera.disconnect() if __name__ == "__main__": multiprocessing.set_start_method('spawn') cameras = find_and_connect_multi_camera() if cameras and confirm_capture_3d(): processes = [] for cam in cameras: info = CameraInfo() show_error(cam.get_camera_info(info)) p = multiprocessing.Process(target=capture_task, args=(info.ip_address, info.serial_number)) processes.append(p) p.start() for p in processes: p.join() ``` -------------------------------- ### Enable Noise Removal in MechEye Profiler Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Use `EnableNoiseRemoval` and `NoiseRemovalIntensity` to filter depth noise from acquired profile data. Ensure `find_and_connect` and `confirm_capture` are successful before setting values. ```python from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect, confirm_capture profiler = Profiler() if find_and_connect(profiler) and confirm_capture(): user_set = profiler.current_user_set() # Enable noise removal at medium intensity show_error(user_set.set_bool_value(EnableNoiseRemoval.name, True)) show_error(user_set.set_enum_value( NoiseRemovalIntensity.name, NoiseRemovalIntensity.Value_Medium )) print("Noise removal enabled at Medium intensity.") profiler.disconnect() ``` -------------------------------- ### Capture Untextured and Textured Point Clouds Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Acquires both 2D and 3D data simultaneously. Point clouds can be saved as PLY using save_untextured_point_cloud() and save_textured_point_cloud(). ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, confirm_capture_3d camera = Camera() frame_all = Frame2DAnd3D() if find_and_connect(camera): if confirm_capture_3d(): show_error(camera.capture_2d_and_3d(frame_all)) # Save untextured point cloud show_error( frame_all.frame_3d().save_untextured_point_cloud( FileFormat_PLY, "PointCloud.ply" ), "Saved PointCloud.ply" ) # Save textured (color) point cloud show_error( frame_all.save_textured_point_cloud( FileFormat_PLY, "TexturedPointCloud.ply" ), "Saved TexturedPointCloud.ply" ) camera.disconnect() ``` -------------------------------- ### Register Camera Event Callback Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Subclass `EventCallbackBase` and override `process_event_with_payload` to handle events. Register callbacks for supported events and set a heartbeat interval. ```python import time from datetime import datetime from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect class MyCallback(EventCallbackBase): def __init__(self): super().__init__() def process_event_with_payload(self, event_data: EventData, extra_payload: Payload): ts = datetime.fromtimestamp(event_data.timestamp / 1000) print(f"Event: {event_data.event_name} (ID={event_data.event_id}) at {ts}") for member in extra_payload: if member.type == PayloadMember.Type__UInt32: print(f" {member.name}: {member.value.uint_32value}") camera = Camera() if find_and_connect(camera): supported_events = EventInfos() show_error(CameraEvent.get_supported_events(camera, supported_events)) camera_event = CameraEvent() callback = MyCallback() for event_info in supported_events: show_error(camera_event.register_camera_event_callback( camera, event_info.event_id, callback )) print(f"Registered callback for: {event_info.event_name}") show_error(camera.set_heartbeat_interval(2000)) # 2-second heartbeat print("Waiting 20s — disconnect the cable to test the disconnect event...") time.sleep(20) camera.disconnect() ``` -------------------------------- ### Manage User Sets with UserSetManager Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Use UserSetManager to perform CRUD operations on named parameter groups. This allows switching between different scanning configurations. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() if find_and_connect(camera): mgr = camera.user_set_manager() # List all user sets _, user_sets = mgr.get_all_user_set_names() print("User sets:", user_sets) # Output: User sets: ['Default', 'HighRes', 'FastScan'] # Get current user set name _, current_name = mgr.current_user_set().get_name() print("Current:", current_name) # Add and switch to a new user set show_error(mgr.add_user_set("NewUserSet"), "Added NewUserSet") show_error(mgr.select_user_set("NewUserSet"), "Switched to NewUserSet") # Save current parameters to the selected user set show_error(mgr.current_user_set().save_all_parameters_to_device(), "Saved parameters.") camera.disconnect() ``` -------------------------------- ### Capture Periodically Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Continuously acquires 2D images, depth maps, and textured point clouds at a specified interval for a defined duration. Saves captured data to files. Ensure `capture_time` and `capture_period` are set appropriately. ```python import time import cv2 from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, confirm_capture_3d capture_time = 5 # total minutes capture_period = 10 # seconds between captures camera = Camera() if find_and_connect(camera): if confirm_capture_3d(): frame = Frame2DAnd3D() start = time.time() count = 0 while time.time() - start < capture_time * 60: before = time.time() status = camera.capture_2d_and_3d(frame) show_error(status) if not status.is_ok(): break count += 1 cv2.imwrite(f"2DImage_{count}.png", frame.frame_2d().get_color_image().data()) cv2.imwrite(f"DepthMap_{count}.tiff", frame.frame_3d().get_depth_map().data()) show_error(frame.save_textured_point_cloud(FileFormat_PLY, f"TexturedPointCloud_{count}.ply")) elapsed = time.time() - before if elapsed < capture_period: time.sleep(capture_period - elapsed) print(f"Captured {count} sets over {capture_time} minutes.") camera.disconnect() ``` -------------------------------- ### Convert Depth Map to Point Cloud Manually Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Reprojects depth pixels to 3D points using camera intrinsics and the pinhole model. Saves the resulting point cloud in PLY format. Ensure camera intrinsics are correctly obtained. ```python import numpy as np from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, confirm_capture_3d camera = Camera() if find_and_connect(camera): if confirm_capture_3d(): frame3d = Frame3D() show_error(camera.capture_3d(frame3d)) depth = frame3d.get_depth_map() intrinsics = CameraIntrinsics() show_error(camera.get_camera_intrinsics(intrinsics)) fx = intrinsics.depth.camera_matrix.fx fy = intrinsics.depth.camera_matrix.fy cx = intrinsics.depth.camera_matrix.cx cy = intrinsics.depth.camera_matrix.cy point_cloud = UntexturedPointCloud() point_cloud.resize(depth.width(), depth.height()) for i in range(depth.width() * depth.height()): r = i // depth.width() c = i % depth.width() z = depth[i].z point_cloud[i].z = z point_cloud[i].x = float((c - cx) * z / fx) point_cloud[i].y = float((r - cy) * z / fy) Frame3D.save_point_cloud(point_cloud, FileFormat_PLY, "ManualPointCloud.ply") print(f"Saved {point_cloud.width() * point_cloud.height()} points") camera.disconnect() ``` -------------------------------- ### Capture and Save a 2D Image from Mech-Eye Camera Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Acquires a 2D image from the camera and saves it as a PNG file. Handles both monochrome and color images. Requires OpenCV for image saving. ```python import cv2 from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() if find_and_connect(camera): frame_2d = Frame2D() show_error(camera.capture_2d(frame_2d)) if frame_2d.color_type() == ColorTypeOf2DCamera_Monochrome: image = frame_2d.get_gray_scale_image() else: image = frame_2d.get_color_image() cv2.imwrite("2DImage.png", image.data()) print(f"Saved 2D image: {image.width()}x{image.height()} px") # Output: Saved 2D image: 2048x1536 px camera.disconnect() ``` -------------------------------- ### Capture and Save a Depth Map from Mech-Eye Camera Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Acquires 3D data, extracts the depth map, and saves it as a TIFF file to preserve 32-bit depth precision. Displays the depth value of a specific pixel. ```python import cv2 from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect, confirm_capture_3d camera = Camera() if find_and_connect(camera): if confirm_capture_3d(): frame_3d = Frame3D() show_error(camera.capture_3d(frame_3d)) depth_map = frame_3d.get_depth_map() # Access a specific pixel's Z depth value (in mm) row, col = 100, 200 depth_val = depth_map[row * depth_map.width() + col].z print(f"Depth at ({row},{col}): {depth_val:.2f} mm") cv2.imwrite("DepthMap.tiff", depth_map.data()) print("Saved DepthMap.tiff") camera.disconnect() ``` -------------------------------- ### Register Profiler Event Callback Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Subclass `EventCallbackBase`, override `process_event`, and register the callback using `ProfilerEvent.register_profiler_event_callback`. Set a heartbeat interval using `profiler.set_heartbeat_interval()`. ```python import time from datetime import datetime from mecheye.shared import * from mecheye.profiler import * from mecheye.profiler_utils import find_and_connect class MyProfilerCallback(EventCallbackBase): def __init__(self): super().__init__() def process_event(self, event_data: EventData, extra_payload: Payload): ts = datetime.fromtimestamp(event_data.timestamp / 1000) print(f"Profiler event: {event_data.event_name} at {ts}") for member in extra_payload: if member.type == PayloadMember.Type__String: print(f" {member.name}: {member.value.string_value}") profiler = Profiler() if find_and_connect(profiler): show_error(profiler.set_heartbeat_interval(2000)) supported_events = EventInfos() show_error(ProfilerEvent.get_supported_events(profiler, supported_events)) profiler_event = ProfilerEvent() callback = MyProfilerCallback() for event_info in supported_events: show_error(profiler_event.register_profiler_event_callback( profiler, event_info.event_id, callback )) print(f"Registered: {event_info.event_name}") print("Waiting 20s to test disconnect event...") time.sleep(20) profiler.disconnect() ``` -------------------------------- ### Hand-Eye Calibration Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Automates the computation of extrinsic parameters between the camera and a robot's end-effector. It requires initializing with mounting mode and board type, adding multiple robot poses with detected board features, and then calculating the final transformation. ```APIDOC ## Hand-Eye Calibration ### Description `HandEyeCalibration` automates extrinsic parameter computation. Initialize with the mounting mode and calibration board model, then iteratively call `add_pose_and_detect()` for each robot pose (≥15 poses needed), and finally `calculate_extrinsics()`. ### Method ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() calibration = HandEyeCalibration() if find_and_connect(camera): # Initialize: eye-to-hand mounting, BDB-5 board show_error(calibration.initialize_calibration( camera, HandEyeCalibration.CameraMountingMode_EyeToHand, HandEyeCalibration.CalibrationBoardModel_BDB_5 )) # For each robot pose (minimum 15), add the pose and detect board features robot_pose = HandEyeTransformation( x=200.0, y=150.0, z=500.0, # translation (mm) qw=0.999, qx=0.0, qy=0.035, qz=0.0 # quaternion ) color_image = Color2DImage() status = calibration.add_pose_and_detect(camera, robot_pose, color_image) if status.is_ok(): print("Pose added and board detected.") # After collecting enough poses, compute extrinsics camera_to_base = HandEyeTransformation() status = calibration.calculate_extrinsics(camera, camera_to_base) if status.is_ok(): print("Extrinsic parameters:\n", camera_to_base.to_string()) camera.disconnect() ``` ``` -------------------------------- ### Transform Point Cloud to Custom Reference Frame Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Applies a rigid-body transformation defined in Mech-Eye Viewer to both untextured and textured point clouds. Checks if a custom reference frame is configured before applying the transformation. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import ( find_and_connect, confirm_capture_3d, get_transformation_params, transform_point_cloud, transform_textured_point_cloud ) camera = Camera() frame_all = Frame2DAnd3D() if find_and_connect(camera): if confirm_capture_3d(): show_error(camera.capture_2d_and_3d(frame_all)) transformation = get_transformation_params(camera) if not transformation.__is__valid__(): print("No custom reference frame configured in Mech-Eye Viewer.") else: # Untextured pc = transform_point_cloud(transformation, frame_all.frame_3d().get_untextured_point_cloud()) Frame3D.save_point_cloud(pc, FileFormat_PLY, "TransformedPointCloud.ply") # Textured tpc = transform_textured_point_cloud(transformation, frame_all.get_textured_point_cloud()) Frame2DAnd3D.save_point_cloud(tpc, FileFormat_PLY, "TransformedTexturedPointCloud.ply") print("Saved transformed point clouds.") camera.disconnect() ``` -------------------------------- ### Set Depth Range Source: https://context7.com/mechmindrobotics/mecheye_python_samples/llms.txt Filter objects outside a specific depth zone using `Scanning3DDepthRange` and `RangeInt`. This helps in focusing on relevant objects. ```python from mecheye.shared import * from mecheye.area_scan_3d_camera import * from mecheye.area_scan_3d_camera_utils import find_and_connect camera = Camera() if find_and_connect(camera): user_set = camera.current_user_set() depth_range = RangeInt(100, 1000) # 100 mm to 1000 mm show_error( user_set.set_range_value(Scanning3DDepthRange.name, depth_range), f"Depth range set: {depth_range.min}–{depth_range.max} mm" ) camera.disconnect() ```