Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 0 additions & 35 deletions librir/CMakeLists.txt

This file was deleted.

2 changes: 1 addition & 1 deletion librir/low_level/rir_signal_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def extract_times(time_series, strategy="union"):
Create a unique time vector from several ones.
time_series is a list of input time series
strategy is either 'union' (take the union of all time series) or 'inter'
Returns a growing time vector containing all different time values given in
Returns a growing time vector containing all different time values given in
time_series, without redundant times.
"""
_signal_processing.extract_times.argtypes = [
Expand Down
11 changes: 3 additions & 8 deletions librir/low_level/rir_video_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,13 +334,7 @@ def flip_camera_calibration(camera, flip_rl, flip_ud):

def calibration_files(camera):
"""
Returns the calibration file names for give camera.
This function only works for WEST IR cameras and returns:
- The lut file name,
- The optical temperature file name,
- The fut transmission file name,
- The hublot transmission file name,
- The mir transmission file name.
Returns the calibration file names for given camera.
"""
dst = np.zeros((100), dtype="c")
dstSize = np.zeros((1), dtype="i")
Expand All @@ -359,7 +353,8 @@ def calibration_files(camera):
)
if ret == -1:
raise RuntimeError("An error occured while calling 'calibration_files'")
return toString(dst).split("\n")
cfiles = toString(dst).split("\n")
return cfiles


def get_attributes(camera):
Expand Down
6 changes: 3 additions & 3 deletions librir/registration/masked_registration_ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ class MaskedRegistratorECC:
To maximize the chances to get a good translation estimation, the input images can be cropped based
on the window_factor value (that takes a centered sub window of input image) and sigma (to apply
a gaussian filter on input image).

Furtheremore, the computation can be performed on static mask only (boolean image) or on a dynamic mask that only contains the X% lowest pixels.

The first image must be processed with MaskedRegistratorECC.start() function, the remaining ones with MaskedRegistratorECC.compute().
The results are stored in MaskedRegistratorECC.x and MaskedRegistratorECC.y (lists of translations). The confidence on the computed translations is accessible in MaskedRegistratorECC.confidences.

Note that the returned translation values correspond to the translation from the very first image passed to MaskedRegistratorECC.start().
"""

Expand Down
131 changes: 126 additions & 5 deletions librir/video_io/IRMovie.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
import numpy as np
from librir.tools.utils import init_thermavip, unbind_thermavip_shared_mem
from librir.tools.FileAttributes import FileAttributes
from typing import List, Dict

from librir.low_level.rir_video_io import (
enable_motion_correction,
load_motion_correction_file,
motion_correction_enabled,
)

from ..low_level.rir_video_io import (
calibrate_image,
Expand Down Expand Up @@ -188,6 +195,42 @@ def close(self):
logger.warning(p_exc)

self.__tempfile__ = None


@property
def registration_file(self) -> Path:
"""
Returns the registration file name for this camera, and tries to download it
from ARCADE if not already done.
"""

return self._registration_file

@registration_file.setter
def registration_file(self, value) -> None:
value = Path(value)
if not value.exists():
raise FileNotFoundError(f"{value} doesn't exist")
self._registration_file = value
load_motion_correction_file(self.handle, self._registration_file)

@property
def registration(self) -> bool:
"""
Returns True is video registration is activated, false otherwise
"""
if self._registration_file.exists():
return motion_correction_enabled(self.handle)
return False

@registration.setter
def registration(self, value: bool) -> None:
"""
Enable/disable video registration.
Throws if the registration file cannot be found for this video.
"""

enable_motion_correction(self.handle, bool(value))

def flip_calibration(self, flip_rl, flip_ud):
flip_camera_calibration(self.handle, flip_rl, flip_ud)
Expand Down Expand Up @@ -251,9 +294,9 @@ def load_secs(self, time, calibration=None):
calibration = 0
if self.times is None:
self.times = np.array(list(self.timestamps), dtype=np.float64)
c = calibration or self.calibration
self.calibration = calibration or self.calibration
index = np.argmin(np.abs(self.times - time))
res = load_image(self.handle, int(index), int(c))
res = load_image(self.handle, int(index), self._calibration_index)
self._frame_attributes_d[int(index)] = get_attributes(self.handle)
# self.frame_attributes =get_attributes(self.handle)
return res
Expand All @@ -272,7 +315,7 @@ def filename(self):
return Path(get_filename(self.handle)) # local filename

@property
def calibration_files(self):
def calibration_files(self) -> List[str]:
try:
return calibration_files(self.handle)
except:
Expand Down Expand Up @@ -385,11 +428,11 @@ def tis(self):
:return:
"""
if self.calibration == "Digital Level":
tis = (self.payload & (2 ** 16 - 2 ** 13)) >> 13
tis = (self.payload & (2**16 - 2**13)) >> 13
else:
old_calib = self.calibration
self.calibration = "DL"
tis = (self.payload & (2 ** 16 - 2 ** 13)) >> 13
tis = (self.payload & (2**16 - 2**13)) >> 13
self.calibration = old_calib
return tis

Expand Down Expand Up @@ -489,6 +532,84 @@ def _build_outfile(self, outfile=None) -> str:
# else:
# logger.info("'{}' is not a PCR file".format(self.filename))

def to_h264(
self,
dst_filename,
start_img=0,
count=-1,
clevel=8,
attrs=None,
times=None,
frame_attributes=None,
cthreads=8,
cfiles: List[str] = None,
):
"""
Exports movie into h264 file.
@param dst_filename: destination file
@param start_img: image index to start export
@param count: number of frame to export
@param clevel: compression level
@return:
"""
# set image count
if count < 0:
count = self.images
if start_img + count > self.images:
count = self.images - start_img

logger.info(
"Start saving in {} from {} to {}".format(
dst_filename, start_img, start_img + count
)
)

# retrieve attributes
if attrs is None:
attrs = self.attributes

# adding custom attribute --> must be a dict[str]=str
# attrs.update(self.additional_attributes)

logger.info("Found keys {}".format(list(attrs.keys())))

# # set calibration files (if needed)
# if cfiles is None:
# cfiles = []

# check if file is saved in temperature
try:
attrs.pop("MIN_T")
attrs.pop("MIN_T_HEIGHT")
attrs.pop("STORE_IT")
logger.info("Images saved in temperature, switch to DL")
except KeyError:
logger.info("Images saved in DL")
pass

h, w = self.image_size
if times is None:
times = list(self.timestamps)
with IRSaver(dst_filename, w, h, h, clevel) as s:
s.set_global_attributes(attrs)
s.set_parameter("threads", cthreads)
saved = 0
for i in range(start_img, start_img + count):
img = self.load_pos(i, 0)

_frame_attributes = (
self.frame_attributes
if frame_attributes is None
else frame_attributes[i]
)

s.add_image(img, times[i] * 1e9, attributes=_frame_attributes)

saved += 1
if saved % 100 == 0:
logger.info("Saved {} images...".format(saved))
logger.info("{} image(s) saved".format(count))

def __repr__(self):
return "IRMovie({})".format(self.filename)

Expand Down
4 changes: 2 additions & 2 deletions librir/video_io/IRSaver.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class IRSaver(object):
"""
Small class to save IR videos in compressed h264 or hevc format and using MP4 container.
It generates MP4 video files containing IR images on 16 bits per pixel, and any kind of global/frame attributes (see FileAttributes class for more details).

The output video is compressed with either H264 or HEVC video codec (based onf ffmpeg library) using its lossless compression mode. The potential losses are
added by the IRSaver itself in order to maximize the video compressibility. The optional temperature losses are bounded and cannot be exceeded.

Expand All @@ -34,7 +34,7 @@ class IRSaver(object):
to 8 (highest compression) with a default value of 0.

The file format supports global attributes as well as frame attributes on the form of a dict.

This class should not be used to mix lossy and lossless frames within the same video file.
"""

Expand Down
Loading