...
Name | Type | Description |
---|---|---|
image | IMAGEJCV | The current frame of the video stream |
starttimestamp | STARTTIMESTAMP | The start time stamp of the frame |
flagstate | STRING | Current state of the camera flag. The flag is periodically (~12s) closed to re-calibrate the camera sensor which results in a short delay (~500ms). Possible values are:
|
Example: Show temperature video
This example shows how to grab a thermal video from an optris camera (16-bit 1 channel), transform it to a grayscale RGB image, and display it in a window. Temperatures are mapped as a linear function from 10.00°C -> 0 (black) to 40.00°C -> 255 (white).
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
video = ACCESS({source='Video',
wrapper='GenericPush',
transport='OptrisCamera',
protocol='none',
datahandler='Tuple',
schema= [
['image', 'IMAGEJCV'],
['timestamp', 'STARTTIMESTAMP'],
['flagState', 'STRING']
]})
/// or shorter, as a source operator:
video = OPTRISCAMERA({source='Video'})
grayscale = MAP({expressions = [['stretchContrastCV(image, 1000, 4000, 0, 255)', 'rgb_grayscale']]}, video)
output = UDO({class='ShowImageJCV', init='0,IR Video'}, grayscale) |
Example: Encode temperature video to video file
This example shows how to grab a thermal video from an optris camera and encode it into a video file. Since most video codecs operate on 24- or 32-bit RGB(A) or YUV data, the FFV1 codec (34) is used which supports 32-bit RGBA data (pixelformat 30). The 16-bit 1 channel temperature video is then reinterpreted as a 32-bit RGBA video with half of the width, where 2 16-bit pixels form one 32-bit pixel. Since fusing two pixels into one on bit level introduces jagged edges which confuse normal video encoders, it is necessary to use FFV1 since it is a lossless video compression algorithm.
PQL
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
/// Grab Optris IR video stream
original = OPTRISCAMERA({source='Video'})
/// Reinterpret image: 2 16-bit pixels form one 32-bit pixel. Width halves.
encoded = MAP({expressions = [['reinterpretCV(image, getWidthCV(image)/2, getHeightCV(image), 8, 4, 28)', 'image']]}, original)
/// Write to file
file = SENDER({sink='videofile',
wrapper='GenericPush',
transport='none',
protocol='FFmpegVideoStream',
dataHandler='Tuple',
options=[
['videoCodec', '34'], /// FFV1
['frameRate', '27'], /// Optris camera operates at 27Hz
['videoQuality', '0'], /// Optimize Quality -> Lossless
['pixelformat', '30'], /// RGBA
['codec:preset', 'veryslow'], /// Best encoding -> Lossless
['frameSizeMultiple', '2'] /// Codec requires image width and height with multiple of 2, extend image without stretching to preserve original data
]}, encoded) |