// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #ifndef __OPENCV_FACE_UTILS_HPP #define __OPENCV_FACE_UTILS_HPP #include "precomp.hpp" using namespace cv; inline Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0) { // make sure the input data is a vector of matrices or vector of vector if(src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR) { String error_message = "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector) or _InputArray::STD_VECTOR_VECTOR (a std::vector< std::vector<...> >)."; CV_Error(Error::StsBadArg, error_message); } // number of samples size_t n = src.total(); // return empty matrix if no matrices given if(n == 0) return Mat(); // dimensionality of (reshaped) samples size_t d = src.getMat(0).total(); // create data matrix Mat data((int)n, (int)d, rtype); // now copy data for(unsigned int i = 0; i < n; i++) { // make sure data can be reshaped, throw exception if not! if(src.getMat(i).total() != d) { String error_message = format("Wrong number of elements in matrix #%u! Expected %zu was %zu.", i, d, src.getMat(i).total()); CV_Error(Error::StsBadArg, error_message); } // get a hold of the current row Mat xi = data.row(i); // make reshape happy by cloning for non-continuous matrices if(src.getMat(i).isContinuous()) { src.getMat(i).reshape(1, 1).convertTo(xi, rtype, alpha, beta); } else { src.getMat(i).clone().reshape(1, 1).convertTo(xi, rtype, alpha, beta); } } return data; } // Reads a sequence from a FileNode::SEQ with type _Tp into a result vector. template inline void readFileNodeList(const FileNode& fn, std::vector<_Tp>& result) { if (fn.type() == FileNode::SEQ) { for (FileNodeIterator it = fn.begin(); it != fn.end();) { _Tp item; it >> item; result.push_back(item); } } } // Writes the a list of given items to a cv::FileStorage. template inline void writeFileNodeList(FileStorage& fs, const String& name, const std::vector<_Tp>& items) { // typedefs typedef typename std::vector<_Tp>::const_iterator constVecIterator; // write the elements in item to fs fs << name << "["; for (constVecIterator it = items.begin(); it != items.end(); ++it) { fs << *it; } fs << "]"; } // Utility structure to load/save face label info (a pair of int and string) via FileStorage struct LabelInfo { LabelInfo():label(-1), value("") {} LabelInfo(int _label, const String &_value): label(_label), value(_value) {} int label; String value; void write(cv::FileStorage& fs) const { fs << "{" << "label" << label << "value" << value << "}"; } void read(const cv::FileNode& node) { label = (int)node["label"]; value = (String)node["value"]; } std::ostream& operator<<(std::ostream& out) { out << "{ label = " << label << ", " << "value = " << value.c_str() << "}"; return out; } }; inline void write(cv::FileStorage& fs, const String&, const LabelInfo& x) { x.write(fs); } inline void read(const cv::FileNode& node, LabelInfo& x, const LabelInfo& default_value = LabelInfo()) { if(node.empty()) x = default_value; else x.read(node); } #endif