Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
132 lines (119 sloc) 3.92 KB
/*
* Copyright (c) 2012. 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/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace cv;
using namespace std;
// Normalizes a given image into a value range between 0 and 255.
Mat norm_0_255(const Mat& src) {
// Create and return normalized image:
Mat dst;
switch(src.channels()) {
case 1:
cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
break;
case 3:
cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
}
//
// Calculates the TanTriggs Preprocessing as described in:
//
// Tan, X., and Triggs, B. "Enhanced local texture feature sets for face
// recognition under difficult lighting conditions.". IEEE Transactions
// on Image Processing 19 (2010), 1635–650.
//
// Default parameters are taken from the paper.
//
Mat tan_triggs_preprocessing(InputArray src,
float alpha = 0.1, float tau = 10.0, float gamma = 0.2, int sigma0 = 1,
int sigma1 = 2) {
// Convert to floating point:
Mat X = src.getMat();
X.convertTo(X, CV_32FC1);
// Start preprocessing:
Mat I;
pow(X, gamma, I);
// Calculate the DOG Image:
{
Mat gaussian0, gaussian1;
// Kernel Size:
int kernel_sz0 = (3*sigma0);
int kernel_sz1 = (3*sigma1);
// Make them odd for OpenCV:
kernel_sz0 += ((kernel_sz0 % 2) == 0) ? 1 : 0;
kernel_sz1 += ((kernel_sz1 % 2) == 0) ? 1 : 0;
GaussianBlur(I, gaussian0, Size(kernel_sz0,kernel_sz0), sigma0, sigma0, BORDER_REPLICATE);
GaussianBlur(I, gaussian1, Size(kernel_sz1,kernel_sz1), sigma1, sigma1, BORDER_REPLICATE);
subtract(gaussian0, gaussian1, I);
}
{
double meanI = 0.0;
{
Mat tmp;
pow(abs(I), alpha, tmp);
meanI = mean(tmp).val[0];
}
I = I / pow(meanI, 1.0/alpha);
}
{
double meanI = 0.0;
{
Mat tmp;
pow(min(abs(I), tau), alpha, tmp);
meanI = mean(tmp).val[0];
}
I = I / pow(meanI, 1.0/alpha);
}
// Squash into the tanh:
{
Mat exp_x, exp_negx;
exp( I / tau, exp_x );
exp( -I / tau, exp_negx );
divide( exp_x - exp_negx, exp_x + exp_negx, I );
I = tau * I;
}
return I;
}
int main(int argc, const char *argv[]) {
// Get filename to the source image:
if (argc != 2) {
cout << "usage: " << argv[0] << " <image.ext>" << endl;
exit(1);
}
// Load image & get skin proportions:
Mat image = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
// Calculate the TanTriggs Preprocessed image with default parameters:
Mat preprocessed = tan_triggs_preprocessing(image);
// Draw it on screen:
imshow("Original Image", image);
imshow("TanTriggs Preprocessed Image", norm_0_255(preprocessed));
// Show the images:
waitKey(0);
// Success!
return 0;
}