void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels, bool preserveData) { if(_in_src.kind() != _InputArray::STD_VECTOR_MAT && _in_src.kind() != _InputArray::STD_VECTOR_VECTOR) { String error_message = "The images are expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< std::vector<...> >)."; CV_Error(Error::StsBadArg, error_message); } if(_in_src.total() == 0) { String error_message = format("Empty training data was given. You'll need more than one sample to learn a model."); CV_Error(Error::StsUnsupportedFormat, error_message); } else if(_in_labels.getMat().type() != CV_32SC1) { String error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _in_labels.type()); CV_Error(Error::StsUnsupportedFormat, error_message); } // get the vector of matrices std::vector<Mat> src; _in_src.getMatVector(src); // get the label matrix Mat labels = _in_labels.getMat(); // check if data is well- aligned if(labels.total() != src.size()) { String error_message = format("The number of samples (src) must equal the number of labels (labels). Was len(samples)=%d, len(labels)=%d.", src.size(), _labels.total()); CV_Error(Error::StsBadArg, error_message); } // if this model should be trained without preserving old data, delete old model data if(!preserveData) { _labels.release(); _histograms.clear(); } // append labels to _labels matrix for(size_t labelIdx = 0; labelIdx < labels.total(); labelIdx++) { _labels.push_back(labels.at<int>((int)labelIdx)); } // store the spatial histograms of the original data for(size_t sampleIdx = 0; sampleIdx < src.size(); sampleIdx++) { // calculate lbp image Mat lbp_image = elbp(src[sampleIdx], _radius, _neighbors); // get spatial histogram from this lbp image Mat p = spatial_histogram( lbp_image, /* lbp_image */ static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */ _grid_x, /* grid size x */ _grid_y, /* grid size y */ true); // add to templates _histograms.push_back(p); } }
void LBPH::predict(InputArray _src, Ptr<PredictCollector> collector) const { if(_histograms.empty()) { // throw error if no data (or simply return -1?) String error_message = "This LBPH model is not computed yet. Did you call the train method?"; CV_Error(Error::StsBadArg, error_message); } Mat src = _src.getMat(); // get the spatial histogram from input image Mat lbp_image = elbp(src, _radius, _neighbors); Mat query = spatial_histogram( lbp_image, /* lbp_image */ static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */ _grid_x, /* grid size x */ _grid_y, /* grid size y */ true /* normed histograms */); // find 1-nearest neighbor collector->init((int)_histograms.size()); for (size_t sampleIdx = 0; sampleIdx < _histograms.size(); sampleIdx++) { double dist = compareHist(_histograms[sampleIdx], query, HISTCMP_CHISQR_ALT); int label = _labels.at<int>((int)sampleIdx); if (!collector->collect(label, dist))return; } }
Mat lbp::spatial_histogram(const Mat& src, int numPatterns, int gridx, int gridy, int overlap) { Mat hist; spatial_histogram(src, hist, numPatterns, gridx, gridy); return hist; }
Mat lbp::spatial_histogram(const Mat& src, int numPatterns, const Size& window, int overlap) { Mat hist; spatial_histogram(src, hist, numPatterns, window, overlap); return hist; }
void lbp::spatial_histogram(const Mat& src, Mat& dst, int numPatterns, int gridx, int gridy, int overlap) { int width = static_cast<int>(floor((float)src.cols/gridx)); int height = static_cast<int>(floor((float)src.rows / gridy)); spatial_histogram(src, dst, numPatterns, Size_<int>(width, height), overlap); }
cv::Mat spatial_histogram(const cv::Mat& src, int numPatterns, const cv::Size& window, int overlap) { cv::Mat hist; spatial_histogram(src, hist, numPatterns, window, overlap); return hist; }
void spatial_histogram(const cv::Mat& src, cv::Mat& dst, int numPatterns, int gridx, int gridy, int overlap) { int width = static_cast<int>(floor((double)src.cols / gridx)); int height = static_cast<int>(floor((double)src.rows / gridy)); spatial_histogram(src, dst, numPatterns, cv::Size_<int>(width, height), overlap); }
void lbp::spatial_histogram(const Mat& src, Mat& dst, int numPatterns, int gridx, int gridy, int overlap) { //int width = src.cols/gridx; //int height =src.rows / gridy; spatial_histogram(src, dst, numPatterns, Size_<int>(gridx, gridy), overlap); }