Fix for (Bug #2789)

Add MatlabFormatter for matlab style output.
See http://code.opencv.org/issues/2789
pull/2626/head
KayKwon 11 years ago
parent f104d5be8c
commit 84257b57d0
  1. 12
      modules/core/include/opencv2/core.hpp
  2. 67
      modules/core/src/out.cpp
  3. 5
      samples/cpp/cout_mat.cpp

@ -953,12 +953,12 @@ public:
class CV_EXPORTS Formatter
{
public:
enum { FMT_MATLAB = 0,
FMT_CSV = 1,
FMT_PYTHON = 2,
FMT_NUMPY = 3,
FMT_C = 4,
FMT_DEFAULT = FMT_MATLAB
enum { FMT_DEFAULT = 0,
FMT_MATLAB = 1,
FMT_CSV = 2,
FMT_PYTHON = 3,
FMT_NUMPY = 4,
FMT_C = 5
};
virtual ~Formatter();

@ -47,7 +47,8 @@ namespace
{
class FormattedImpl : public cv::Formatted
{
enum { STATE_PROLOGUE, STATE_EPILOGUE, STATE_ROW_OPEN, STATE_ROW_CLOSE, STATE_CN_OPEN, STATE_CN_CLOSE, STATE_VALUE, STATE_FINISHED,
enum { STATE_PROLOGUE, STATE_EPILOGUE, STATE_INTERLUDE,
STATE_ROW_OPEN, STATE_ROW_CLOSE, STATE_CN_OPEN, STATE_CN_CLOSE, STATE_VALUE, STATE_FINISHED,
STATE_LINE_SEPARATOR, STATE_CN_SEPARATOR, STATE_VALUE_SEPARATOR };
enum {BRACE_ROW_OPEN = 0, BRACE_ROW_CLOSE = 1, BRACE_ROW_SEP=2, BRACE_CN_OPEN=3, BRACE_CN_CLOSE=4 };
@ -57,6 +58,7 @@ namespace
cv::Mat mtx;
int mcn; // == mtx.channels()
bool singleLine;
bool alignOrder; // true when cn first order
int state;
int row;
@ -79,8 +81,10 @@ namespace
public:
FormattedImpl(cv::String pl, cv::String el, cv::Mat m, char br[5], bool sLine, int precision)
FormattedImpl(cv::String pl, cv::String el, cv::Mat m, char br[5], bool sLine, bool aOrder, int precision)
{
CV_Assert(m.dims <= 2);
prologue = pl;
epilogue = el;
mtx = m;
@ -88,6 +92,8 @@ namespace
memcpy(braces, br, 5);
state = STATE_PROLOGUE;
singleLine = sLine;
alignOrder = aOrder;
row = col = cn =0;
if (precision < 0)
{
@ -126,9 +132,28 @@ namespace
row = 0;
if (mtx.empty())
state = STATE_EPILOGUE;
else if (alignOrder)
state = STATE_INTERLUDE;
else
state = STATE_ROW_OPEN;
return prologue.c_str();
case STATE_INTERLUDE:
state = STATE_ROW_OPEN;
if (row >= mtx.rows)
{
if (++cn >= mcn)
{
state = STATE_EPILOGUE;
buf[0] = 0;
return buf;
}
else
row = 0;
sprintf(buf, "\n(:, :, %d) = \n", cn+1);
return buf;
}
sprintf(buf, "(:, :, %d) = \n", cn+1);
return buf;
case STATE_EPILOGUE:
state = STATE_FINISHED;
return epilogue.c_str();
@ -165,8 +190,9 @@ namespace
}
return next();
case STATE_CN_OPEN:
cn = 0;
state = STATE_VALUE;
if (!alignOrder)
cn = 0;
if (mcn > 1 && braces[BRACE_CN_OPEN])
{
buf[0] = braces[BRACE_CN_OPEN];
@ -189,9 +215,10 @@ namespace
return next();
case STATE_VALUE:
(this->*valueToStr)();
if (++cn >= mcn)
state = STATE_CN_CLOSE;
else
if (alignOrder)
return buf;
if (++cn < mcn)
state = STATE_VALUE_SEPARATOR;
return buf;
case STATE_FINISHED:
@ -199,6 +226,9 @@ namespace
case STATE_LINE_SEPARATOR:
if (row >= mtx.rows)
{
if (alignOrder)
state = STATE_INTERLUDE;
else
state = STATE_EPILOGUE;
return next();
}
@ -248,6 +278,17 @@ namespace
int prec64f;
int multiline;
};
class DefaultFormatter : public FormatterBase
{
public:
cv::Ptr<cv::Formatted> format(const cv::Mat& mtx) const
{
char braces[5] = {'\0', '\0', ';', '\0', '\0'};
return cv::makePtr<FormattedImpl>("[", "]", mtx, &*braces,
mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
}
};
class MatlabFormatter : public FormatterBase
{
@ -256,8 +297,8 @@ namespace
cv::Ptr<cv::Formatted> format(const cv::Mat& mtx) const
{
char braces[5] = {'\0', '\0', ';', '\0', '\0'};
return cv::makePtr<FormattedImpl>("[", "]", mtx, &*braces,
mtx.rows == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
return cv::makePtr<FormattedImpl>("", "", mtx, &*braces,
mtx.rows == 1 || !multiline, true, mtx.depth() == CV_64F ? prec64f : prec32f );
}
};
@ -271,7 +312,7 @@ namespace
if (mtx.cols == 1)
braces[0] = braces[1] = '\0';
return cv::makePtr<FormattedImpl>("[", "]", mtx, &*braces,
mtx.rows*mtx.channels() == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
}
};
@ -290,7 +331,7 @@ namespace
braces[0] = braces[1] = '\0';
return cv::makePtr<FormattedImpl>("array([",
cv::format("], type='%s')", numpyTypes[mtx.depth()]), mtx, &*braces,
mtx.rows*mtx.channels() == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
}
};
@ -303,7 +344,7 @@ namespace
char braces[5] = {'\0', '\0', '\0', '\0', '\0'};
return cv::makePtr<FormattedImpl>(cv::String(),
mtx.rows > 1 ? cv::String("\n") : cv::String(), mtx, &*braces,
mtx.rows*mtx.channels() == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
}
};
@ -315,7 +356,7 @@ namespace
{
char braces[5] = {'\0', '\0', ',', '\0', '\0'};
return cv::makePtr<FormattedImpl>("{", "}", mtx, &*braces,
mtx.rows == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
}
};
@ -331,6 +372,8 @@ namespace cv
{
switch(fmt)
{
case FMT_DEFAULT:
return makePtr<DefaultFormatter>();
case FMT_MATLAB:
return makePtr<MatlabFormatter>();
case FMT_CSV:
@ -342,6 +385,6 @@ namespace cv
case FMT_C:
return makePtr<CFormatter>();
}
return makePtr<MatlabFormatter>();
return makePtr<DefaultFormatter>();
}
} // cv

@ -17,8 +17,8 @@ static void help()
<< "\n------------------------------------------------------------------\n"
<< " This program shows the serial out capabilities of cv::Mat\n"
<< "That is, cv::Mat M(...); cout << M; Now works.\n"
<< "Output can be formated to OpenCV, python, numpy, csv and C styles"
<< "Usage:\n"
<< "Output can be formated to OpenCV, matlab, python, numpy, csv and \n"
<< "C styles Usage:\n"
<< "./cvout_sample\n"
<< "------------------------------------------------------------------\n\n"
<< endl;
@ -36,6 +36,7 @@ int main(int,char**)
randu(r, Scalar::all(0), Scalar::all(255));
cout << "r (default) = \n" << r << ";" << endl << endl;
cout << "r (matlab) = \n" << format(r, Formatter::FMT_MATLAB) << ";" << endl << endl;
cout << "r (python) = \n" << format(r, Formatter::FMT_PYTHON) << ";" << endl << endl;
cout << "r (numpy) = \n" << format(r, Formatter::FMT_NUMPY) << ";" << endl << endl;
cout << "r (csv) = \n" << format(r, Formatter::FMT_CSV) << ";" << endl << endl;

Loading…
Cancel
Save