star-camera

Camera models
git clone git://git.meso-star.fr/star-camera.git
Log | Files | Refs | README | LICENSE

commit 0d482412d2db4d86d212c302f10fe219f8f37ec7
parent 8b877921633c4de88b6af83a91e90301090e75a2
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu,  1 Jul 2021 12:00:34 +0200

Add the scam_create_pinhole function

Diffstat:
Acmake/CMakeLists.txt | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/scam.c | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/scam.h | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/scam_c.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/scam_log.c | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/scam_log.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/scam_pinhole.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 644 insertions(+), 0 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -0,0 +1,93 @@ +# Copyright (C) 2021 |Meso|Star> (contact@meso-star.com) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +cmake_minimum_required(VERSION 2.8) +project(scam C) +enable_testing() + +set(SCAM_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src) +option(NO_TEST "Do not build tests" OFF) + +################################################################################ +# Check dependencies +################################################################################ +find_package(RCMake 0.4 REQUIRED) +find_package(RSys 0.9 REQUIRED) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) +include(rcmake) +include(rcmake_runtime) + +include_directories(${RSys_INCLUDE_DIR}) + +################################################################################ +# Configure and define targets +################################################################################ +set(VERSION_MAJOR 0) +set(VERSION_MINOR 0) +set(VERSION_PATCH 0) +set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + +set(SCAM_FILES_SRC + scam.c + scam_log.c + scam_pinhole.c) +set(SCAM_FILES_INC + scam_c.h + scam_log.h) +set(SCAM_FILES_INC_API scam.h) +set(SCAM_FILES_DOC COPYING README.md) + +# Prepend each file in the `SCAM_FILES_<SRC|INC>' list by `SCAM_SOURCE_DIR' +rcmake_prepend_path(SCAM_FILES_SRC ${SCAM_SOURCE_DIR}) +rcmake_prepend_path(SCAM_FILES_INC ${SCAM_SOURCE_DIR}) +rcmake_prepend_path(SCAM_FILES_INC_API ${SCAM_SOURCE_DIR}) +rcmake_prepend_path(SCAM_FILES_DOC ${PROJECT_SOURCE_DIR}/../) + +add_library(scam SHARED ${SCAM_FILES_SRC} ${SCAM_FILES_INC} ${SCAM_FILES_INC_API}) +target_link_libraries(scam RSys m) + +set_target_properties(scam PROPERTIES + DEFINE_SYMBOL SCAM_SHARED_BUILD + VERSION ${VERSION} + SOVERSION ${VERSION_MAJOR}) + +rcmake_setup_devel(scam StarCamera ${VERSION} star/scam_version.h) + +################################################################################ +# Add tests +################################################################################ +if(NOT NO_TEST) + function(build_test _name) + add_executable(${_name} ${SCAM_SOURCE_DIR}/${_name}.c) + target_link_libraries(${_name} scam RSys) + endfunction() + + function(new_test _name) + build_test(${_name}) + add_test(${_name}_${_palette} ${_name}) + endfunction() +endif() + +################################################################################ +# Define output & install directories +################################################################################ +install(TARGETS scam + ARCHIVE DESTINATION bin + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) +install(FILES ${SCAM_FILES_INC_API} DESTINATION include/star) +install(FILES ${SCAM_FILES_DOC} DESTINATION share/doc/star-camera) + diff --git a/src/scam.c b/src/scam.c @@ -0,0 +1,105 @@ +/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "scam_c.h" +#include "scam_log.h" + +#include <rsys/logger.h> +#include <rsys/mem_allocator.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +release_scam(ref_T* ref) +{ + struct scam* cam = CONTAINER_OF(ref, struct scam, ref); + ASSERT(ref); + if(cam->logger == &cam->logger__) logger_release(&cam->logger__); + MEM_RM(cam->allocator, cam); +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +scam_ref_get(struct scam* cam) +{ + if(!cam) return RES_BAD_ARG; + ref_get(&cam->ref); + return RES_OK; +} + +res_T +scam_ref_put(struct scam* cam) +{ + if(!cam) return RES_BAD_ARG; + ref_put(&cam->ref, release_scam); + return RES_OK; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +camera_create + (struct logger* logger, + struct mem_allocator* mem_allocator, + const int verbose, /* Verbosity level */ + const enum scam_type type, + struct scam** out_cam) +{ + struct scam* cam = NULL; + struct mem_allocator* allocator = NULL; + res_T res = RES_OK; + ASSERT(out_cam && (unsigned)type < SCAM_TYPES_COUNT__); + + allocator = mem_allocator ? mem_allocator : &mem_default_allocator; + cam = MEM_CALLOC(allocator, 1, sizeof(*cam)); + if(!cam) { + if(verbose) { + #define ERR_STR "Could not allocate the Star-Camera.\n" + if(logger) { + logger_print(logger, LOG_ERROR, ERR_STR); + } else { + fprintf(stderr, MSG_ERROR_PREFIX ERR_STR); + } + #undef ERR_STR + } + res = RES_MEM_ERR; + goto error; + } + ref_init(&cam->ref); + cam->allocator = allocator; + cam->type = type; + cam->verbose = verbose; + + if(logger) { + cam->logger = logger; + } else { + setup_log_default(cam); + } + +exit: + if(out_cam) *out_cam = cam; + return res; +error: + if(cam) { + SCAM(ref_put(cam)); + cam = NULL; + } + goto exit; +} + diff --git a/src/scam.h b/src/scam.h @@ -0,0 +1,92 @@ +/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SCAM_H +#define SCAM_H + +#include <rsys/rsys.h> + +/* Library symbol management */ +#if defined(SCAM_SHARED_BUILD) /* Build shared library */ + #define SCAM_API extern EXPORT_SYM +#elif defined(SCAM_STATIC) /* Use/build static library */ + #define SCAM_API extern LOCAL_SYM +#else /* Use shared library */ + #define SCAM_API extern IMPORT_SYM +#endif + +/* Helper macro that asserts if the invocation of the suvm function `Func' + * returns an error. One should use this macro on scam function calls for + * which no explicit error checking is performed */ +#ifndef NDEBUG + #define SCAM(Func) ASSERT(scam_ ## Func == RES_OK) +#else + #define SCAM(Func) scam_ ## Func +#endif + +enum scam_type { + SCAM_PINHOLE, + SCAM_TYPES_COUNT__, + SCAM_NONE = SCAM_TYPES_COUNT__ +}; + +struct scam_pinhole_args { + double position[3]; /* Focal point */ + double target[3]; /* Targeted point. target-position = image plane normal */ + double up[3]; /* Vector defining the upward orientation */ + double aspect_ratio; /* Image plane aspect ratio (width / height) */ + double field_of_view; /* Vertical field of view in radians */ +}; +#define SCAM_PINHOLE_ARGS_DEFAULT__ { \ + {0,0,0}, /* Position */ \ + {0,1,0}, /* Target */ \ + {0,0,1}, /* Up */ \ + 1.0, /* Aspect ratio */ \ + 1.22173047639603070383, /* ~70 degrees */ \ +} +static const struct scam_pinhole_args SCAM_PINHOLE_ARGS_DEFAULT = + SCAM_PINHOLE_ARGS_DEFAULT__; + +/* Forward declaration of external data types */ +struct logger; +struct mem_allocator; + +/* Opaque data type */ +struct scam; + +/******************************************************************************* + * Star-Camera API + ******************************************************************************/ +BEGIN_DECLS + +SCAM_API res_T +scam_create_pinhole + (struct logger* logger, /* NULL <=> use builtin logger */ + struct mem_allocator* allocator, /* NULL <=> use default allocator */ + const int verbose, /* Verbosity level */ + struct scam_pinhole_args* args, + struct scam** camera); + +SCAM_API res_T +scam_ref_get + (struct scam* camera); + +SCAM_API res_T +scam_ref_put + (struct scam* camera); + +END_DECLS + +#endif /* SCAM_H */ diff --git a/src/scam_c.h b/src/scam_c.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SCAM_C_H +#define SCAM_C_H + +#include "scam.h" /* For enum scam_type */ + +#include <rsys/logger.h> +#include <rsys/ref_count.h> + +struct pinhole { + /* Orthogonal basis of the camera */ + double axis_x[3]; + double axis_y[3]; + double axis_z[3]; + + /* Focal point */ + double position[3]; +}; + +struct scam { + enum scam_type type; + union { + struct pinhole pinhole; + } param; + + int verbose; + struct logger* logger; + struct logger logger__; + + struct mem_allocator* allocator; + ref_T ref; +}; + + +extern LOCAL_SYM res_T +camera_create + (struct logger* logger, /* NULL <=> use builtin logger */ + struct mem_allocator* allocator, /* NULL <=> use default allocator */ + const int verbose, /* Verbosity level */ + const enum scam_type type, + struct scam** scam); + +#endif /* SCAM_C_H */ diff --git a/src/scam_log.c b/src/scam_log.c @@ -0,0 +1,122 @@ +/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "scam_c.h" +#include "scam_log.h" + +#include <rsys/cstr.h> +#include <rsys/logger.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE void +log_msg + (const struct scam* cam, + const enum log_type stream, + const char* msg, + va_list vargs) +{ + ASSERT(cam && msg); + if(cam->verbose) { + res_T res; (void)res; + res = logger_vprint(cam->logger, stream, msg, vargs); + ASSERT(res == RES_OK); + } +} + +static void +print_info(const char* msg, void* ctx) +{ + (void)ctx; + fprintf(stderr, MSG_INFO_PREFIX"%s", msg); +} + +static void +print_err(const char* msg, void* ctx) +{ + (void)ctx; + fprintf(stderr, MSG_ERROR_PREFIX"%s", msg); +} + +static void +print_warn(const char* msg, void* ctx) +{ + (void)ctx; + fprintf(stderr, MSG_WARNING_PREFIX"%s", msg); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +setup_log_default(struct scam* cam) +{ + res_T res = RES_OK; + ASSERT(cam); + + res = logger_init(cam->allocator, &cam->logger__); + if(res != RES_OK) { + if(cam->verbose) { + fprintf(stderr, + MSG_ERROR_PREFIX + "Could not setup the Star-Camera default logger -- %s.\n", + res_to_cstr(res)); + } + goto error; + } + logger_set_stream(&cam->logger__, LOG_OUTPUT, print_info, NULL); + logger_set_stream(&cam->logger__, LOG_ERROR, print_err, NULL); + logger_set_stream(&cam->logger__, LOG_WARNING, print_warn, NULL); + cam->logger = &cam->logger__; + +exit: + return res; +error: + goto exit; +} + +void +log_info(const struct scam* cam, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(cam && msg); + + va_start(vargs_list, msg); + log_msg(cam, LOG_OUTPUT, msg, vargs_list); + va_end(vargs_list); +} + +void +log_err(const struct scam* cam, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(cam && msg); + + va_start(vargs_list, msg); + log_msg(cam, LOG_ERROR, msg, vargs_list); + va_end(vargs_list); +} + +void +log_warn(const struct scam* cam, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(cam && msg); + + va_start(vargs_list, msg); + log_msg(cam, LOG_WARNING, msg, vargs_list); + va_end(vargs_list); +} diff --git a/src/scam_log.h b/src/scam_log.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SCAM_LOG_H +#define SCAM_LOG_H + +#include <rsys/rsys.h> + +#define MSG_INFO_PREFIX "Star-Camera:\x1b[1m\x1b[32minfo\x1b[0m: " +#define MSG_ERROR_PREFIX "Star-Camera:\x1b[1m\x1b[31merror\x1b[0m: " +#define MSG_WARNING_PREFIX "Star-Camera:\x1b[1m\x1b[33mwarning\x1b[0m: " + +extern LOCAL_SYM res_T +setup_log_default + (struct scam* cam); + +/* Conditionally log a message on the LOG_OUTPUT stream of the atrstm logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_info + (const struct scam* cam, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +/* Conditionally log a message on the LOG_ERROR stream of the scam logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_err + (const struct scam* cam, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +/* Conditionally log a message on the LOG_WARNING stream of the scam logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_warn + (const struct scam* cam, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +#endif /* SCAM_LOG_H */ diff --git a/src/scam_pinhole.c b/src/scam_pinhole.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "scam_c.h" +#include "scam_log.h" + +#include <rsys/double3.h> +#include <rsys/math.h> + +#include <math.h> + +/******************************************************************************* + * Helper function + ******************************************************************************/ +static res_T +setup_pinhole(struct scam* cam, const struct scam_pinhole_args* args) +{ + double x[3], y[3], z[3]; + double img_plane_depth; + res_T res = RES_OK; + ASSERT(cam && args && cam->type == SCAM_PINHOLE); + + if(args->field_of_view <= 0 || args->field_of_view >= PI) { + log_err(cam, + "pinhole camera: invalid vertical field of view: `%g'\n", + args->field_of_view); + res = RES_BAD_ARG; + goto error; + } + + if(args->aspect_ratio <= 0) { + log_err(cam, + "pinhole camera: invalid aspect ratio: `%g'\n", + args->aspect_ratio); + res = RES_BAD_ARG; + goto error; + } + + if(d3_normalize(z, d3_sub(z, args->target, args->position)) <= 0 + || d3_normalize(x, d3_cross(x, z, args->up)) <= 0 + || d3_normalize(y, d3_cross(y, z, x)) <= 0) { + log_err(cam, + "pinhole camera: invalid point of view:\n" + " position = %g %g %g\n" + " target = %g %g %g\n" + " up = %g %g %g\n", + SPLIT3(args->position), SPLIT3(args->target), SPLIT3(args->up)); + res = RES_BAD_ARG; + goto error; + } + + img_plane_depth = 1.0/tan(args->field_of_view*0.5); + d3_muld(cam->param.pinhole.axis_x, x, args->aspect_ratio); + d3_set(cam->param.pinhole.axis_y, y); + d3_muld(cam->param.pinhole.axis_z, z, img_plane_depth); + d3_set(cam->param.pinhole.position, args->position); + +exit: + return res; +error: + goto exit; +} + +/******************************************************************************* + * Exported function + ******************************************************************************/ +SCAM_API res_T +scam_create_pinhole + (struct logger* logger, /* NULL <=> use builtin logger */ + struct mem_allocator* allocator, /* NULL <=> use default allocator */ + const int verbose, /* Verbosity level */ + struct scam_pinhole_args* args, + struct scam** out_cam) +{ + struct scam* cam = NULL; + res_T res = RES_OK; + + if(!out_cam) { + res = RES_BAD_ARG; + goto error; + } + + res = camera_create(logger, allocator, verbose, SCAM_PINHOLE, &cam); + if(res != RES_OK) goto error; + res = setup_pinhole(cam, args); + if(res != RES_OK) goto error; + + exit: + if(out_cam) *out_cam = cam; + return res; +error: + if(cam) { + SCAM(ref_put(cam)); + cam = NULL; + } + goto exit; +} +