Camera API reference#
- class pyflir.Camera(ip: str | None = None, interface_ip: str | None = None, timeout: float = 2.0)[source]#
Bases:
objectFLIR GigE Vision camera controller.
Uses pyGigEVision for GVCP control and GVSP image streaming. Vendor-specific registers are accessed directly via addresses in
pyflir.registers.- Parameters:
ip – Camera IP address. None = auto-discover first camera.
interface_ip – Local NIC IP for discovery and streaming. Useful with multiple network interfaces.
timeout – GVCP socket timeout in seconds.
Examples:
with Camera() as cam: cam.download_xml() cam.load_xml("camera_xxx.xml") cam.start_stream() frame = cam.read() cam.stop_stream() # Single-shot grab with Camera() as cam: cam.load_xml("camera_xxx.xml") frame = cam.grab()
- connect() None[source]#
Discover (if needed), open GVCP connection, and acquire control.
- Raises:
CameraError – If no camera is found or the connection fails.
- download_xml(save_path: str | None = None) bytes[source]#
Download the GenICam XML from the camera and save it to disk.
Uses pyGigEVision to fetch and decompress the descriptor stored in the camera’s on-board memory (bootstrap register 0x0200).
- Parameters:
save_path – Output file path. Defaults to camera_<serial>.xml.
- Returns:
Raw XML bytes.
- load_xml(xml_path: str) None[source]#
Load and parse a previously saved GenICam XML file.
After loading, width/height are read from the camera registers and feature aliases are built for SFNC compatibility.
- Parameters:
xml_path – Path to the GenICam XML file.
- start_stream(packet_size: int = 1500, packet_delay: int = 0) None[source]#
Configure stream channel 0 and send AcquisitionStart.
- Parameters:
packet_size – GVSP packet size in bytes (≤1500 for standard Ethernet; up to 9000 for jumbo frames if both ends support it).
packet_delay – Inter-packet delay in timestamp ticks. 0 = max speed.
- Raises:
CameraError – If not connected or image dimensions are unknown.
- grab(timeout: float = 5.0) ndarray[source]#
Start streaming, capture one frame, stop streaming, and return it.
Convenience for single-shot capture. XML must be loaded first.
- Parameters:
timeout – Seconds to wait for a frame.
- Returns:
2D numpy array (H, W), dtype uint16.
- read(timeout: float = 5.0, latest: bool = False) ndarray[source]#
Return a frame from the live stream as a numpy array (H × W).
- Parameters:
timeout – Seconds to wait for a frame before raising CameraError.
latest – If True, drain the queue and return only the most recent frame. Use in live-display loops to prevent lag from building up.
- Returns:
2D numpy array (H, W), dtype uint16.
- Raises:
CameraError – If not streaming or no frame arrives in time.
- acquire(n_frames: int, timeout: float = 30.0) list[ndarray][source]#
Capture exactly
n_framesframes and return them as a list.If streaming is already active, reads from the live stream. Otherwise starts it automatically, captures, then stops:
frames = cam.acquire(50) # no start_stream() / stop_stream() needed
- Parameters:
n_frames – Number of frames to capture.
timeout – Total seconds to wait before raising CameraError.
- Returns:
List of (H, W) numpy arrays, dtype uint16.
- execute_command(feature: str) None[source]#
Execute a Command register feature (e.g. AcquisitionStart).
- property frame_rate_max: float | None#
Maximum frame rate for the current ROI (read-only, from camera).
- get_max_frame_rate() float | None[source]#
Return camera’s max frame rate for the current ROI, or None.
- get_calibration_blocks() list[dict][source]#
Return a list of all calibration blocks with their temperature ranges.
Each entry has keys:
index,name,lens,tmin,tmax. Temporarily iterates all blocks and restores the original selection.
- get_calibration(block: int | None = None) dict[source]#
Read calibration data for a calibration block.
If block is
Nonethe currently active block is used. The active block is restored after reading.Temperature conversion uses two polynomials:
counts → radiance: W = Σ counts_coeffs[i] · counts^i − counts_background
radiance → temp °C: T_C = Σ temp_coeffs[i] · W^i
Both tmin/tmax and the temp polynomial output are in °C.
- Returns:
block,tmin,tmax(°C),counts_order,counts_coeffs,counts_background,temp_order,temp_coeffs.- Return type:
dict with keys
- counts_to_temperature(counts: ndarray, emissivity: float | None = None, refl_temp_c: float | None = None, atm_temp_c: float | None = None, tau: float = 1.0) ndarray[source]#
Convert a raw uint16 frame to temperature in degrees Celsius.
Reads calibration for the currently active block, then applies two polynomial steps:
counts → radiance: W = Σ counts_coeffs[i] · counts^i − background
radiance → °C: T_C = Σ temp_coeffs[i] · W^i
If emissivity, refl_temp_c, or atm_temp_c are omitted they default to the values previously set via
set_object_params().- Parameters:
- Returns:
Float64 array (H, W) with temperature in degrees Celsius.
Example:
frame = cam.grab() temp = cam.counts_to_temperature(frame) print(f"Centre pixel: {temp[256, 320]:.1f} °C")
- set_object_params(emissivity: float | None = None, distance_m: float | None = None, atm_temp_k: float | None = None, refl_temp_k: float | None = None, humidity: float | None = None) None[source]#
Set radiometry object parameters (any subset).
- get_roi() dict[source]#
Return current ROI as
{width, height, offset_x, offset_y}.heightreflects the usable image rows only; any trailing metadata rows appended by the camera firmware are excluded.
- get_roi_limits() dict[source]#
Return
{width_min, width_inc, height_min, height_inc, sensor_width, sensor_height}.All height values are in usable image rows (metadata rows excluded).
- set_roi(width: int, height: int, offset_x: int = 0, offset_y: int = 0) None[source]#
Set the acquisition ROI. Stream must be stopped first.
Width and height are validated against the camera’s increment constraints before being written. After writing, the max frame rate register updates automatically.
- Parameters:
width – ROI width in pixels (must be a multiple of WidthInc).
height – ROI height in pixels.
offset_x – Horizontal offset from left edge of sensor.
offset_y – Vertical offset from top edge of sensor.
- trigger_nuc(preset: int = 0) None[source]#
Apply the stored NUC correction coefficients for the given preset.
Loads pre-computed correction data (PS0–PS3) into the active pipeline. Does not compute a new NUC; to do that, move the physical flag into the FOV, capture a flat-field frame, then save and re-apply.
- Parameters:
preset – Preset index to correct (0–3). Default 0.
- flag_move_in_fov() None[source]#
Move the internal NUC flag into the field of view.
Only available on cameras equipped with a physical shutter (e.g. FLIR A6751sc). Call before capturing a flat-field reference.
- get_temperatures() dict[str, float][source]#
Read all available on-board temperature sensors.
Returns a dict with keys
FPA,Digitizer,PowerBoard,FrontPanel(degrees Celsius). The selector register is restored to its original value after reading.
- info() dict[source]#
Return a dict of the camera’s current state.
Includes IP, model, serial, ROI, frame rate, exposure, calibration block, detector temperature, and streaming status.
- live_view(colormap: str = 'inferno', scale: int = 2) None[source]#
Open a live thermal image viewer window.
Requires the ‘gui’ extra:
pip install pyflir[gui]XML must be loaded first (for width/height). If streaming is already active it will be stopped and restarted by the viewer.
- Parameters:
colormap – Matplotlib colormap name (default “inferno”).
scale – Display upscale factor (default 2 = double size).
Module-level helpers#
- pyflir.discover(interface_ip: str | None = None, timeout: float = 2.0) list[dict][source]#
Discover GigE Vision cameras on the network.
- Parameters:
interface_ip – Bind to this local IP to target a specific NIC. Omit to broadcast on all interfaces.
timeout – Seconds to wait for discovery replies.
- Returns:
ip, mac, spec_version, manufacturer, model, device_version, manufacturer_info, serial, user_name, interface_ip (the local NIC that received the reply).
- Return type:
List of dicts with keys
Example:
import pyflir cameras = pyflir.discover(interface_ip="169.254.100.1") for cam in cameras: print(cam["manufacturer"], cam["model"], cam["ip"])
- pyflir.force_ip(camera: dict, ip: str, mask: str, gateway: str | None = None) None[source]#
Assign a new IP to a discovered camera by MAC, via GVCP FORCEIP.
Re-homes a camera that is on the wrong subnet (or fell back to link-local) without changing host NIC configuration. The camera reboots its IP stack; re-run
pyflir.discover()afterwards to see the new address.- Parameters:
camera (dict) – A camera dict from
pyflir.discover()(must contain"mac").ip (str) – New IPv4 address and subnet mask for the camera.
mask (str) – New IPv4 address and subnet mask for the camera.
gateway (str or None, optional) – Default gateway, or
Nonefor none.
Connection diagnostics#
- pyflir.tune_connection(cam, probe_only: bool = True, read_nic_info: bool = False) ConnectionReport[source]#
Probe the host NIC and return connection recommendations.
FLIR cameras do not have an onboard memory buffer, so this function performs a read-only probe phase only: it inspects the host NIC carrying the camera link (speed, USB vs. PCIe, MTU) and returns recommended
start_streamkwargs.- Parameters:
cam (Camera) – A connected FLIR camera.
probe_only (bool, optional) – Ignored (always
Truefor pyFlir; kept for API parity with pyTelops). Reserved for a future live-stream sweep.read_nic_info (bool, optional) – Read (never change) host NIC facts to annotate the report. Requires
psutil. DefaultFalse.
- Return type:
- class pyflir.ConnectionReport(recommended: dict, probe: ConnectionStats | None = None, warnings: list[str] = <factory>)#
Bases:
objectResult of
tune_connection().Fields are documented below; pass the report to
apply()to write the recommended settings onto a connected camera.- apply(cam) dict[source]#
Store the recommended packet_size on cam for future streams.
Does not change any system or camera setting; records the recommendation as
cam._recommended_packet_size.
- probe: ConnectionStats | None = None#
- class pyflir.ConnectionStats(max_packet_size: int | None = None, link_speed_mbps: int | None = None, adapter_name: str | None = None, is_usb_adapter: bool | None = None)#
Bases:
objectRead-only facts gathered from a
tune_connection()probe.Populated by
pyflir.connection.tune_connection()and returned insideConnectionReport.
Errors#
GenICam XML#
- pyflir.parse_genicam_xml(xml_bytes: bytes) dict[str, RegNode][source]#
Parse a GenICam XML blob and return {feature_name: RegNode}.
Only features with a plain numeric <Address> tag are included. Features whose address is computed at runtime (via <pAddress>, IntSwissKnife, StructEntry, etc.) are silently skipped.
- class pyflir.RegNode(name: str, node_type: str, address: int, length: int = 4, access: str = 'RW', endianness: str = 'Big', sign: str = 'Unsigned', cmd_value: int | None = None, enum_entries: dict[str, int]=<factory>, description: str = '')#
Bases:
objectDescribes one GenICam feature backed by a hardware register.
File I/O#
- pyflir.read_ats(filepath: str) tuple[source]#
Read a FLIR ATS-US recording file (.ats).
- Returns:
raw (np.ndarray, shape (N, H, W), dtype uint16)
metadata (ATSMetadata)
Examples
>>> from pyflir.io import read_ats >>> raw, meta = read_ats("recording.ats") >>> print(meta.camera_model, raw.shape)
- pyflir.read_sfmov(filepath: str)[source]#
Read a FLIR SFMOV sequence file (.sfmov).
Requires
pysfmov: pip install pyflir[io]
- pyflir.read_sfmov_meta(filepath: str) dict[source]#
Read metadata from a FLIR SFMOV sequence file (.sfmov).
Requires
pysfmov: pip install pyflir[io]
- class pyflir.FLIRATSReader(filepath: str)#
Bases:
objectReader for FLIR ATS-US thermal recording files (.ats).
- Parameters:
filepath (str) – Path to the .ats file.
read()) (Attributes (populated after calling)
-------------------------------------------
raw (np.ndarray, shape (N, H, W), dtype uint16) – Raw sensor counts for all N frames.
temperature_C (np.ndarray, shape (N, H, W), dtype float32, or None) – Temperature in °C using linear calibration from the embedded XML. None if calibration data is absent.
metadata (ATSMetadata) – All extracted metadata as a structured dataclass.
Examples
>>> reader = FLIRATSReader("recording.ats").read() >>> print(reader.metadata) >>> print(reader.raw.shape) # (N, H, W) >>> print(reader.temperature_C.shape)
- FILE_MAGIC = b'FLIR ATS-US File'#
- export_csv(idx: int = 0, unit: str = 'C', path: str | None = None) str[source]#
Save one frame as a CSV file. Returns the output path.
- export_npy(path: str | None = None) str[source]#
Save all raw uint16 frames as a .npy file. Returns the output path.
- export_tiff(unit: str = 'C', path: str | None = None) str[source]#
Save all frames as a multi-page float32 TIFF. Requires tifffile.
- get_temperature(unit: str = 'C') ndarray[source]#
Return temperature array in the requested unit (C, K, or F).
- read() FLIRATSReader[source]#
Parse the file and populate raw, temperature_C, and metadata. Returns self.
- class pyflir.ATSMetadata(filepath: str = '', file_size_bytes: int = 0, camera_model: str | None = None, camera_part: str | None = None, lens: str | None = None, filter: str | None = None, width: int = 0, height: int = 0, n_frames: int = 0, frame_start_byte: int = 0, stride_bytes: int = 0, sync_row_bytes: int = 0, emissivity: float | None = None, distance: float | None = None, relative_humidity: float | None = None, reflected_temp: float | None = None, atmosphere_temp: float | None = None, ext_optics_temp: float | None = None, ext_optics_transmission: float | None = None, range_counts_min: float | None = None, range_counts_max: float | None = None, range_radiance_min: float | None = None, range_radiance_max: float | None = None, range_temperaturec_min: float | None = None, range_temperaturec_max: float | None = None, range_temperaturek_min: float | None = None, range_temperaturek_max: float | None = None, range_temperaturef_min: float | None = None, range_temperaturef_max: float | None = None, range_temperaturer_min: float | None = None, range_temperaturer_max: float | None = None, source_unit: str | None = None, temperature_type: str | None = None, apply_nuc: str | None = None, apply_bp: str | None = None, display_min_c: float | None = None, display_max_c: float | None = None, display_mode: str | None = None, scale_mode: str | None = None, segmentation_enabled: str | None = None)#
Bases:
objectAll metadata extracted from a FLIR ATS-US file.
All fields are optional (
Nonewhen not present in the file). Useas_dict()to convert to a plain dictionary orstr()for a formatted summary.