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)