package utils; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import android.graphics.Bitmap; /** * Local Binary Pattern descriptor. * @author Alan Zanoni Peixinho */ public class LocalBinaryPattern { public static final int WIDTH = 75; public static final int HEIGHT = 150; double windowW, windowH; long time; int pixels[]; /** Initialize some variables. * @param windowW Window width. * @param windowH Window height. */ private void initialize(double windowW, double windowH) { this.windowW = windowW; this.windowH = windowH; time = 0; pixels = null; } /** Creates an instance of {@link LocalBinaryPattern} without windows. */ public LocalBinaryPattern() { initialize(1.0, 1.0); } /** Creates an instance of {@link LocalBinaryPattern} with windows. * @param detect Face detector used. * @param windowPercentage Windows size percentage used in descriptor. */ public LocalBinaryPattern(FaceDetect detect, double windowPercentage) { initialize(windowPercentage, windowPercentage); } /** Creates an instance of {@link LocalBinaryPattern} with windows. * @param detect Face detector used. * @param windowW Window width. * @param windowH Window height. */ public LocalBinaryPattern(FaceDetect detect, double windowW, double windowH) { initialize(windowW, windowH); } /** Creates an instance of {@link LocalBinaryPattern} with windows. * @param detect Face detector used. */ public LocalBinaryPattern(FaceDetect detect) { initialize(1.0, 1.0); } /** Get the (x,y) pixel in the image array. * @param pixels Image array. * @param x Pixel line. * @param y Pixel Column. * @param width Image width. * @return Return the pixel value at (x,y). */ private int getPixel(int pixels[], int x, int y, int width) { return pixels[y * width + x]; } private int[] lbpToInt(Bitmap img) { int[] feats = new int[257]; for (int i = 0; i < feats.length; ++i) feats[i] = 0; if (pixels == null || pixels.length < (img.getHeight() * img.getWidth())) { pixels = new int[img.getWidth() * img.getHeight()]; } int width = img.getWidth(); int height = img.getHeight(); img.getPixels(pixels, 0, width, 0, 0, width, height); for (int i = 0; i < pixels.length; i++) { pixels[i] = (int) FaceImage.rgb2gray(pixels[i]); } for (int i = 1; i < width - 1; ++i) { for (int j = 1; j < height - 1; ++j) { int output = 0; int cur = getPixel(pixels, i, j, width); if (getPixel(pixels, i - 1, j - 1, width) >= cur) { output = 1; } else { output = 0; } if (getPixel(pixels, i, j - 1, width) >= cur) { output = (output << 1) + 1; } else { output = (output << 1) + 0; } if (getPixel(pixels, i + 1, j - 1, width) >= cur) { output = (output << 1) + 1; } else { output = (output << 1) + 0; } if (getPixel(pixels, i + 1, j, width) >= cur) { output = (output << 1) + 1; } else { output = (output << 1) + 0; } if (getPixel(pixels, i + 1, j + 1, width) >= cur) { output = (output << 1) + 1; } else { output = (output << 1) + 0; } if (getPixel(pixels, i, j + 1, width) >= cur) { output = (output << 1) + 1; } else { output = (output << 1) + 0; } if (getPixel(pixels, i - 1, j + 1, width) >= cur) { output = (output << 1) + 1; } else { output = (output << 1) + 0; } if (getPixel(pixels, i - 1, j, width) >= cur) { output = (output << 1) + 1; } else { output = (output << 1) + 0; } feats[output]++; } } int sum = 0; for (int k = 0; k < feats.length; k++) { sum += feats[k]; } feats[feats.length-1] = sum; return feats; } private ArrayList<Integer> intArrayToArrayList(int[] array) { ArrayList<Integer> list = new ArrayList<Integer>(); for(int i : array) { list.add(i); } return list; } public ArrayList<ArrayList<Integer>> getDescriptor(Bitmap img) { Bitmap resImg = FaceImage.resizeBitmap(img, (double) WIDTH / img.getWidth()); if (windowW == 1.0 && windowH == 1.0) { ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>(); list.add(intArrayToArrayList(lbpToInt(resImg))); return list; } int wInc = (int) (resImg.getWidth() * windowW); int hInc = (int) (resImg.getHeight() * windowH); ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>(); for (int i = 0; i + wInc <= resImg.getWidth(); i += wInc) { for (int j = 0; j + hInc <= resImg.getHeight(); j += hInc) { Bitmap subImg = Bitmap.createBitmap(resImg, i, j, wInc, hInc); list.add(intArrayToArrayList(lbpToInt(subImg))); subImg.recycle(); } } resImg.recycle(); return list; } public static double distance(Collection<Double> c1, Collection<Double> c2) { return MathUtils.chiSquareDistance(c1, c2); } public static Collection<Double> ArrayListToCollection(ArrayList<ArrayList<Integer>> arrayLists) { LinkedList<Double> list = new LinkedList<Double>(); for(ArrayList<Integer> subArrayList: arrayLists) { for (int i = 0; i < subArrayList.size()-1; i++) { list.addLast((double)subArrayList.get(i)/(double)subArrayList.get(subArrayList.size()-1) ); } } return list; } }