001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009
010package imagingbook.pub.sift;
011
012
013import java.util.Locale;
014
015/**
016 * SIFT descriptor.
017 * Added magnitude field and Comparable interface for easy sorting.
018 * @author W. Burger
019 *
020 */
021public class SiftDescriptor implements Comparable<SiftDescriptor> {
022        
023        private final double x; // image position
024        private final double y;
025        private final double scale;
026        private final double magnitude;
027        private final double orientation;
028        private final int[] features;
029        
030        public double getX() {
031                return x;
032        }
033
034        public double getY() {
035                return y;
036        }
037
038        public double getScale() {
039                return scale;
040        }
041        
042        public double getMagnitude() {
043                return magnitude;
044        }
045
046
047        public double getOrientation() {
048                return orientation;
049        }
050        public int[] getFeatures() {
051                return features;
052        }
053
054        public SiftDescriptor(double x, double y, double scale, double magnitude, double orientation, int[] features) {
055                this.x = x;
056                this.y = y;
057                this.scale = scale;
058                this.magnitude = magnitude;
059                this.orientation = orientation;
060                this.features = features;
061        }
062        
063        // -----------------------------
064        
065        public double getDistanceL1(SiftDescriptor other) {
066                int[] f1 = this.features;
067                int[] f2 = other.features;
068                int sum = 0;
069                for (int i=0; i<f1.length; i++) {
070                        sum = sum + Math.abs(f1[i] - f2[i]);
071                }
072                return sum;
073        }
074        
075        public double getDistanceL2(SiftDescriptor other) {
076                int[] f1 = this.features;
077                int[] f2 = other.features;
078                int sum = 0;
079                for (int i = 0; i < f1.length; i++) {
080                        int d = f1[i] - f2[i];
081                        sum = sum + d * d;
082                }
083                return Math.sqrt(sum);
084        }
085        
086        public double getDistanceLinf(SiftDescriptor other) {
087                int[] f1 = this.features;
088                int[] f2 = other.features;
089                int dmax = 0;
090                for (int i = 0; i < f1.length; i++) {
091                        int d = Math.abs(f1[i] - f2[i]);
092                        dmax = Math.max(dmax, d);
093                }
094                return dmax;
095        }
096        
097        // -----------------------------
098        
099        public String toString() {
100                return String.format(Locale.US, 
101                                "x=%.1f y=%.1f s=%.2f mag=%.4f angle=%.2f", 
102                                x, y, scale, magnitude, orientation);
103        }
104
105        //used for sorting SIFT descriptors by magnitude
106        public int compareTo(SiftDescriptor d2) {
107                if (this.magnitude > d2.magnitude) return -1;
108                if (this.magnitude < d2.magnitude) return 1;
109                else return 0;
110        }
111
112
113
114}