diff --git a/modules/matlab/CMakeLists.txt b/modules/matlab/CMakeLists.txt index b2246ab35..f13fea7ee 100644 --- a/modules/matlab/CMakeLists.txt +++ b/modules/matlab/CMakeLists.txt @@ -50,7 +50,11 @@ ocv_add_module(matlab BINDINGS opencv_core #TODO: does it actually NEED to dep # TODO: Undo this when building all modules to find python properly #set(HDR_PARSER_PATH ${OPENCV_MODULE_opencv_python_LOCATION}/src2) set(HDR_PARSER_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../python/src2) -prepend("-I" MEX_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include) + +# set mex compiler options +prepend("-I" MEX_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include) +prepend("-L" MEX_LIB_DIR ${CMAKE_BINARY_DIR}/lib) +set(MEX_OPTS "-largeArrayDims") if (BUILD_TESTS) add_subdirectory(test) @@ -79,7 +83,7 @@ endif() # attempt to compile the file using mex message("-- Trying to compile mex file") execute_process( - COMMAND ${MATLAB_MEX_SCRIPT} ${MEX_INCLUDES} + COMMAND ${MATLAB_MEX_SCRIPT} ${MEX_OPTS} ${MEX_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/test/test_compiler.cpp WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src ERROR_VARIABLE MEX_ERROR @@ -105,6 +109,8 @@ string(REPLACE "opencv_" "" OPENCV_MATLAB_MODULES "${OPENCV_MODULE_${the_module} foreach(module ${OPENCV_MATLAB_MODULES}) if (HAVE_opencv_${module}) list(APPEND opencv_hdrs "${OPENCV_MODULE_opencv_${module}_LOCATION}/include/opencv2/${module}.hpp") + prepend("-I" MEX_INCLUDE_DIRS "${OPENCV_MODULE_opencv_${module}_LOCATION}/include") + prepend("-l" MEX_LIBS "opencv_${module}") endif() endforeach() @@ -122,8 +128,8 @@ foreach(SOURCE_FILE ${SOURCE_FILES}) get_filename_component(FILENAME ${SOURCE_FILE} NAME_WE) # compile the source file using mex add_custom_command(TARGET opencv_matlab PRE_BUILD - COMMAND echo ${MATLAB_MEX_SCRIPT} ${MEX_INCLUDES} - ${SOURCE_FILE} + COMMAND ${MATLAB_MEX_SCRIPT} ${MEX_OPTS} ${MEX_INCLUDE_DIRS} + ${MEX_LIB_DIR} ${MEX_LIBS} ${SOURCE_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src ) endforeach() diff --git a/modules/matlab/generator/templates/functional.cpp b/modules/matlab/generator/templates/functional.cpp index fac3cce6b..be81daf1e 100644 --- a/modules/matlab/generator/templates/functional.cpp +++ b/modules/matlab/generator/templates/functional.cpp @@ -7,8 +7,9 @@ / {% macro compose(fun) %} {# ----------- Return type ------------- #} - {%- if not fun.rtp|void -%} {{fun.rtp}} retval = {% endif -%} - cv::{{fun.name}}( + {%- if not fun.rtp|void -%} retval = {% endif -%} + {%- if fun.clss -%}inst.{%- else -%} cv:: {% endif -%} + {{fun.name}}( {#- ----------- Required ------------- -#} {%- for arg in fun.req -%} {%- if arg.ref == '*' -%}&{%- endif -%} @@ -34,7 +35,7 @@ {{arg.tp}} {{arg.name}} = inputs[{{ loop.index0 }}]; {% endfor %} {% for opt in fun.opt|inputs %} - {{opt.tp}} {{opt.name}} = (nrhs > {{loop.index0 + fun.req|inputs|length}}) ? inputs[{{loop.index0 + fun.req|inputs|length}}] : {{opt.default}}; + {{opt.tp}} {{opt.name}} = (nrhs > {{loop.index0 + fun.req|inputs|length}}) ? ({{opt.tp}})inputs[{{loop.index0 + fun.req|inputs|length}}] : {{opt.default}}; {% endfor %} {# ----------- Outputs ------------ #} {% for arg in fun.req|only|outputs %} @@ -43,6 +44,9 @@ {% for opt in fun.opt|only|outputs %} {{opt.tp}} {{opt.name}}; {% endfor %} + {% if not fun.rtp|void %} + {{fun.rtp}} retval; + {% endif %} // call the opencv function // [out =] namespace.fun(src1, ..., srcn, dst1, ..., dstn, opt1, ..., optn); diff --git a/modules/matlab/generator/templates/template_class_base.cpp b/modules/matlab/generator/templates/template_class_base.cpp index 48ebc5083..872f563b0 100644 --- a/modules/matlab/generator/templates/template_class_base.cpp +++ b/modules/matlab/generator/templates/template_class_base.cpp @@ -11,11 +11,11 @@ #include "mex.h" #include "bridge.hpp" #include +//TODO: Standard C++ does not have an unordered_map (only C++11 and Boost) #include #include #include -{% block includes %} -{% endblock %} +using namespace cv; namespace { @@ -25,12 +25,7 @@ typedef std::vector (*)({{clss.name}}&, const std::vector&) Meth {% for function in clss.functions %} // wrapper for {{function.name}}() method std::vector {{function.name}}({{clss.name}}& inst, const std::vector& args) { - // setup - - // invoke {{ functional.generate(function) }} - - // setdown } {% endfor %} diff --git a/modules/matlab/generator/templates/template_class_base.m b/modules/matlab/generator/templates/template_class_base.m index 6e7bce81c..1507bbdab 100644 --- a/modules/matlab/generator/templates/template_class_base.m +++ b/modules/matlab/generator/templates/template_class_base.m @@ -1,5 +1,5 @@ % {{clss.name | upper}} -% Matlab handle clss for OpenCV object clsses +% Matlab handle class for OpenCV object classes % % This file was autogenerated, do not modify. % See LICENCE for full modification and redistribution details. @@ -20,7 +20,7 @@ classdef {{clss.name}} < handle {{clss.name}}Bridge(this.ptr_, 'delete'); end - {% for function in clss.functions -%} + {% for function in clss.functions %} % {{function.__str__()}} function varargout = {{function.name}}(this, varargin) [varargout{1:nargout}] = {{clss.name}}Bridge('{{function.name}}', this.ptr_, varargin{:}); diff --git a/modules/matlab/generator/templates/template_function_base.cpp b/modules/matlab/generator/templates/template_function_base.cpp index 9f3bb7643..192af46c9 100644 --- a/modules/matlab/generator/templates/template_function_base.cpp +++ b/modules/matlab/generator/templates/template_function_base.cpp @@ -14,8 +14,7 @@ #include #include #include -{% block includes %} -{% endblock %} +using namespace cv; /* * {{ fun.name }} diff --git a/modules/matlab/include/bridge.hpp b/modules/matlab/include/bridge.hpp index 467eb1ff4..7e93e0af6 100644 --- a/modules/matlab/include/bridge.hpp +++ b/modules/matlab/include/bridge.hpp @@ -2,5 +2,56 @@ #define OPENCV_BRIDGE_HPP_ #include "mex.h" +#include + +/*! + * @class Bridge + * @brief Type conversion class for converting OpenCV and native C++ types + * + * Bridge provides an interface for converting between OpenCV/C++ types + * to Matlab's mxArray format. + * + * Each type conversion requires three operators: + * // conversion from ObjectType --> Bridge + * Bridge& operator=(const ObjectType&); + * // implicit conversion from Bridge --> ObjectType + * operator ObjectType(); + * // explicit conversion from Bridge --> ObjectType + * ObjectType toObjectType + * + * The bridging class provides common conversions between OpenCV types, + * std and stl types to Matlab's mxArray format. By inheriting Bridge, + * you can add your own custom type conversions. + * + * Bridge attempts to make as few assumptions as possible, however in + * some cases where 1-to-1 mappings don't exist, some assumptions are necessary. + * In particular: + * - conversion from of a 2-channel Mat to an mxArray will result in a complex + * output + * - conversion from multi-channel interleaved Mats will result in + * multichannel planar mxArrays + * + */ +class Bridge { +public: + // bridges are default constructible + Bridge() {} + virtual ~Bridge() {} + + // --------------------------- mxArray -------------------------------------- + Bridge& operator=(const mxArray* obj) {} + Bridge(const mxArray* obj) {} + mxArray* mxArray() { return NULL; } + + // --------------------------- cv::Mat -------------------------------------- + Bridge& operator=(const cv::Mat& obj) {} + operator cv::Mat() { return cv::Mat(); } + cv::Mat toMat() { return cv::Mat(); } + + // --------------------------- int -------------------------------------- + Bridge& operator=(const int& obj) {} + operator int() { return 0; } + int toInt() { return 0; } +}; #endif