Import Camera Intrinsic Parameters from ROS
The ROS camera calibration package estimates camera intrinsic parameters using the OpenCV camera calibration tools [1]. After calibrating a camera in ROS, you can import its intrinsic parameters to a YAML file using the camera calibration parser in ROS. To use the calibrated camera with Computer Vision Toolbox™ functions, such as undistortImage
, you must read the camera parameters from the YAML file and then convert them into a cameraIntrinsics
object using cameraIntrinsicsFromOpenCV
.
Note: The cameraIntrinsicsFromOpenCV
function supports importing camera intrinsic parameters for only those pinhole camera models that use the ROS plumb-bob
distortion model.
Read Camera Intrinsic Parameters from a ROS YAML File
Read the camera parameters stored in cameraParams.yaml
using the helper function helperReadYAML
.
intrinsicsParams = helperReadYAML('cameraParams.yaml');
Create cameraIntrinsics
Object Using cameraIntrinsicsFromOpenCV
Use the cameraIntrinsicsFromOpenCV
function to create a cameraIntrinsics
object from the camera matrix and the distortion coefficients.
imageSize = [intrinsicsParams.image_height intrinsicsParams.image_width]; intrinsicMatrix = intrinsicsParams.camera_matrix; distortionCoefficients = intrinsicsParams.distortion_coefficients; intrinsicsObj = cameraIntrinsicsFromOpenCV(intrinsicMatrix,distortionCoefficients,imageSize);
Undistort Image
Use the imported camera intrinsics with undistortImage
to undistort an image captured using the calibrated camera.
% Load the captured image. imageName = fullfile(toolboxdir('vision'),'visiondata','calibration','stereo','left','left01.png'); I = imread(imageName); % Undistort the image. J = undistortImage(I,intrinsicsObj,'OutputView','full'); % Display the result. figure montage({I,J})
Supporting Functions
helperReadYAML
The helperReadYAML
function reads the monocular camera parameters from the input YAML file that was exported from ROS.
function cameraParams = helperReadYAML(filename) % helperReadYAML reads a ROS YAML file, filename, and returns a structure % with these fields: image_width, image_height, camera_name, % camera_matrix, distortion_model, distortion_coefficients, % rectification_matrix, and projection_matrix. These fields are stored % in the YAML file colon separated from their values in different lines. f = fopen(filename,'r'); stringFields = {'camera_name','distortion_model'}; while ~feof(f) [name,value,isEmptyLine] = helperReadYAMLLine(f); if isEmptyLine continue end if ~isempty(value) % Convert all values to numbers except for known string % fields. if ~any(contains(name, stringFields)) value = str2num(value); %#ok end else % An empty value in ROS YAML files indicates a matrix in % upcoming lines. Read the matrix from the upcoming lines. value = helperReadYAMLMatrix(f); end % Store post-processed value. cameraParams.(name) = value; end fclose(f); end
helperReadYAMLMatrix
The helperReadYAMLMatrix
function reads the rows, columns and data fields of a matrix in the ROS YAML file.
function matrix = helperReadYAMLMatrix(f) % helperReadYAMLMatrix reads a matrix from the ROS YAML file. A matrix in % a ROS YAML file has three fields: rows, columns and data. rows and col % describe the matrix size. data is a continguous array of the matrix % elements in row-major order. This helper function assumes the presence % of all three fields of a matrix to return the correct matrix. numRows = 0; numCols = 0; data = []; % Read numRows, numCols and matrix data. while ~feof(f) [name,value,isEmptyLine] = helperReadYAMLLine(f); if isEmptyLine continue end switch name case 'rows' numRows = str2num(value); %#ok case 'cols' numCols = str2num(value); %#ok case 'data' data = str2num(value); %#ok % Terminate the while loop as data is the last % field of a matrix in the ROS YAML file. break otherwise % Terminate the while loop if any other field is % encountered. break end end if numel(data) == numRows*numCols % Reshape the matrix using row-major order. matrix = reshape(data,[numCols numRows])'; end end
helperReadYAMLLine
The helperReadYAMLLine
function reads a line of a ROS YAML file.
function [name,value,isEmptyLine] = helperReadYAMLLine(f) % Read line from file. line = fgetl(f); % Trim leading and trailing whitespaces. line = strtrim(line); if isempty(line) || line(1)=='#' % Empty line or comment. name = ''; value = ''; isEmptyLine = true; else % Split the line to get name and value. c = strsplit(line,':'); assert(length(c)==2,'Unexpected file format') name = c{1}; value = strtrim(c{2}); % Trim leading whitespace. isEmptyLine = false; end end