Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                          License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
     15 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
     16 // Third party copyrights are property of their respective owners.
     17 //
     18 // Redistribution and use in source and binary forms, with or without modification,
     19 // are permitted provided that the following conditions are met:
     20 //
     21 //   * Redistribution's of source code must retain the above copyright notice,
     22 //     this list of conditions and the following disclaimer.
     23 //
     24 //   * Redistribution's in binary form must reproduce the above copyright notice,
     25 //     this list of conditions and the following disclaimer in the documentation
     26 //     and/or other materials provided with the distribution.
     27 //
     28 //   * The name of the copyright holders may not be used to endorse or promote products
     29 //     derived from this software without specific prior written permission.
     30 //
     31 // This software is provided by the copyright holders and contributors "as is" and
     32 // any express or implied warranties, including, but not limited to, the implied
     33 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     34 // In no event shall the Intel Corporation or contributors be liable for any direct,
     35 // indirect, incidental, special, exemplary, or consequential damages
     36 // (including, but not limited to, procurement of substitute goods or services;
     37 // loss of use, data, or profits; or business interruption) however caused
     38 // and on any theory of liability, whether in contract, strict liability,
     39 // or tort (including negligence or otherwise) arising in any way out of
     40 // the use of this software, even if advised of the possibility of such damage.
     41 //
     42 //M*/
     43 
     44 #include "precomp.hpp"
     45 
     46 namespace cv
     47 {
     48     class FormattedImpl : public Formatted
     49     {
     50         enum { STATE_PROLOGUE, STATE_EPILOGUE, STATE_INTERLUDE,
     51                STATE_ROW_OPEN, STATE_ROW_CLOSE, STATE_CN_OPEN, STATE_CN_CLOSE, STATE_VALUE, STATE_FINISHED,
     52                STATE_LINE_SEPARATOR, STATE_CN_SEPARATOR, STATE_VALUE_SEPARATOR };
     53         enum {BRACE_ROW_OPEN = 0, BRACE_ROW_CLOSE = 1, BRACE_ROW_SEP=2, BRACE_CN_OPEN=3, BRACE_CN_CLOSE=4 };
     54 
     55         char floatFormat[8];
     56         char buf[32];   // enough for double with precision up to 20
     57 
     58         Mat mtx;
     59         int mcn; // == mtx.channels()
     60         bool singleLine;
     61         bool alignOrder;    // true when cn first order
     62 
     63         int state;
     64         int row;
     65         int col;
     66         int cn;
     67 
     68         String prologue;
     69         String epilogue;
     70         char braces[5];
     71 
     72         void (FormattedImpl::*valueToStr)();
     73         void valueToStr8u()  { sprintf(buf, "%3d", (int)mtx.ptr<uchar>(row, col)[cn]); }
     74         void valueToStr8s()  { sprintf(buf, "%3d", (int)mtx.ptr<schar>(row, col)[cn]); }
     75         void valueToStr16u() { sprintf(buf, "%d", (int)mtx.ptr<ushort>(row, col)[cn]); }
     76         void valueToStr16s() { sprintf(buf, "%d", (int)mtx.ptr<short>(row, col)[cn]); }
     77         void valueToStr32s() { sprintf(buf, "%d", mtx.ptr<int>(row, col)[cn]); }
     78         void valueToStr32f() { sprintf(buf, floatFormat, mtx.ptr<float>(row, col)[cn]); }
     79         void valueToStr64f() { sprintf(buf, floatFormat, mtx.ptr<double>(row, col)[cn]); }
     80         void valueToStrOther() { buf[0] = 0; }
     81 
     82     public:
     83 
     84         FormattedImpl(String pl, String el, Mat m, char br[5], bool sLine, bool aOrder, int precision)
     85         {
     86             CV_Assert(m.dims <= 2);
     87 
     88             prologue = pl;
     89             epilogue = el;
     90             mtx = m;
     91             mcn = m.channels();
     92             memcpy(braces, br, 5);
     93             state = STATE_PROLOGUE;
     94             singleLine = sLine;
     95             alignOrder = aOrder;
     96             row = col = cn =0;
     97 
     98             if (precision < 0)
     99             {
    100                 floatFormat[0] = '%';
    101                 floatFormat[1] = 'a';
    102                 floatFormat[2] = 0;
    103             }
    104             else
    105             {
    106                 sprintf(floatFormat, "%%.%dg", std::min(precision, 20));
    107             }
    108 
    109             switch(mtx.depth())
    110             {
    111                 case CV_8U:  valueToStr = &FormattedImpl::valueToStr8u; break;
    112                 case CV_8S:  valueToStr = &FormattedImpl::valueToStr8s; break;
    113                 case CV_16U: valueToStr = &FormattedImpl::valueToStr16u; break;
    114                 case CV_16S: valueToStr = &FormattedImpl::valueToStr16s; break;
    115                 case CV_32S: valueToStr = &FormattedImpl::valueToStr32s; break;
    116                 case CV_32F: valueToStr = &FormattedImpl::valueToStr32f; break;
    117                 case CV_64F: valueToStr = &FormattedImpl::valueToStr64f; break;
    118                 default:     valueToStr = &FormattedImpl::valueToStrOther; break;
    119             }
    120         }
    121 
    122         void reset()
    123         {
    124             state = STATE_PROLOGUE;
    125         }
    126 
    127         const char* next()
    128         {
    129             switch(state)
    130             {
    131                 case STATE_PROLOGUE:
    132                     row = 0;
    133                     if (mtx.empty())
    134                         state = STATE_EPILOGUE;
    135                     else if (alignOrder)
    136                         state = STATE_INTERLUDE;
    137                     else
    138                         state = STATE_ROW_OPEN;
    139                     return prologue.c_str();
    140                 case STATE_INTERLUDE:
    141                     state = STATE_ROW_OPEN;
    142                     if (row >= mtx.rows)
    143                     {
    144                         if (++cn >= mcn)
    145                         {
    146                             state = STATE_EPILOGUE;
    147                             buf[0] = 0;
    148                             return buf;
    149                         }
    150                         else
    151                             row = 0;
    152                         sprintf(buf, "\n(:, :, %d) = \n", cn+1);
    153                         return buf;
    154                     }
    155                     sprintf(buf, "(:, :, %d) = \n", cn+1);
    156                     return buf;
    157                 case STATE_EPILOGUE:
    158                     state = STATE_FINISHED;
    159                     return epilogue.c_str();
    160                 case STATE_ROW_OPEN:
    161                     col = 0;
    162                     state = STATE_CN_OPEN;
    163                     {
    164                         size_t pos = 0;
    165                         if (row > 0)
    166                             while(pos < prologue.size() && pos < sizeof(buf) - 2)
    167                                 buf[pos++] = ' ';
    168                         if (braces[BRACE_ROW_OPEN])
    169                             buf[pos++] = braces[BRACE_ROW_OPEN];
    170                         if(!pos)
    171                             return next();
    172                         buf[pos] = 0;
    173                     }
    174                     return buf;
    175                 case STATE_ROW_CLOSE:
    176                     state = STATE_LINE_SEPARATOR;
    177                     ++row;
    178                     if (braces[BRACE_ROW_CLOSE])
    179                     {
    180                         buf[0] = braces[BRACE_ROW_CLOSE];
    181                         buf[1] = row < mtx.rows ? ',' : '\0';
    182                         buf[2] = 0;
    183                         return buf;
    184                     }
    185                     else if(braces[BRACE_ROW_SEP] && row < mtx.rows)
    186                     {
    187                         buf[0] = braces[BRACE_ROW_SEP];
    188                         buf[1] = 0;
    189                         return buf;
    190                     }
    191                     return next();
    192                 case STATE_CN_OPEN:
    193                     state = STATE_VALUE;
    194                     if (!alignOrder)
    195                         cn = 0;
    196                     if (mcn > 1 && braces[BRACE_CN_OPEN])
    197                     {
    198                         buf[0] = braces[BRACE_CN_OPEN];
    199                         buf[1] = 0;
    200                         return buf;
    201                     }
    202                     return next();
    203                 case STATE_CN_CLOSE:
    204                     ++col;
    205                     if (col >= mtx.cols)
    206                         state = STATE_ROW_CLOSE;
    207                     else
    208                         state = STATE_CN_SEPARATOR;
    209                     if (mcn > 1 && braces[BRACE_CN_CLOSE])
    210                     {
    211                         buf[0] = braces[BRACE_CN_CLOSE];
    212                         buf[1] = 0;
    213                         return buf;
    214                     }
    215                     return next();
    216                 case STATE_VALUE:
    217                     (this->*valueToStr)();
    218                     state = STATE_CN_CLOSE;
    219                     if (alignOrder)
    220                         return buf;
    221                     if (++cn < mcn)
    222                         state = STATE_VALUE_SEPARATOR;
    223                     return buf;
    224                 case STATE_FINISHED:
    225                     return 0;
    226                 case STATE_LINE_SEPARATOR:
    227                     if (row >= mtx.rows)
    228                     {
    229                         if (alignOrder)
    230                             state = STATE_INTERLUDE;
    231                         else
    232                             state = STATE_EPILOGUE;
    233                         return next();
    234                     }
    235                     state = STATE_ROW_OPEN;
    236                     buf[0] = singleLine ? ' ' : '\n';
    237                     buf[1] = 0;
    238                     return buf;
    239                 case STATE_CN_SEPARATOR:
    240                     state = STATE_CN_OPEN;
    241                     buf[0] = ',';
    242                     buf[1] = ' ';
    243                     buf[2] = 0;
    244                     return buf;
    245                 case STATE_VALUE_SEPARATOR:
    246                     state = STATE_VALUE;
    247                     buf[0] = ',';
    248                     buf[1] = ' ';
    249                     buf[2] = 0;
    250                     return buf;
    251             }
    252             return 0;
    253         }
    254     };
    255 
    256     class FormatterBase : public Formatter
    257     {
    258     public:
    259         FormatterBase() : prec32f(8), prec64f(16), multiline(true) {}
    260 
    261         void set32fPrecision(int p)
    262         {
    263             prec32f = p;
    264         }
    265 
    266         void set64fPrecision(int p)
    267         {
    268             prec64f = p;
    269         }
    270 
    271         void setMultiline(bool ml)
    272         {
    273             multiline = ml;
    274         }
    275 
    276     protected:
    277         int prec32f;
    278         int prec64f;
    279         int multiline;
    280     };
    281 
    282     class DefaultFormatter : public FormatterBase
    283     {
    284     public:
    285 
    286         Ptr<Formatted> format(const Mat& mtx) const
    287         {
    288             char braces[5] = {'\0', '\0', ';', '\0', '\0'};
    289             return makePtr<FormattedImpl>("[", "]", mtx, &*braces,
    290                 mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
    291         }
    292     };
    293 
    294     class MatlabFormatter : public FormatterBase
    295     {
    296     public:
    297 
    298         Ptr<Formatted> format(const Mat& mtx) const
    299         {
    300             char braces[5] = {'\0', '\0', ';', '\0', '\0'};
    301             return makePtr<FormattedImpl>("", "", mtx, &*braces,
    302                 mtx.rows == 1 || !multiline, true, mtx.depth() == CV_64F ? prec64f : prec32f );
    303         }
    304     };
    305 
    306     class PythonFormatter : public FormatterBase
    307     {
    308     public:
    309 
    310         Ptr<Formatted> format(const Mat& mtx) const
    311         {
    312             char braces[5] = {'[', ']', ',', '[', ']'};
    313             if (mtx.cols == 1)
    314                 braces[0] = braces[1] = '\0';
    315             return makePtr<FormattedImpl>("[", "]", mtx, &*braces,
    316                 mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
    317         }
    318     };
    319 
    320     class NumpyFormatter : public FormatterBase
    321     {
    322     public:
    323 
    324         Ptr<Formatted> format(const Mat& mtx) const
    325         {
    326             static const char* numpyTypes[] =
    327             {
    328                 "uint8", "int8", "uint16", "int16", "int32", "float32", "float64", "uint64"
    329             };
    330             char braces[5] = {'[', ']', ',', '[', ']'};
    331             if (mtx.cols == 1)
    332                 braces[0] = braces[1] = '\0';
    333             return makePtr<FormattedImpl>("array([",
    334                 cv::format("], dtype='%s')", numpyTypes[mtx.depth()]), mtx, &*braces,
    335                 mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
    336         }
    337     };
    338 
    339     class CSVFormatter : public FormatterBase
    340     {
    341     public:
    342 
    343         Ptr<Formatted> format(const Mat& mtx) const
    344         {
    345             char braces[5] = {'\0', '\0', '\0', '\0', '\0'};
    346             return makePtr<FormattedImpl>(String(),
    347                 mtx.rows > 1 ? String("\n") : String(), mtx, &*braces,
    348                 mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
    349         }
    350     };
    351 
    352     class CFormatter : public FormatterBase
    353     {
    354     public:
    355 
    356         Ptr<Formatted> format(const Mat& mtx) const
    357         {
    358             char braces[5] = {'\0', '\0', ',', '\0', '\0'};
    359             return makePtr<FormattedImpl>("{", "}", mtx, &*braces,
    360                 mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f );
    361         }
    362     };
    363 
    364     Formatted::~Formatted() {}
    365     Formatter::~Formatter() {}
    366 
    367     Ptr<Formatter> Formatter::get(int fmt)
    368     {
    369         switch(fmt)
    370         {
    371             case FMT_DEFAULT:
    372                 return makePtr<DefaultFormatter>();
    373             case FMT_MATLAB:
    374                 return makePtr<MatlabFormatter>();
    375             case FMT_CSV:
    376                 return makePtr<CSVFormatter>();
    377             case FMT_PYTHON:
    378                 return makePtr<PythonFormatter>();
    379             case FMT_NUMPY:
    380                 return makePtr<NumpyFormatter>();
    381             case FMT_C:
    382                 return makePtr<CFormatter>();
    383         }
    384         return makePtr<DefaultFormatter>();
    385     }
    386 } // cv
    387