32 #define N_PTS_TO_FIND   400    33 #define N_PTS_TO_TEACH  200    37 #define STRUCT_SIZE     11    38 #define SIGNATURE_SIZE  400    66     : FernClassifier(fileNode)
    71                                              const vector<Mat> &referenceImages,
    72                                              const vector<vector<int> > &labels,
    73                                              int _nclasses, 
int _patchSize,
    74                                              int _signatureSize, 
int _nstructs,
    75                                              int _structSize, 
int _nviews,
    76                                              int _compressionMethod,
    77                                              const PatchGenerator &patchGenerator)
    78     : FernClassifier(points, referenceImages, labels, _nclasses, _patchSize, _signatureSize,
    79                      _nstructs, _structSize, _nviews, _compressionMethod, patchGenerator)
    91     stream.read((
char *)&verbose, 
sizeof(verbose));
    92     stream.read((
char *)&nstructs, 
sizeof(nstructs));
    93     stream.read((
char *)&structSize, 
sizeof(structSize));
    94     stream.read((
char *)&nclasses, 
sizeof(nclasses));
    95     stream.read((
char *)&signatureSize, 
sizeof(signatureSize));
    96     stream.read((
char *)&compressionMethod, 
sizeof(compressionMethod));
    97     stream.read((
char *)&leavesPerStruct, 
sizeof(leavesPerStruct));
    98     stream.read((
char *)&patchSize.width, 
sizeof(patchSize.width));
    99     stream.read((
char *)&patchSize.height, 
sizeof(patchSize.height));
   101     std::vector<Feature>::size_type featuresSize;
   102     stream.read((
char *)&featuresSize, 
sizeof(featuresSize));
   103     features.reserve(featuresSize);
   104     unsigned int featuresValue;
   106     for (std::vector<Feature>::size_type i = 0; i < featuresSize; ++i) {
   107         stream.read((
char *)&featuresValue, 
sizeof(featuresValue));
   108         value.x1 = (uchar)(featuresValue % patchSize.width);
   109         value.y1 = (uchar)(featuresValue / patchSize.width);
   110         stream.read((
char *)&featuresValue, 
sizeof(featuresValue));
   111         value.x2 = (uchar)(featuresValue % patchSize.width);
   112         value.y2 = (uchar)(featuresValue / patchSize.width);
   113         features.push_back(value);
   128     std::vector<float>::size_type posteriorsSize;
   129     stream.read((
char *)&posteriorsSize, 
sizeof(posteriorsSize));
   130     posteriors.reserve(posteriorsSize);
   131     float posteriorsValue;
   132     for (std::vector<float>::size_type i = 0; i < posteriorsSize; ++i) {
   133         stream.read((
char *)&posteriorsValue, 
sizeof(posteriorsValue));
   134         posteriors.push_back(posteriorsValue);
   140     stream.write((
char *)&verbose, 
sizeof(verbose));
   141     stream.write((
char *)&nstructs, 
sizeof(nstructs));
   142     stream.write((
char *)&structSize, 
sizeof(structSize));
   143     stream.write((
char *)&nclasses, 
sizeof(nclasses));
   144     stream.write((
char *)&signatureSize, 
sizeof(signatureSize));
   145     stream.write((
char *)&compressionMethod, 
sizeof(compressionMethod));
   146     stream.write((
char *)&leavesPerStruct, 
sizeof(leavesPerStruct));
   147     stream.write((
char *)&patchSize.width, 
sizeof(patchSize.width));
   148     stream.write((
char *)&patchSize.height, 
sizeof(patchSize.height));
   150     std::vector<Feature>::size_type featuresSize = features.size();
   151     stream.write((
char *)&featuresSize, 
sizeof(featuresSize));
   152     unsigned int featuresValue;
   153     for (std::vector<Feature>::const_iterator itr = features.begin(); itr != features.end(); ++itr) {
   154         featuresValue = itr->y1 * patchSize.width + itr->x1;
   155         stream.write((
char *)&featuresValue, 
sizeof(featuresValue));
   156         featuresValue = itr->y2 * patchSize.width + itr->x2;
   157         stream.write((
char *)&featuresValue, 
sizeof(featuresValue));
   169     std::vector<float>::size_type posteriorsSize = posteriors.size();
   170     stream.write((
char *)&posteriorsSize, 
sizeof(posteriorsSize));
   171     for (std::vector<float>::const_iterator itr = posteriors.begin(); itr != posteriors.end(); ++itr) {
   172         stream.write((
char *)&*itr, 
sizeof(*itr));
   177     : mPatchGenerator(0, 256, 13, true, 0.10, 1.0, -CV_PI*1.0, CV_PI*1.0, -CV_PI*0.0, CV_PI*0.0) 
   183     , mVisualize(visualize)
   218                         pt.x -= 
mSize.width/2;
   219                         pt.y -= 
mSize.height/2;
   220                         pt.x /= 
mSize.width*0.10;
   221                         pt.y /= 
mSize.width*0.10;
   223                 points.push_back(pt);
   244         Mat 
object = imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
   256                 cvNamedWindow(
"Object", 1);
   257                 imshow(
"Object", blurredObject);
   266                 for(
int i = 0; i < (int)
mKeyPoints.size(); ++i)
   269                 imshow(
"Object", blurredObject);
   280                                                                         FernClassifier::COMPRESSION_NONE,
   283         mSize = cv::Size(
object.cols, 
object.rows);
   290         vector<KeyPoint> keypoints;
   299         int n = keypoints.size();
   300     vector<int> bestMatches(m, -1);
   301     vector<float> maxLogProb(m, -FLT_MAX);
   302     vector<float> signature;
   305         for(
size_t i = 0; i < keypoints.size(); ++i) {
   306                 Point2f pt = keypoints[i].pt;
   309                 if(k >= 0 && (bestMatches[k] < 0 || signature[k] > maxLogProb[k])) {
   310                         maxLogProb[k] = signature[k];
   315         for(
int i = 0; i < m; i++ )
   316                 if(bestMatches[i] >= 0) {
   318                         pairs.push_back(bestMatches[i]);
   326                 cvtColor(
object, part, CV_GRAY2BGR);
   328                 for(
int i = 0; i < (int)keypoints.size(); ++i)
   329                         circle(
object, keypoints[i].pt, 
int(keypoints[i].
size/5), CV_RGB(64,64,64));
   331                 vector<Point2f> fromPt, toPt;
   333                 for(
int i = 0; i < m; ++i)
   334                         if( bestMatches[i] >= 0 ){
   336                                 toPt.push_back(keypoints[bestMatches[i]].pt);
   339                         static double valmin = 1.0;
   340                         static double valmax = 0.0;
   345                         if(planeAssumption && fromPt.size() > 8) {
   346                                 cv::Mat H = cv::findHomography(Mat(fromPt), Mat(toPt), mask, RANSAC, 20);
   350                                 for(
size_t i = 0, j = 0; i < (int)pairs.size(); i += 2, ++j) {
   352                                                 cv::Point2f pi(keypoints[pairs[i+1]].pt);
   357                                                         keypoints[pairs[i+1]].pt + Point2f(0.0,(
float)
mObjects[0].rows),
   358                                                         Scalar(i*i%244,100-i*100%30,i*i-50*i));
   363                                 for(
size_t i = 0, j = 0; i < (int)pairs.size(); i += 2, ++j) {
   364                                         cv::Point2f pi(keypoints[pairs[i+1]].pt);
   369                                                 keypoints[pairs[i+1]].pt + Point2f(0.0,(
float)
mObjects[0].rows),
   370                                                 Scalar(i*i%244,100-i*100%30,i*i-50*i));
   376                         if(fromPt.size()>0) val = 1.*n_inliers/fromPt.size();
   377                         if(val > valmax) valmax = val;
   378                         if(val < valmin) valmin = val;
   383         cvNamedWindow(
"Matches", 1);
   392         std::fstream bs(filename.c_str(), std::fstream::in | std::fstream::binary);
   408         std::vector<float>::size_type 
size;
   409         bs.read((
char *)&size, 
sizeof(size));
   412         for (std::vector<float>::size_type i = 0; i < 
size; ++i) {
   413             bs.read((
char *)&value.pt.x, 
sizeof(value.pt.x));
   414             bs.read((
char *)&value.pt.y, 
sizeof(value.pt.y));
   415             bs.read((
char *)&value.size, 
sizeof(value.size));
   416             bs.read((
char *)&value.angle, 
sizeof(value.angle));
   417             bs.read((
char *)&value.response, 
sizeof(value.response));
   418             bs.read((
char *)&value.octave, 
sizeof(value.octave));
   419             bs.read((
char *)&value.class_id, 
sizeof(value.class_id));
   423         bs.read((
char *)&
mSize.width, 
sizeof(
mSize.width));
   424         bs.read((
char *)&
mSize.height, 
sizeof(
mSize.height));
   426         std::vector<Mat>::size_type objectsSize;
   427         bs.read((
char *)&objectsSize, 
sizeof(objectsSize));
   432         for (std::vector<Mat>::size_type i = 0; i < objectsSize; ++i) {
   433             bs.read((
char *)&rows, 
sizeof(rows));
   434             bs.read((
char *)&cols, 
sizeof(cols));
   435             bs.read((
char *)&type, 
sizeof(type));
   436             Mat objectsValue(rows, cols, type);
   437             bs.read((
char *)objectsValue.data, objectsValue.elemSize() * objectsValue.total());
   444         FileStorage fs(filename, FileStorage::READ);
   446         if (!fs.isOpened()) {
   450         FileNode node = fs.getFirstTopLevelNode();
   451         std::cout << 
"loaded file" << std::endl;
   453         std::cout << 
"loaded model points" << std::endl;
   455         std::cout << 
"loaded classifier" << std::endl;
   464         std::fstream bs(filename.c_str(), std::fstream::out | std::fstream::binary);
   481         bs.write((
char *)&size, 
sizeof(size));
   482         for (std::vector<KeyPoint>::const_iterator itr = 
mKeyPoints.begin(); itr != 
mKeyPoints.end(); ++itr) {
   483             bs.write((
char *)&itr->pt.x, 
sizeof(itr->pt.x));
   484             bs.write((
char *)&itr->pt.y, 
sizeof(itr->pt.y));
   485             bs.write((
char *)&itr->size, 
sizeof(itr->size));
   486             bs.write((
char *)&itr->angle, 
sizeof(itr->angle));
   487             bs.write((
char *)&itr->response, 
sizeof(itr->response));
   488             bs.write((
char *)&itr->octave, 
sizeof(itr->octave));
   489             bs.write((
char *)&itr->class_id, 
sizeof(itr->class_id));
   492         bs.write((
char *)&
mSize.width, 
sizeof(
mSize.width));
   493         bs.write((
char *)&
mSize.height, 
sizeof(
mSize.height));
   495         std::vector<Mat>::size_type objectsSize = 
mObjects.size();
   496         bs.write((
char *)&objectsSize, 
sizeof(objectsSize));
   497         for (std::vector<Mat>::const_iterator itr = 
mObjects.begin(); itr != 
mObjects.end(); ++itr) {
   498             bs.write((
char *)&itr->rows, 
sizeof(itr->rows));
   499             bs.write((
char *)&itr->cols, 
sizeof(itr->cols));
   500             int type = itr->type();
   501             bs.write((
char *)&type, 
sizeof(type));
   502             bs.write((
char *)itr->data, itr->elemSize() * itr->total());
   508         FileStorage fs(filename, FileStorage::WRITE);
   510         if (!fs.isOpened()) {
   514         WriteStructContext ws(fs, 
"fern_image_detector", CV_NODE_MAP);
 
This file implements a Fern-based image detector. 
virtual void readBinary(std::fstream &stream)
std::vector< Mat > mObjects
void modelPoints(vector< CvPoint3D64f > &points, bool normalize=true)
FernImageDetector(const bool visualize=false)
TFSIMD_FORCE_INLINE const tfScalar & y() const 
void imagePoints(vector< CvPoint2D64f > &points)
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
virtual ~FernClassifierWrapper()
TFSIMD_FORCE_INLINE const tfScalar & x() const 
std::vector< FernClassifierWrapper > mClassifier
bool read(const std::string &filename, const bool binary=true)
vector< cv::Point2f > mModelPoints
vector< KeyPoint > mKeyPoints
PatchGenerator mPatchGenerator
void findFeatures(Mat &image, bool planeAssumption=true)
bool write(const std::string &filename, const bool binary=true)
vector< cv::Point2f > mImagePoints
virtual void writeBinary(std::fstream &stream) const 
void train(const std::string &filename)