Better C++11 and C++98 support/interop. Started writing map interface. Some core functions actually run
This commit is contained in:
parent
6fd296c0b0
commit
504558c0be
modules/matlab
@ -3,7 +3,7 @@ macro(listify OUT_LIST IN_STRING)
|
|||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
listify(MEX_INCLUDE_DIRS_LIST ${MEX_INCLUDE_DIRS})
|
listify(MEX_INCLUDE_DIRS_LIST ${MEX_INCLUDE_DIRS})
|
||||||
set(MEX_CXXFLAGS "CXXFLAGS=\$CXXFLAGS -pedantic -Wall -Wextra -Weffc++ -Wno-unused -Wold-style-cast -Wshadow -Wmissing-declarations -Wmissing-include-dirs -Wnon-virtual-dtor")
|
set(MEX_CXXFLAGS "CXXFLAGS=\$CXXFLAGS -pedantic -Wall -Wextra -Weffc++ -Wno-unused -Wold-style-cast -Wshadow -Wmissing-declarations -Wmissing-include-dirs -Wnon-virtual-dtor -Wno-newline-eof")
|
||||||
file(GLOB SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/src/*.cpp")
|
file(GLOB SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/src/*.cpp")
|
||||||
foreach(SOURCE_FILE ${SOURCE_FILES})
|
foreach(SOURCE_FILE ${SOURCE_FILES})
|
||||||
# strip out the filename
|
# strip out the filename
|
||||||
|
@ -53,3 +53,4 @@ void mexFunction(int nlhs, mxArray*{% if fun|noutputs %} plhs[]{% else %}*{% end
|
|||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
#define OPENCV_BRIDGE_HPP_
|
#define OPENCV_BRIDGE_HPP_
|
||||||
|
|
||||||
#include "mex.h"
|
#include "mex.h"
|
||||||
|
#include "map.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <opencv2/core.hpp>
|
#include <opencv2/core.hpp>
|
||||||
#include <opencv2/calib3d.hpp>
|
#include <opencv2/calib3d.hpp>
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All recent versions of Matlab ship with the MKL library which contains
|
* All recent versions of Matlab ship with the MKL library which contains
|
||||||
@ -180,7 +180,7 @@ namespace Matlab {
|
|||||||
public:
|
public:
|
||||||
static std::string ToString() { return "Inherited type"; }
|
static std::string ToString() { return "Inherited type"; }
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -205,29 +205,15 @@ private:
|
|||||||
mxArray* ptr_;
|
mxArray* ptr_;
|
||||||
bool owns_;
|
bool owns_;
|
||||||
|
|
||||||
// this function is called exclusively from constructors!!
|
void dealloc() {
|
||||||
template <typename Scalar>
|
if (owns_ && ptr_) { mxDestroyArray(ptr_); ptr_ = NULL; owns_ = false; }
|
||||||
void fromMat(const cv::Mat& mat) {
|
|
||||||
mwSize dims[] = { static_cast<mwSize>(mat.rows), static_cast<mwSize>(mat.cols), static_cast<mwSize>(mat.channels()) };
|
|
||||||
ptr_ = mxCreateNumericArray(3, dims, Matlab::Traits<Scalar>::ScalarType, Matlab::Traits<>::Real);
|
|
||||||
owns_ = true;
|
|
||||||
switch (mat.depth()) {
|
|
||||||
case CV_8U: deepCopyAndTranspose<uint8_t, Scalar>(mat, *this); break;
|
|
||||||
case CV_8S: deepCopyAndTranspose<int8_t, Scalar>(mat, *this); break;
|
|
||||||
case CV_16U: deepCopyAndTranspose<uint16_t, Scalar>(mat, *this); break;
|
|
||||||
case CV_16S: deepCopyAndTranspose<int16_t, Scalar>(mat, *this); break;
|
|
||||||
case CV_32S: deepCopyAndTranspose<int32_t, Scalar>(mat, *this); break;
|
|
||||||
case CV_32F: deepCopyAndTranspose<float, Scalar>(mat, *this); break;
|
|
||||||
case CV_64F: deepCopyAndTranspose<double, Scalar>(mat, *this); break;
|
|
||||||
default: error("Attempted to convert from unknown class");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// constructors and destructor
|
// constructors and destructor
|
||||||
MxArray() : ptr_(mxCreateDoubleMatrix(1, 1, Matlab::Traits<>::Real)), owns_(true) {}
|
MxArray() : ptr_(mxCreateDoubleMatrix(1, 1, Matlab::Traits<>::Real)), owns_(true) {}
|
||||||
MxArray(const mxArray* ptr) : ptr_(const_cast<mxArray *>(ptr)), owns_(false) {}
|
MxArray(const mxArray* ptr) : ptr_(const_cast<mxArray *>(ptr)), owns_(false) {}
|
||||||
virtual ~MxArray() {
|
virtual ~MxArray() {
|
||||||
if (owns_ && ptr_) mxDestroyArray(ptr_);
|
dealloc();
|
||||||
}
|
}
|
||||||
// copy constructor
|
// copy constructor
|
||||||
// all copies are deep copies
|
// all copies are deep copies
|
||||||
@ -286,9 +272,25 @@ public:
|
|||||||
ptr_ = mxCreateNumericArray(3, dims, Matlab::Traits<Scalar>::ScalarType, Matlab::Traits<>::Real);
|
ptr_ = mxCreateNumericArray(3, dims, Matlab::Traits<Scalar>::ScalarType, Matlab::Traits<>::Real);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this function is called exclusively from constructors!!
|
||||||
template <typename Scalar>
|
template <typename Scalar>
|
||||||
explicit MxArray(const cv::Mat& mat) : owns_(false) {
|
MxArray& fromMat(const cv::Mat& mat) {
|
||||||
fromMat<Scalar>(mat);
|
// dealloc any existing storage before reallocating
|
||||||
|
dealloc();
|
||||||
|
mwSize dims[] = { static_cast<mwSize>(mat.rows), static_cast<mwSize>(mat.cols), static_cast<mwSize>(mat.channels()) };
|
||||||
|
ptr_ = mxCreateNumericArray(3, dims, Matlab::Traits<Scalar>::ScalarType, Matlab::Traits<>::Real);
|
||||||
|
owns_ = true;
|
||||||
|
switch (mat.depth()) {
|
||||||
|
case CV_8U: deepCopyAndTranspose<uint8_t, Scalar>(mat, *this); break;
|
||||||
|
case CV_8S: deepCopyAndTranspose<int8_t, Scalar>(mat, *this); break;
|
||||||
|
case CV_16U: deepCopyAndTranspose<uint16_t, Scalar>(mat, *this); break;
|
||||||
|
case CV_16S: deepCopyAndTranspose<int16_t, Scalar>(mat, *this); break;
|
||||||
|
case CV_32S: deepCopyAndTranspose<int32_t, Scalar>(mat, *this); break;
|
||||||
|
case CV_32F: deepCopyAndTranspose<float, Scalar>(mat, *this); break;
|
||||||
|
case CV_64F: deepCopyAndTranspose<double, Scalar>(mat, *this); break;
|
||||||
|
default: error("Attempted to convert from unknown class");
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Scalar>
|
template <typename Scalar>
|
||||||
@ -364,17 +366,18 @@ public:
|
|||||||
* that gets mapped to an unsigned 8-bit value
|
* that gets mapped to an unsigned 8-bit value
|
||||||
*/
|
*/
|
||||||
template <>
|
template <>
|
||||||
void MxArray::fromMat<Matlab::InheritType>(const cv::Mat& mat) {
|
MxArray& MxArray::fromMat<Matlab::InheritType>(const cv::Mat& mat) {
|
||||||
switch (mat.depth()) {
|
switch (mat.depth()) {
|
||||||
case CV_8U: fromMat<uint8_t>(mat); break;
|
case CV_8U: return fromMat<uint8_t>(mat); break;
|
||||||
case CV_8S: fromMat<int8_t>(mat); break;
|
case CV_8S: return fromMat<int8_t>(mat); break;
|
||||||
case CV_16U: fromMat<uint16_t>(mat); break;
|
case CV_16U: return fromMat<uint16_t>(mat); break;
|
||||||
case CV_16S: fromMat<int16_t>(mat); break;
|
case CV_16S: return fromMat<int16_t>(mat); break;
|
||||||
case CV_32S: fromMat<int32_t>(mat); break;
|
case CV_32S: return fromMat<int32_t>(mat); break;
|
||||||
case CV_32F: fromMat<double>(mat); break; //NOTE: Matlab uses double as native type!
|
case CV_32F: return fromMat<double>(mat); break; //NOTE: Matlab uses double as native type!
|
||||||
case CV_64F: fromMat<double>(mat); break;
|
case CV_64F: return fromMat<double>(mat); break;
|
||||||
default: error("Attempted to convert from unknown class");
|
default: error("Attempted to convert from unknown class");
|
||||||
}
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -412,13 +415,40 @@ cv::Mat MxArray::toMat<Matlab::InheritType>() const {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
template <typename InputScalar, typename OutputScalar>
|
template <typename InputScalar, typename OutputScalar>
|
||||||
void deepCopyAndTranspose(const cv::Mat&, MxArray&) {
|
void deepCopyAndTranspose(const cv::Mat& in, MxArray& out) {
|
||||||
|
conditionalError(static_cast<size_t>(in.rows) == out.rows(), "Matrices must have the same number of rows");
|
||||||
|
conditionalError(static_cast<size_t>(in.cols) == out.cols(), "Matrices must have the same number of cols");
|
||||||
|
conditionalError(static_cast<size_t>(in.channels()) == out.channels(), "Matrices must have the same number of channels");
|
||||||
|
OutputScalar* outp = out.real<OutputScalar>();
|
||||||
|
const size_t M = out.rows();
|
||||||
|
const size_t N = out.cols();
|
||||||
|
for (size_t m = 0; m < M; ++m) {
|
||||||
|
const InputScalar* inp = in.ptr<InputScalar>(m);
|
||||||
|
for (size_t n = 0; n < N; ++n) {
|
||||||
|
// copy and transpose
|
||||||
|
outp[m + n*M] = inp[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputScalar, typename OutputScalar>
|
template <typename InputScalar, typename OutputScalar>
|
||||||
void deepCopyAndTranspose(const MxArray&, cv::Mat&) {
|
void deepCopyAndTranspose(const MxArray& in, cv::Mat& out) {
|
||||||
|
conditionalError(in.rows() == static_cast<size_t>(out.rows), "Matrices must have the same number of rows");
|
||||||
|
conditionalError(in.cols() == static_cast<size_t>(out.cols), "Matrices must have the same number of cols");
|
||||||
|
conditionalError(in.channels() == static_cast<size_t>(out.channels()), "Matrices must have the same number of channels");
|
||||||
|
const InputScalar* inp = in.real<InputScalar>();
|
||||||
|
const size_t M = in.rows();
|
||||||
|
const size_t N = in.cols();
|
||||||
|
for (size_t m = 0; m < M; ++m) {
|
||||||
|
OutputScalar* outp = out.ptr<OutputScalar>(m);
|
||||||
|
for (size_t n = 0; n < N; ++n) {
|
||||||
|
// copy and transpose
|
||||||
|
outp[n] = inp[m + n*M];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void deepCopyAndTranspose<float, float>(const cv::Mat&, MxArray&) {
|
void deepCopyAndTranspose<float, float>(const cv::Mat&, MxArray&) {
|
||||||
}
|
}
|
||||||
@ -583,7 +613,7 @@ public:
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
// --------------------------- cv::Mat --------------------------------------
|
// --------------------------- cv::Mat --------------------------------------
|
||||||
Bridge& operator=(const cv::Mat& ) { return *this; }
|
Bridge& operator=(const cv::Mat& mat) { ptr_ = MxArray().fromMat<Matlab::InheritType>(mat); return *this; }
|
||||||
cv::Mat toMat() const { return ptr_.toMat<Matlab::InheritType>(); }
|
cv::Mat toMat() const { return ptr_.toMat<Matlab::InheritType>(); }
|
||||||
operator cv::Mat() const { return toMat(); }
|
operator cv::Mat() const { return toMat(); }
|
||||||
|
|
||||||
|
46
modules/matlab/include/map.hpp
Normal file
46
modules/matlab/include/map.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef OPENCV_MAP_HPP_
|
||||||
|
#define OPENCV_MAP_HPP_
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
|
||||||
|
// If we have C++11 support, we just want to use unordered_map
|
||||||
|
#include <unordered_map>
|
||||||
|
template <typename KeyType, typename ValueType>
|
||||||
|
using Map = std::unordered_map<KeyType, ValueType>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// If we don't have C++11 support, we wrap another map implementation
|
||||||
|
// in the same public API as unordered_map
|
||||||
|
#include <map>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
template <typename KeyType, typename ValueType>
|
||||||
|
class Map {
|
||||||
|
private:
|
||||||
|
std::map<KeyType, ValueType> map_;
|
||||||
|
public:
|
||||||
|
// map[key] = val;
|
||||||
|
ValueType& operator[] (const KeyType& k) {
|
||||||
|
return map_[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
// map.at(key) = val (throws)
|
||||||
|
ValueType& at(const KeyType& k) {
|
||||||
|
typename std::map<KeyType, ValueType>::iterator it;
|
||||||
|
it = map_.find(k);
|
||||||
|
if (it == map_.end()) throw std::out_of_range("Key not found");
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// val = map.at(key) (throws, const)
|
||||||
|
const ValueType& at(const KeyType& k) const {
|
||||||
|
typename std::map<KeyType, ValueType>::const_iterator it;
|
||||||
|
it = map_.find(k);
|
||||||
|
if (it == map_.end()) throw std::out_of_range("Key not found");
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user