/*
* Copyright (c) 2011. Philipp Wagner <bytefish[at]gmx[dot]de>.
* Released to public domain under terms of the BSD Simplified license.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the organization nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* See <http://www.opensource.org/licenses/bsd-license>
*/ #include "opencv2/core/core.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/highgui/highgui.hpp" #include <iostream>
#include <fstream>
#include <sstream> using namespace cv;
using namespace std; static Mat norm_0_255(InputArray _src) {
Mat src = _src.getMat();
// Create and return normalized image:
Mat dst;
switch(src.channels()) {
case :
cv::normalize(_src, dst, , , NORM_MINMAX, CV_8UC1);
break;
case :
cv::normalize(_src, dst, , , NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
} static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "No valid input file was given, please check the given filename.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if(!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, ));
labels.push_back(atoi(classlabel.c_str()));
}
}
} int main(int argc, const char *argv[]) {
// Check for valid command line arguments, print usage
// if no arguments were given.
if (argc < ) {
cout << "usage: " << argv[] << " <csv.ext> <output_folder> " << endl;
exit();
}
string output_folder = ".";
if (argc == ) {
output_folder = string(argv[]);
}
// Get the path to your CSV.
string fn_csv = string(argv[]);
// These vectors hold the images and corresponding labels.
vector<Mat> images;
vector<int> labels;
// Read in the data. This can fail if no valid
// input filename is given.
try {
read_csv(fn_csv, images, labels);
} catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
// nothing more we can do
exit();
}
// Quit if there are not enough images for this demo.
if(images.size() <= ) {
string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
CV_Error(CV_StsError, error_message);
}
// Get the height from the first image. We'll need this
// later in code to reshape the images to their original
// size:
int height = images[].rows;
// The following lines simply get the last images from
// your dataset and remove it from the vector. This is
// done, so that the training data (which we learn the
// cv::FaceRecognizer on) and the test data we test
// the model with, do not overlap.
Mat testSample = images[images.size() - ];
int testLabel = labels[labels.size() - ];
images.pop_back();
labels.pop_back();
// The following lines create an Fisherfaces model for
// face recognition and train it with the images and
// labels read from the given CSV file.
// If you just want to keep 10 Fisherfaces, then call
// the factory method like this:
//
// cv::createFisherFaceRecognizer(10);
//
// However it is not useful to discard Fisherfaces! Please
// always try to use _all_ available Fisherfaces for
// classification.
//
// If you want to create a FaceRecognizer with a
// confidence threshold (e.g. 123.0) and use _all_
// Fisherfaces, then call it with:
//
// cv::createFisherFaceRecognizer(0, 123.0);
//
Ptr<FaceRecognizer> model = createFisherFaceRecognizer();
model->train(images, labels);
// The following line predicts the label of a given
// test image:
int predictedLabel = model->predict(testSample);
//
// To get the confidence of a prediction call the model with:
//
// int predictedLabel = -1;
// double confidence = 0.0;
// model->predict(testSample, predictedLabel, confidence);
//
string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
cout << result_message << endl;
// Here is how to get the eigenvalues of this Eigenfaces model:
Mat eigenvalues = model->getMat("eigenvalues");
// And we can do the same to display the Eigenvectors (read Eigenfaces):
Mat W = model->getMat("eigenvectors");
// Get the sample mean from the training data
Mat mean = model->getMat("mean");
// Display or save:
if(argc == ) {
imshow("mean", norm_0_255(mean.reshape(, images[].rows)));
} else {
imwrite(format("%s/mean.png", output_folder.c_str()), norm_0_255(mean.reshape(, images[].rows)));
}
// Display or save the first, at most 16 Fisherfaces:
for (int i = ; i < min(, W.cols); i++) {
string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
cout << msg << endl;
// get eigenvector #i
Mat ev = W.col(i).clone();
// Reshape to original size & normalize to [0...255] for imshow.
Mat grayscale = norm_0_255(ev.reshape(, height));
// Show the image & apply a Bone colormap for better sensing.
Mat cgrayscale;
applyColorMap(grayscale, cgrayscale, COLORMAP_BONE);
// Display or save:
if(argc == ) {
imshow(format("fisherface_%d", i), cgrayscale);
} else {
imwrite(format("%s/fisherface_%d.png", output_folder.c_str(), i), norm_0_255(cgrayscale));
}
}
// Display or save the image reconstruction at some predefined steps:
for(int num_component = ; num_component < min(, W.cols); num_component++) {
// Slice the Fisherface from the model:
Mat ev = W.col(num_component);
Mat projection = subspaceProject(ev, mean, images[].reshape(,));
Mat reconstruction = subspaceReconstruct(ev, mean, projection);
// Normalize the result:
reconstruction = norm_0_255(reconstruction.reshape(, images[].rows));
// Display or save:
if(argc == ) {
imshow(format("fisherface_reconstruction_%d", num_component), reconstruction);
} else {
imwrite(format("%s/fisherface_reconstruction_%d.png", output_folder.c_str(), num_component), reconstruction);
}
}
// Display if we are not writing to an output folder:
if(argc == ) {
waitKey();
}
return ;
}

Fisherfaces 算法的具体实现源码的更多相关文章

  1. 中国象棋程序的设计与实现(六)--N皇后问题的算法设计与实现(源码+注释+截图)

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题. 该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列 ...

  2. 数据挖掘:关联规则的apriori算法在weka的源码分析

    相对于机器学习,关联规则的apriori算法更偏向于数据挖掘. 1) 测试文档中调用weka的关联规则apriori算法,如下 try { File file = new File("F:\ ...

  3. 数据挖掘 FP-tree算法C++实现及源码

    FP-growth挖掘算法 步骤一 扫描数据库,扫描数据库一次,得到频繁1-项集,把项按支持度递减排序,再一次扫描数据库,建立FP-tree 步骤二 对每个项,生成它的 条件模式库 步骤三 用条件模式 ...

  4. 常用限流算法与Guava RateLimiter源码解析

    在分布式系统中,应对高并发访问时,缓存.限流.降级是保护系统正常运行的常用方法.当请求量突发暴涨时,如果不加以限制访问,则可能导致整个系统崩溃,服务不可用.同时有一些业务场景,比如短信验证码,或者其它 ...

  5. 最快速的“高斯”模糊算法(附Android源码)

      这是一个外国人的算法,本人是搬运工.参考:http://blog.ivank.net/fastest-gaussian-blur.html   1:高斯模糊算法(参考:http://www.rua ...

  6. A*算法(附c源码)

    关于A*算法网上介绍的有很多,我只是看了之后对这个算法用c写了一下,并测试无误后上传以分享一下,欢迎指正!下面是我找的一个介绍,并主要根据这个实现的. 寻路算法不止 A* 这一种, 还有递归, 非递归 ...

  7. SIFT算法的教程及源码

    1.ubc:DAVID LOWE---SIFT算法的创始人,两篇巨经典经典的文章http://www.cs.ubc.ca/~lowe/[1] 2.cmu:YanKe---PCASIFT,总结的SIFT ...

  8. 常见算法合集[java源码+持续更新中...]

    一.引子 本文搜集从各种资源上搜集高频面试算法,慢慢填充...每个算法都亲测可运行,原理有注释.Talk is cheap,show me the code! 走你~ 二.常见算法 2.1 判断单向链 ...

  9. 【数据结构&算法】08-栈概念&源码

    目录 前言 栈的定义 定义 常见应用 栈的常见应用 进栈出栈变化形式 栈的抽象数据类型 栈的顺序存储结构及实现 栈的顺序存储结构 顺序栈 顺序栈的结构定义 两栈共享空间 栈的链式存储结构及实现 栈的链 ...

随机推荐

  1. Lightoj 1098【数学/玄学】

    题意: 对于每个数求除1和本身的约数和,然后求前n个数的所有这种约数的和: 思路: 首先可以知道对于约数考虑就好了, 对于1-n的约数,n/2-1(减1是因为2不算啊)就是约数为2出现过的次数 如果n ...

  2. 打包时,指定war包的名称

    在pom.xml中修改finalName节点的值即可,如下: <build> <plugins> <plugin> <groupId>org.sprin ...

  3. 51nodcontest#24 A(xjb)

    題目鏈接:http://www.51nod.com/contest/problem.html#!problemId=1804 題意:中文題誒~ 思路: 三角形個數爲n-1, a, b數組元素個數也爲n ...

  4. cf786C(xjb)

    题目链接:http://codeforces.com/problemset/problem/768/C 题意:给出一个数组,经过k次操作后最大元素和最小元素分别是什么.. 操作:给当前数组排序,再将第 ...

  5. ionic4+angular7+cordova开发入门

    前言 ionic是一个垮平台开发框架,可通过web技术开发出多平台的应用.但只建议开发简单应用.复杂的应用需要用到许多cordova插件,而cordova插件的更新或者移动平台的更新很可能导致插件的不 ...

  6. System.TypeInitializationException: 'The type initializer for 'MySql.Data.MySqlClient.Replication.ReplicationManager' threw an exception.'

    下午在调试的时候报错数据库连接就报错我就很纳闷后面用原来的代码写发现还是报错 System.TypeInitializationException: 'The type initializer for ...

  7. 【CSS】纯css实现立体摆放图片效果

    1.  元素的 width/height/padding/margin 的百分比基准 设置 一个元素 width/height/padding/margin 的百分比的时候,大家可知道基准是什么? 举 ...

  8. Android 权限的实现

    1.    权限 每个程序在安装时都有建立一个系统ID,如app_15,用以保护数据不被其它应用获取.Android根据不同的用户和组,分配不同权限,比如访问SD卡,访问网络等等.底层映射为Linux ...

  9. siege4安装和使用介绍

    使用文档参考地址:https://www.joedog.org/siege-manual/ siege4地址:http://download.joedog.org/siege/ cd /usr/loc ...

  10. APP启动原理

    当我们点击一个应用的时候,系统会自动创建一个相应的activity类实例,然后执行Oncreate方法,接着会执行以下两行代码,解释如下: super.onCreate(savedInstanceSt ...