001package org.openimaj.demos.sandbox.tldcpp.detector;
002
003import org.openimaj.image.FImage;
004import org.openimaj.image.processing.algorithm.MeanCenter;
005import org.openimaj.image.processing.resize.ResizeFilterFunction;
006import org.openimaj.image.processing.resize.ResizeProcessor;
007import org.openimaj.image.processing.resize.filters.TriangleFilter;
008import org.openimaj.math.geometry.shape.Rectangle;
009
010/**
011 * Defines a intensity normalised patch extracted from an image. Allowances are
012 * made for reuse of patches
013 * 
014 * @author Sina Samangooei (ss@ecs.soton.ac.uk)
015 * 
016 */
017public class NormalizedPatch {
018        private final static MeanCenter msp = new MeanCenter();
019        /**
020         * Normalised patch size
021         */
022        public static final int TLD_PATCH_SIZE = 15;
023        private static final ResizeFilterFunction filter = TriangleFilter.INSTANCE;
024
025        /**
026         * The slut workspace gets around a little bit. Use the slut workspace but
027         * don't expect it to be yours for long.
028         */
029        public static final FImage SLUT_WORKSPACE = new FImage(TLD_PATCH_SIZE, TLD_PATCH_SIZE);
030        /**
031         * Is this patch positive, i.e. representative of the object
032         */
033        public boolean positive;
034        /**
035         * The image to extract this patch from
036         */
037        public FImage source;
038        /**
039         * The window to extract form the source
040         */
041        public Rectangle window;
042        /**
043         * The extracted patch, might be null, might be the SLUT_WORKSPACE.
044         */
045        public FImage normalisedPatch;
046
047        /**
048         * A function which uses
049         * {@link ResizeProcessor#zoom(FImage, Rectangle, FImage, Rectangle, ResizeFilterFunction)}
050         * on a to put {@link NormalizedPatch#window} form
051         * {@link NormalizedPatch#source} into normalisedPatch.
052         * 
053         * This is not a convenient function but it allows for very efficient
054         * resize/normalisation process (with minimal new stuff constructed)
055         * 
056         * @param holder
057         * @return the holder as a convenience
058         */
059        protected FImage zoomAndNormaliseTo(FImage holder) {
060                ResizeProcessor.zoom(source, window, holder, holder.getBounds(), filter);
061                return holder.processInplace(msp);
062        }
063
064        /**
065         * calculate the variance, sets the valueImg if it is null
066         * 
067         * @return an inefficient way to calculate variance of this window, a new
068         *         image is constructed!
069         */
070        public float calculateVariance() {
071                prepareNormalisedPatch();
072                final float[][] value = normalisedPatch.pixels;
073                float temp = 0;
074                final int n = normalisedPatch.width * normalisedPatch.height;
075                for (int y = 0; y < normalisedPatch.height; y++) {
076                        for (int x = 0; x < normalisedPatch.width; x++) {
077                                temp += (value[y][x]) * (value[y][x]); // There are two implied
078                                                                                                                // (- 0)'s here. these
079                                                                                                                // values are MEAN
080                                                                                                                // CENTERED
081                        }
082                }
083                return temp / n;
084        }
085
086        /**
087         * for construction of a new normalised patch
088         */
089        public void prepareNormalisedPatch() {
090                if (this.normalisedPatch == null) {
091                        this.normalisedPatch = new FImage(TLD_PATCH_SIZE, TLD_PATCH_SIZE);
092                        zoomAndNormaliseTo(normalisedPatch);
093                }
094        }
095}