Skip to content

Commit 45f9d57

Browse files
committed
matlab: fix conversion functions
1 parent a1815ca commit 45f9d57

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

modules/matlab/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
set(BUILD_opencv_matlab_INIT OFF) # Matlab module is broken
2-
31
# ----------------------------------------------------------------------------
42
# CMake file for Matlab/Octave support
53
#

modules/matlab/include/opencv2/matlab/bridge.hpp

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,13 @@ class Bridge {
249249
case mxUINT16_CLASS: deepCopyAndTranspose<uint16_t, Scalar>(ptr_, mat); break;
250250
case mxINT32_CLASS: deepCopyAndTranspose<int32_t, Scalar>(ptr_, mat); break;
251251
case mxUINT32_CLASS: deepCopyAndTranspose<uint32_t, Scalar>(ptr_, mat); break;
252-
case mxINT64_CLASS: deepCopyAndTranspose<int64_t, Scalar>(ptr_, mat); break;
253-
case mxUINT64_CLASS: deepCopyAndTranspose<uint64_t, Scalar>(ptr_, mat); break;
252+
//case mxINT64_CLASS: deepCopyAndTranspose<int64_t, Scalar>(ptr_, mat); break;
253+
//case mxUINT64_CLASS: deepCopyAndTranspose<uint64_t, Scalar>(ptr_, mat); break;
254254
case mxSINGLE_CLASS: deepCopyAndTranspose<float, Scalar>(ptr_, mat); break;
255255
case mxDOUBLE_CLASS: deepCopyAndTranspose<double, Scalar>(ptr_, mat); break;
256256
case mxCHAR_CLASS: deepCopyAndTranspose<char, Scalar>(ptr_, mat); break;
257257
case mxLOGICAL_CLASS: deepCopyAndTranspose<int8_t, Scalar>(ptr_, mat); break;
258-
default: matlab::error("Attempted to convert from unknown class");
258+
default: matlab::error("Attempted to convert from unknown/unsupported class");
259259
}
260260
return mat;
261261
}
@@ -576,13 +576,13 @@ cv::Mat Bridge::toMat<matlab::InheritType>() const {
576576
case mxUINT16_CLASS: return toMat<uint16_t>();
577577
case mxINT32_CLASS: return toMat<int32_t>();
578578
case mxUINT32_CLASS: return toMat<int32_t>();
579-
case mxINT64_CLASS: return toMat<int64_t>();
580-
case mxUINT64_CLASS: return toMat<int64_t>();
579+
//case mxINT64_CLASS: return toMat<int64_t>();
580+
//case mxUINT64_CLASS: return toMat<int64_t>();
581581
case mxSINGLE_CLASS: return toMat<float>();
582582
case mxDOUBLE_CLASS: return toMat<float>(); //NOTE: OpenCV uses float as native type!
583583
case mxCHAR_CLASS: return toMat<int8_t>();
584584
case mxLOGICAL_CLASS: return toMat<int8_t>();
585-
default: matlab::error("Attempted to convert from unknown class");
585+
default: matlab::error("Attempted to convert from unknown/unsuported class");
586586
}
587587
return cv::Mat();
588588
}
@@ -598,36 +598,52 @@ cv::Mat Bridge::toMat() const { return toMat<matlab::InheritType>(); }
598598

599599
template <typename InputScalar, typename OutputScalar>
600600
void deepCopyAndTranspose(const cv::Mat& in, matlab::MxArray& out) {
601+
const int cols = out.cols();
602+
const int rows = out.rows();
601603
matlab::conditionalError(static_cast<size_t>(in.rows) == out.rows(), "Matrices must have the same number of rows");
602604
matlab::conditionalError(static_cast<size_t>(in.cols) == out.cols(), "Matrices must have the same number of cols");
603605
matlab::conditionalError(static_cast<size_t>(in.channels()) == out.channels(), "Matrices must have the same number of channels");
604606
std::vector<cv::Mat> channels;
605607
cv::split(in, channels);
606608
for (size_t c = 0; c < out.channels(); ++c) {
607-
cv::transpose(channels[c], channels[c]);
608-
cv::Mat outmat(out.cols(), out.rows(), cv::DataType<OutputScalar>::type,
609-
static_cast<void *>(out.real<OutputScalar>() + out.cols()*out.rows()*c));
610-
channels[c].convertTo(outmat, cv::DataType<OutputScalar>::type);
609+
cv::Mat_<InputScalar> m;
610+
cv::transpose(channels[c], m);
611+
OutputScalar* dst_plane = (OutputScalar*)out.real<InputScalar>() + cols*rows*c;
612+
for (int x = 0; x < cols; x++)
613+
{
614+
OutputScalar* dst_col = dst_plane + x * rows;
615+
for (int y = 0; y < rows; y++)
616+
{
617+
dst_col[y] = cv::saturate_cast<OutputScalar>(m(y, x));
618+
}
619+
}
611620
}
612-
613621
//const InputScalar* inp = in.ptr<InputScalar>(0);
614622
//OutputScalar* outp = out.real<OutputScalar>();
615623
//gemt('R', out.rows(), out.cols(), inp, in.step1(), outp, out.rows());
616624
}
617625

618626
template <typename InputScalar, typename OutputScalar>
619627
void deepCopyAndTranspose(const matlab::MxArray& in, cv::Mat& out) {
628+
const int cols = in.cols();
629+
const int rows = in.rows();
620630
matlab::conditionalError(in.rows() == static_cast<size_t>(out.rows), "Matrices must have the same number of rows");
621631
matlab::conditionalError(in.cols() == static_cast<size_t>(out.cols), "Matrices must have the same number of cols");
622632
matlab::conditionalError(in.channels() == static_cast<size_t>(out.channels()), "Matrices must have the same number of channels");
623633
std::vector<cv::Mat> channels;
624634
for (size_t c = 0; c < in.channels(); ++c) {
625-
cv::Mat outmat;
626-
cv::Mat inmat(in.cols(), in.rows(), cv::DataType<InputScalar>::type,
627-
static_cast<void *>(const_cast<InputScalar *>(in.real<InputScalar>() + in.cols()*in.rows()*c)));
628-
inmat.convertTo(outmat, cv::DataType<OutputScalar>::type);
629-
cv::transpose(outmat, outmat);
630-
channels.push_back(outmat);
635+
cv::Mat_<OutputScalar> m(cols, rows);
636+
const InputScalar* src_plane = in.real<InputScalar>() + cols*rows*c;
637+
for (int x = 0; x < cols; x++)
638+
{
639+
const InputScalar* src_col = src_plane + x * rows;
640+
for (int y = 0; y < rows; y++)
641+
{
642+
m(y, x) = cv::saturate_cast<InputScalar>(src_col[y]);
643+
}
644+
}
645+
cv::transpose(m, m);
646+
channels.push_back(m);
631647
}
632648
cv::merge(channels, out);
633649

0 commit comments

Comments
 (0)