|
|
|
@@ -49,6 +49,9 @@
|
|
|
|
|
#include <opencv2/core.hpp>
|
|
|
|
|
#include <opencv2/calib3d.hpp>
|
|
|
|
|
|
|
|
|
|
namespace cv {
|
|
|
|
|
namespace bridge {
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Custom typedefs
|
|
|
|
|
* Parsed names from the hdr_parser
|
|
|
|
@@ -72,10 +75,10 @@ typedef cv::Ptr<cv::FeatureDetector> Ptr_FeatureDetector;
|
|
|
|
|
class Bridge;
|
|
|
|
|
|
|
|
|
|
template <typename InputScalar, typename OutputScalar>
|
|
|
|
|
void deepCopyAndTranspose(const cv::Mat& src, MxArray& dst);
|
|
|
|
|
void deepCopyAndTranspose(const cv::Mat& src, matlab::MxArray& dst);
|
|
|
|
|
|
|
|
|
|
template <typename InputScalar, typename OutputScalar>
|
|
|
|
|
void deepCopyAndTranspose(const MxArray& src, cv::Mat& dst);
|
|
|
|
|
void deepCopyAndTranspose(const matlab::MxArray& src, cv::Mat& dst);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -104,7 +107,7 @@ void deepCopyAndTranspose(const MxArray& src, cv::Mat& dst);
|
|
|
|
|
* you can add your own custom type conversions.
|
|
|
|
|
*
|
|
|
|
|
* Because Matlab uses a homogeneous storage type, all operations are provided
|
|
|
|
|
* relative to Matlab's type. That is, Bridge always stores an MxArray object
|
|
|
|
|
* relative to Matlab's type. That is, Bridge always stores an matlab::MxArray object
|
|
|
|
|
* and converts to and from other object types on demand.
|
|
|
|
|
*
|
|
|
|
|
* NOTE: for the explicit conversion function, the object name must be
|
|
|
|
@@ -126,7 +129,7 @@ void deepCopyAndTranspose(const MxArray& src, cv::Mat& dst);
|
|
|
|
|
*/
|
|
|
|
|
class Bridge {
|
|
|
|
|
private:
|
|
|
|
|
MxArray ptr_;
|
|
|
|
|
matlab::MxArray ptr_;
|
|
|
|
|
public:
|
|
|
|
|
// bridges are default constructible
|
|
|
|
|
Bridge() {}
|
|
|
|
@@ -145,11 +148,11 @@ public:
|
|
|
|
|
// check that the object is actually of correct type before unpacking
|
|
|
|
|
// TODO: Traverse class hierarchy?
|
|
|
|
|
if (!ptr_.isClass(name)) {
|
|
|
|
|
error(std::string("Expected class ").append(std::string(name))
|
|
|
|
|
matlab::error(std::string("Expected class ").append(std::string(name))
|
|
|
|
|
.append(" but was given ").append(ptr_.className()));
|
|
|
|
|
}
|
|
|
|
|
// get the instance field
|
|
|
|
|
MxArray inst = ptr_.field("inst_");
|
|
|
|
|
matlab::MxArray inst = ptr_.field("inst_");
|
|
|
|
|
Object* obj = NULL;
|
|
|
|
|
// make sure the pointer is the correct size for the system
|
|
|
|
|
if (sizeof(void *) == 8 && inst.ID() == mxUINT64_CLASS) {
|
|
|
|
@@ -160,11 +163,11 @@ public:
|
|
|
|
|
// 32-bit pointers
|
|
|
|
|
obj = reinterpret_cast<Object *>(inst.scalar<uint32_t>());
|
|
|
|
|
} else {
|
|
|
|
|
error("Incorrect pointer type stored for architecture");
|
|
|
|
|
matlab::error("Incorrect pointer type stored for architecture");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// finally check if the object is NULL
|
|
|
|
|
conditionalError(obj, std::string("Object ").append(std::string(name)).append(std::string(" is NULL")));
|
|
|
|
|
matlab::conditionalError(obj, std::string("Object ").append(std::string(name)).append(std::string(" is NULL")));
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -173,10 +176,10 @@ public:
|
|
|
|
|
// MATLAB TYPES
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
Bridge& operator=(const mxArray* obj) { ptr_ = obj; return *this; }
|
|
|
|
|
Bridge& operator=(const MxArray& obj) { ptr_ = obj; return *this; }
|
|
|
|
|
Bridge(const MxArray& obj) : ptr_(obj) {}
|
|
|
|
|
Bridge& operator=(const matlab::MxArray& obj) { ptr_ = obj; return *this; }
|
|
|
|
|
Bridge(const matlab::MxArray& obj) : ptr_(obj) {}
|
|
|
|
|
Bridge(const mxArray* obj) : ptr_(obj) {}
|
|
|
|
|
MxArray toMxArray() { return ptr_; }
|
|
|
|
|
matlab::MxArray toMxArray() { return ptr_; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
@@ -187,8 +190,8 @@ public:
|
|
|
|
|
operator cv::Mat() const { return toMat(); }
|
|
|
|
|
|
|
|
|
|
template <typename Scalar>
|
|
|
|
|
static MxArray FromMat(const cv::Mat& mat) {
|
|
|
|
|
MxArray arr(mat.rows, mat.cols, mat.channels(), Matlab::Traits<Scalar>::ScalarType);
|
|
|
|
|
static matlab::MxArray FromMat(const cv::Mat& mat) {
|
|
|
|
|
matlab::MxArray arr(mat.rows, mat.cols, mat.channels(), matlab::Traits<Scalar>::ScalarType);
|
|
|
|
|
switch (mat.depth()) {
|
|
|
|
|
case CV_8U: deepCopyAndTranspose<uint8_t, Scalar>(mat, arr); break;
|
|
|
|
|
case CV_8S: deepCopyAndTranspose<int8_t, Scalar>(mat, arr); break;
|
|
|
|
@@ -197,7 +200,7 @@ public:
|
|
|
|
|
case CV_32S: deepCopyAndTranspose<int32_t, Scalar>(mat, arr); break;
|
|
|
|
|
case CV_32F: deepCopyAndTranspose<float, Scalar>(mat, arr); break;
|
|
|
|
|
case CV_64F: deepCopyAndTranspose<double, Scalar>(mat, arr); break;
|
|
|
|
|
default: error("Attempted to convert from unknown class");
|
|
|
|
|
default: matlab::error("Attempted to convert from unknown class");
|
|
|
|
|
}
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
@@ -218,7 +221,7 @@ public:
|
|
|
|
|
case mxDOUBLE_CLASS: deepCopyAndTranspose<double, Scalar>(ptr_, mat); break;
|
|
|
|
|
case mxCHAR_CLASS: deepCopyAndTranspose<char, Scalar>(ptr_, mat); break;
|
|
|
|
|
case mxLOGICAL_CLASS: deepCopyAndTranspose<int8_t, Scalar>(ptr_, mat); break;
|
|
|
|
|
default: error("Attempted to convert from unknown class");
|
|
|
|
|
default: matlab::error("Attempted to convert from unknown class");
|
|
|
|
|
}
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
@@ -393,9 +396,13 @@ public:
|
|
|
|
|
Ptr_FeatureDetector toPtrFeatureDetector() { return Ptr_FeatureDetector(); }
|
|
|
|
|
operator Ptr_FeatureDetector() { return toPtrFeatureDetector(); }
|
|
|
|
|
|
|
|
|
|
}; // class Bridge
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// SPECIALIZATIONS
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* @brief template specialization for inheriting types
|
|
|
|
@@ -407,7 +414,7 @@ public:
|
|
|
|
|
* that gets mapped to an unsigned 8-bit value
|
|
|
|
|
*/
|
|
|
|
|
template <>
|
|
|
|
|
MxArray Bridge::FromMat<Matlab::InheritType>(const cv::Mat& mat) {
|
|
|
|
|
matlab::MxArray Bridge::FromMat<matlab::InheritType>(const cv::Mat& mat) {
|
|
|
|
|
switch (mat.depth()) {
|
|
|
|
|
case CV_8U: return FromMat<uint8_t>(mat);
|
|
|
|
|
case CV_8S: return FromMat<int8_t>(mat);
|
|
|
|
@@ -416,9 +423,9 @@ MxArray Bridge::FromMat<Matlab::InheritType>(const cv::Mat& mat) {
|
|
|
|
|
case CV_32S: return FromMat<int32_t>(mat);
|
|
|
|
|
case CV_32F: return FromMat<double>(mat); //NOTE: Matlab uses double as native type!
|
|
|
|
|
case CV_64F: return FromMat<double>(mat);
|
|
|
|
|
default: error("Attempted to convert from unknown class");
|
|
|
|
|
default: matlab::error("Attempted to convert from unknown class");
|
|
|
|
|
}
|
|
|
|
|
return MxArray();
|
|
|
|
|
return matlab::MxArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@@ -430,7 +437,7 @@ MxArray Bridge::FromMat<Matlab::InheritType>(const cv::Mat& mat) {
|
|
|
|
|
* to unsignd 8-bit value.
|
|
|
|
|
*/
|
|
|
|
|
template <>
|
|
|
|
|
cv::Mat Bridge::toMat<Matlab::InheritType>() const {
|
|
|
|
|
cv::Mat Bridge::toMat<matlab::InheritType>() const {
|
|
|
|
|
switch (ptr_.ID()) {
|
|
|
|
|
case mxINT8_CLASS: return toMat<int8_t>();
|
|
|
|
|
case mxUINT8_CLASS: return toMat<uint8_t>();
|
|
|
|
@@ -444,13 +451,13 @@ cv::Mat Bridge::toMat<Matlab::InheritType>() const {
|
|
|
|
|
case mxDOUBLE_CLASS: return toMat<float>(); //NOTE: OpenCV uses float as native type!
|
|
|
|
|
case mxCHAR_CLASS: return toMat<int8_t>();
|
|
|
|
|
case mxLOGICAL_CLASS: return toMat<int8_t>();
|
|
|
|
|
default: error("Attempted to convert from unknown class");
|
|
|
|
|
default: matlab::error("Attempted to convert from unknown class");
|
|
|
|
|
}
|
|
|
|
|
return cv::Mat();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bridge& Bridge::operator=(const cv::Mat& mat) { ptr_ = FromMat<Matlab::InheritType>(mat); return *this; }
|
|
|
|
|
cv::Mat Bridge::toMat() const { return toMat<Matlab::InheritType>(); }
|
|
|
|
|
Bridge& Bridge::operator=(const cv::Mat& mat) { ptr_ = FromMat<matlab::InheritType>(mat); return *this; }
|
|
|
|
|
cv::Mat Bridge::toMat() const { return toMat<matlab::InheritType>(); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
@@ -459,10 +466,10 @@ cv::Mat Bridge::toMat() const { return toMat<Matlab::InheritType>(); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename InputScalar, typename OutputScalar>
|
|
|
|
|
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");
|
|
|
|
|
void deepCopyAndTranspose(const cv::Mat& in, matlab::MxArray& out) {
|
|
|
|
|
matlab::conditionalError(static_cast<size_t>(in.rows) == out.rows(), "Matrices must have the same number of rows");
|
|
|
|
|
matlab::conditionalError(static_cast<size_t>(in.cols) == out.cols(), "Matrices must have the same number of cols");
|
|
|
|
|
matlab::conditionalError(static_cast<size_t>(in.channels()) == out.channels(), "Matrices must have the same number of channels");
|
|
|
|
|
std::vector<cv::Mat> channels;
|
|
|
|
|
cv::split(in, channels);
|
|
|
|
|
for (size_t c = 0; c < out.channels(); ++c) {
|
|
|
|
@@ -478,10 +485,10 @@ void deepCopyAndTranspose(const cv::Mat& in, MxArray& out) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename InputScalar, typename OutputScalar>
|
|
|
|
|
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");
|
|
|
|
|
void deepCopyAndTranspose(const matlab::MxArray& in, cv::Mat& out) {
|
|
|
|
|
matlab::conditionalError(in.rows() == static_cast<size_t>(out.rows), "Matrices must have the same number of rows");
|
|
|
|
|
matlab::conditionalError(in.cols() == static_cast<size_t>(out.cols), "Matrices must have the same number of cols");
|
|
|
|
|
matlab::conditionalError(in.channels() == static_cast<size_t>(out.channels()), "Matrices must have the same number of channels");
|
|
|
|
|
std::vector<cv::Mat> channels;
|
|
|
|
|
for (size_t c = 0; c < in.channels(); ++c) {
|
|
|
|
|
cv::Mat outmat;
|
|
|
|
@@ -499,4 +506,8 @@ void deepCopyAndTranspose(const MxArray& in, cv::Mat& out) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace bridge
|
|
|
|
|
} // namespace cv
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|