Commit bc93edac authored by hbristow's avatar hbristow

Removed all OpenCV-specific functionality from mxarray into bridge. mxarray is now standalone

parent 153549c7
......@@ -66,6 +66,18 @@ typedef cv::Ptr<cv::StereoSGBM> Ptr_StereoSGBM;
typedef cv::Ptr<cv::FeatureDetector> Ptr_FeatureDetector;
// ----------------------------------------------------------------------------
// PREDECLARATIONS
// ----------------------------------------------------------------------------
class Bridge;
template <typename InputScalar, typename OutputScalar>
void deepCopyAndTranspose(const cv::Mat& src, MxArray& dst);
template <typename InputScalar, typename OutputScalar>
void deepCopyAndTranspose(const MxArray& src, cv::Mat& dst);
// ----------------------------------------------------------------------------
......@@ -157,10 +169,6 @@ public:
}
// --------------------------------------------------------------------------
// MATLAB TYPES
// --------------------------------------------------------------------------
......@@ -171,7 +179,50 @@ public:
MxArray toMxArray() { return ptr_; }
// --------------------------------------------------------------------------
// MATRIX CONVERSIONS
// --------------------------------------------------------------------------
Bridge& operator=(const cv::Mat& mat);
cv::Mat toMat() const;
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);
switch (mat.depth()) {
case CV_8U: deepCopyAndTranspose<uint8_t, Scalar>(mat, arr); break;
case CV_8S: deepCopyAndTranspose<int8_t, Scalar>(mat, arr); break;
case CV_16U: deepCopyAndTranspose<uint16_t, Scalar>(mat, arr); break;
case CV_16S: deepCopyAndTranspose<int16_t, Scalar>(mat, arr); break;
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");
}
return arr;
}
template <typename Scalar>
cv::Mat toMat() const {
cv::Mat mat(ptr_.rows(), ptr_.cols(), CV_MAKETYPE(cv::DataType<Scalar>::type, ptr_.channels()));
switch (ptr_.ID()) {
case mxINT8_CLASS: deepCopyAndTranspose<int8_t, Scalar>(ptr_, mat); break;
case mxUINT8_CLASS: deepCopyAndTranspose<uint8_t, Scalar>(ptr_, mat); break;
case mxINT16_CLASS: deepCopyAndTranspose<int16_t, Scalar>(ptr_, mat); break;
case mxUINT16_CLASS: deepCopyAndTranspose<uint16_t, Scalar>(ptr_, mat); break;
case mxINT32_CLASS: deepCopyAndTranspose<int32_t, Scalar>(ptr_, mat); break;
case mxUINT32_CLASS: deepCopyAndTranspose<uint32_t, Scalar>(ptr_, mat); break;
case mxINT64_CLASS: deepCopyAndTranspose<int64_t, Scalar>(ptr_, mat); break;
case mxUINT64_CLASS: deepCopyAndTranspose<uint64_t, Scalar>(ptr_, mat); break;
case mxSINGLE_CLASS: deepCopyAndTranspose<float, Scalar>(ptr_, mat); break;
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");
}
return mat;
}
// --------------------------------------------------------------------------
......@@ -213,11 +264,6 @@ public:
// CORE OPENCV TYPES
// --------------------------------------------------------------------------
// --------------------------- cv::Mat --------------------------------------
Bridge& operator=(const cv::Mat& mat) { ptr_ = MxArray::FromMat<Matlab::InheritType>(mat); return *this; }
cv::Mat toMat() const { return ptr_.toMat<Matlab::InheritType>(); }
operator cv::Mat() const { return toMat(); }
// -------------------------- Point --------------------------------------
Bridge& operator=(const cv::Point& ) { return *this; }
cv::Point toPoint() const { return cv::Point(); }
......@@ -351,4 +397,106 @@ public:
};
/*!
* @brief template specialization for inheriting types
*
* This template specialization attempts to preserve the best mapping
* between OpenCV and Matlab types. Matlab uses double types almost universally, so
* all floating float types are converted to doubles.
* Unfortunately OpenCV does not have a native logical type, so
* that gets mapped to an unsigned 8-bit value
*/
template <>
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);
case CV_16U: return FromMat<uint16_t>(mat);
case CV_16S: return FromMat<int16_t>(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");
}
return MxArray();
}
/*!
* @brief template specialization for inheriting types
*
* This template specialization attempts to preserve the best mapping
* between Matlab and OpenCV types. OpenCV has poor support for double precision
* types, so all floating point types are cast to float. Logicals get cast
* to unsignd 8-bit value.
*/
template <>
cv::Mat Bridge::toMat<Matlab::InheritType>() const {
switch (ptr_.ID()) {
case mxINT8_CLASS: return toMat<int8_t>();
case mxUINT8_CLASS: return toMat<uint8_t>();
case mxINT16_CLASS: return toMat<int16_t>();
case mxUINT16_CLASS: return toMat<uint16_t>();
case mxINT32_CLASS: return toMat<int32_t>();
case mxUINT32_CLASS: return toMat<int32_t>();
case mxINT64_CLASS: return toMat<int64_t>();
case mxUINT64_CLASS: return toMat<int64_t>();
case mxSINGLE_CLASS: return toMat<float>();
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");
}
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>(); }
// ----------------------------------------------------------------------------
// MATRIX TRANSPOSE
// ----------------------------------------------------------------------------
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");
std::vector<cv::Mat> channels;
cv::split(in, channels);
for (size_t c = 0; c < out.channels(); ++c) {
cv::transpose(channels[c], channels[c]);
cv::Mat outmat(out.cols(), out.rows(), cv::DataType<OutputScalar>::type,
static_cast<void *>(out.real<OutputScalar>() + out.cols()*out.rows()*c));
channels[c].convertTo(outmat, cv::DataType<OutputScalar>::type);
}
//const InputScalar* inp = in.ptr<InputScalar>(0);
//OutputScalar* outp = out.real<OutputScalar>();
//gemt('R', out.rows(), out.cols(), inp, in.step1(), outp, out.rows());
}
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");
std::vector<cv::Mat> channels;
for (size_t c = 0; c < in.channels(); ++c) {
cv::Mat outmat;
cv::Mat inmat(in.cols(), in.rows(), cv::DataType<InputScalar>::type,
static_cast<void *>(const_cast<InputScalar *>(in.real<InputScalar>() + in.cols()*in.rows()*c)));
inmat.convertTo(outmat, cv::DataType<OutputScalar>::type);
cv::transpose(outmat, outmat);
channels.push_back(outmat);
}
cv::merge(channels, out);
//const InputScalar* inp = in.real<InputScalar>();
//OutputScalar* outp = out.ptr<OutputScalar>(0);
//gemt('C', in.rows(), in.cols(), inp, in.rows(), outp, out.step1());
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment