...
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 pixel format 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
Attention: Although the FFV1 codec writes RGBA video, the pixel format has to be set to BGRA (30)! Upon reading the video RGBA (28) can be used to retreive the original data.
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=[ ['streamUrl', 'ir.avi'], ['format', 'avi'], /// Necessary if streamUrl doesn't end with .avi, since FFmpeg can't determine the format then ['videoCodec', '34'], /// FFV1 ['frameRate', '27'], /// Optris camera operates at 27Hz ['videoQuality', '0'], /// Optimize Quality -> Lossless ['pixelformat', '30'], /// Need to supply images in BGRA, but images get written as 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) |
Example: Display encoded temperature video
This example shows how to read an RGBA-encoded temperature video, convert it back to its original 16-bit 1-channel format and display it as an RGB grayscale image.
PQL
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
encoded = FFMPEGVIDEO({source='Video', options=[
['streamUrl', 'ir.avi'],
['timeStampMode', 'filetime'],
['useDelay', 'true'],
['pixelFormat', '28'], /// RGBA
['bitsPerPixel', '32']
]})
/// Reinterpret image: 1 32-bit pixel is extended to 2 16-bit pixels. Width doubles.
original = MAP({expressions = [['reinterpretCV(image, getWidthCV(image)*2, getHeightCV(image), 16, 1, 28)', 'image']]}, encoded)
grayscale = MAP({expressions = [['stretchContrastCV(image, 2000, 4000, 0, 255)', 'image']]}, original)
output = UDO({class='ShowImageJCV', init='0,IR Video'}, grayscale) |