// Catalano Imaging Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
package Catalano.Imaging.Tools;
import Catalano.Imaging.FastBitmap;
/**
* Weber Local Descriptor. (WLD)
* Paper: http://www.jdl.ac.cn/user/sgshan/pub/CVPR08_JChen_Print.pdf
* @author Diego Catalano
*/
public class WeberLocalDescriptor {
private final int beta = 5;
private final double epsilon = 0.0000001D;
private int alpha = 3;
private double[][] differentialExcitation;
private double[][] gradientOrientation;
/**
* Get Alpha.
* @return Alpha value.
*/
public int getAlpha() {
return alpha;
}
/**
* Set Alpha.
* @param alpha Alpha value.
*/
public void setAlpha(int alpha) {
this.alpha = alpha;
}
/**
* Get Gradient orientation.
* @return Gradient orientation.
*/
public double[][] getGradientOrientation() {
return gradientOrientation;
}
//Filter
private final int[][] kernel = {
{1, 1, 1},
{1, -8, 1},
{1, 1, 1}
};
/**
* Initialize a new instance of the WeberLocalDescriptor class.
*/
public WeberLocalDescriptor() {}
/**
* Compute Weber local descriptor.
* @param fastBitmap Image to be processed.
* @return Differential Excitation.
*/
public double[][] Compute(FastBitmap fastBitmap){
if (fastBitmap.isGrayscale()){
int width = fastBitmap.getWidth();
int height = fastBitmap.getHeight();
differentialExcitation = new double[height - 1][width - 1];
gradientOrientation = new double[height - 1][width - 1];
for (int i = 1; i < height - 1; i++) {
for (int j = 1; j < width - 1; j++) {
//Step 1: Compute differential excitation
double v00 =
kernel[0][0] * fastBitmap.getGray(i - 1, j - 1)
+ kernel[0][1] * fastBitmap.getGray(i - 1, j)
+ kernel[0][2] * fastBitmap.getGray(i - 1, j + 1)
+ kernel[1][0] * fastBitmap.getGray(i, j - 1)
+ kernel[1][1] * fastBitmap.getGray(i, j)
+ kernel[1][2] * fastBitmap.getGray(i, j + 1)
+ kernel[2][0] * fastBitmap.getGray(i + 1, j - 1)
+ kernel[2][1] * fastBitmap.getGray(i + 1, j)
+ kernel[2][2] * fastBitmap.getGray(i + 1, j + 1);
double v01 = fastBitmap.getGray(i, j) + beta;
if (v01 != 0){
differentialExcitation[i - 1][j - 1] = Math.atan(alpha * v00 / v01);
}
else{
differentialExcitation[i - 1][j - 1] = 0.1;
}
//Step 2: Compute gradient orientation
int n1 = fastBitmap.getGray(i - 1, j);
int n3 = fastBitmap.getGray(i, j + 1);
int n5 = fastBitmap.getGray(i + 1, j);
int n7 = fastBitmap.getGray(i, j - 1);
if (Math.abs(n7-n3) < epsilon){
gradientOrientation[i - 1][j - 1] = 0;
}
else{
double v10 = n5 - n1;
double v11 = n7 - n3;
gradientOrientation[i - 1][j - 1] = Math.atan(v10/v11) * 180 / Math.PI;
if (v11 > epsilon && v10 > epsilon){
gradientOrientation[i - 1][j - 1] += 0;
}
else if (v11 < -epsilon && v10 > epsilon){
gradientOrientation[i - 1][j - 1] += 180;
}
else if (v11 < -epsilon && v10 < -epsilon){
gradientOrientation[i - 1][j - 1] += 180;
}
else if (v11 > epsilon && v10 < -epsilon){
gradientOrientation[i - 1][j - 1] += 360;
}
}
}
}
return differentialExcitation;
}
else{
throw new IllegalArgumentException("Weber Local Descriptor only works in grayscale images.");
}
}
/**
* Display the diffential excitation.
* @return Differential excitation.
*/
public FastBitmap toFastBitmap(){
FastBitmap fb = new FastBitmap(differentialExcitation[0].length, differentialExcitation.length, FastBitmap.ColorSpace.Grayscale);
for (int i = 0; i < differentialExcitation.length; i++) {
for (int j = 0; j < differentialExcitation[0].length; j++) {
fb.setGray(i, j, (int)(255 * (differentialExcitation[i][j] - (-Math.PI/2))/((Math.PI/2)-(-Math.PI/2))));
}
}
return fb;
}
}
Ads help maintain this website.