Commit 36ad1b2d authored by Vincent POLLET's avatar Vincent POLLET
Browse files

Implements (first draft of) parsing of calibration data files and pattern identification

parent 3a4e0a19
Pipeline #48341 failed with stage
in 4 minutes and 25 seconds
import os
import cv2
import pandas as pd
from bob.io.stream import Stream, StreamFile
def detect_patterns(directory_path, data_config_path, pattern_type, pattern_size, cv_flags=None, frames=None):
files = [file for file in os.listdir(directory_path) if file.endswith(".h5")]
pattern_points = pd.DataFrame(dtype=object)
for file_idx, capture in enumerate(files):
f = StreamFile(os.path.join(directory_path, capture), data_config_path)
streams = [Stream(stream, f) for stream in f.get_available_streams()]
# check that all streams have the same number of frames
if any(stream.shape[0] != streams[0].shape[0] for stream in streams):
file_name = os.path.join("processed_calibration_data/dark_demosaiced", pattern_type)
error_str = (
"Capture files must contain synced data: "
+ "all streams must have the same number of frames!"
+ "\n"
+ "Streams with shapes "
)
for stream in f.get_available_streams():
error_str = error_str + str(stream.shape) + " "
error_str = error_str + "\n" + "in file " + file_name
raise ValueError(error_str)
# add columns for streams, if not already present in dataframe
for stream in streams:
if stream.name not in pattern_points.columns:
pattern_points[stream.name] = None
# Get the indices of frames to use in data files
if frames is None:
frame_idx = range(streams[0].shape[0])
elif isinstance(frames, list):
if len(frames) != len(files):
raise ValueError("List of frames to use does not match number of data files.")
frame_idx = frames[file_idx]
if isinstance(frame_idx, int):
frame_idx = [frame_idx]
for stream in streams:
for frame in frame_idx:
# TODO: grayscale, normalization, squeeze channel dim with cv2
image = stream.normalize()[frame]
if image.shape[0] == 3:
image = image.mean(axis=0, dtype=image.dtype)
image = image.squeeze()
# if detection fails, pattern_points are set to None
if pattern_type == "chessboard":
_, ptrn_pts = cv2.findChessboardCorners(image, pattern_size, cv_flags)
elif pattern_type == "charuco":
raise NotImplementedError # TODO: charuco cv2 call
else:
raise ValueError("Invalid pattern type: " + pattern_type)
pattern_points.loc[capture + ":" + str(frame), stream.name] = ptrn_pts
return pattern_points
def get_valid_frames_for_intrinsic_calibration(detection_df, camera):
return detection_df[~detection_df[camera].isnull()]
def get_valid_frames_for_extrinsic_calibration(detection_df, camera_1, camera_2):
return detection_df[(~detection_df[camera_1].isnull()) & (~detection_df[camera_2].isnull())]
......@@ -33,6 +33,7 @@ requirements:
- pybind11 {{ pybind11 }}
- opencv {{ opencv }}
- scikit-image {{ scikit_image }}
- pandas {{ pandas }}
- bob.io.image
- bob.ip.color
- bob.io.stream
......@@ -41,6 +42,7 @@ requirements:
- {{ pin_compatible('setuptools') }}
- {{ pin_compatible('numpy') }}
- {{ pin_compatible('opencv') }}
- {{ pin_compatible('pandas') }}
test:
imports:
......
......@@ -3,6 +3,7 @@ bob.extension
numpy
# opencv We need opencv, but the opencv package is broken and can't be installed with pip. Install it with conda.
scikit-image
pandas
bob.io.image
bob.ip.color
bob.io.stream
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment