001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.image.feature.local.keypoints;
031
032import java.io.DataInput;
033import java.io.DataOutput;
034import java.io.IOException;
035import java.io.PrintWriter;
036import java.util.Scanner;
037
038/**
039 * A {@link Keypoint} extended to hold information on whether was detected at a
040 * maxima or minima.
041 * 
042 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
043 */
044public class MinMaxKeypoint extends Keypoint {
045        private static final long serialVersionUID = 1L;
046
047        /**
048         * Was the keypoint detected at a maxima?
049         */
050        public boolean isMaxima;
051
052        /**
053         * Construct with the default feature vector length for SIFT (128).
054         */
055        public MinMaxKeypoint() {
056                super();
057        }
058
059        /**
060         * Construct with the given parameters
061         * 
062         * @param x
063         *            x-ordinate of feature
064         * @param y
065         *            y-ordinate of feature
066         * @param scale
067         *            scale of feature
068         * @param ori
069         *            orientation of feature
070         * @param ivec
071         *            the feature vector
072         * @param isMaxima
073         *            was the detection at a maxima?
074         */
075        public MinMaxKeypoint(float x, float y, float ori, float scale, byte[] ivec, boolean isMaxima) {
076                super(x, y, ori, scale, ivec);
077                this.isMaxima = isMaxima;
078        }
079
080        /**
081         * Construct with the given feature vector length.
082         * 
083         * @param length
084         *            the length of the feature vector
085         */
086        public MinMaxKeypoint(int length) {
087                super(length);
088        }
089
090        /**
091         * The location of a {@link MinMaxKeypoint}.
092         * 
093         * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
094         * 
095         */
096        public static class MinMaxKeypointLocation extends KeypointLocation {
097                private static final long serialVersionUID = 1L;
098
099                /**
100                 * Was the keypoint detected at a maxima?
101                 */
102                public boolean isMaxima;
103
104                /**
105                 * Construct with the given parameters
106                 * 
107                 * @param x
108                 *            x-ordinate of feature
109                 * @param y
110                 *            y-ordinate of feature
111                 * @param scale
112                 *            scale of feature
113                 * @param ori
114                 *            orientation of feature
115                 * @param isMaxima
116                 *            was the detection at a maxima?
117                 */
118                public MinMaxKeypointLocation(float x, float y, float ori, float scale, boolean isMaxima) {
119                        super(x, y, ori, scale);
120                        this.isMaxima = isMaxima;
121                }
122
123                @Override
124                public void writeBinary(DataOutput out) throws IOException {
125                        out.writeFloat(this.x);
126                        out.writeFloat(this.y);
127                        out.writeFloat(this.scale);
128                        out.writeFloat(this.orientation);
129                        out.writeBoolean(isMaxima);
130                }
131
132                @Override
133                public void writeASCII(PrintWriter out) throws IOException {
134                        /* Output data for the keypoint. */
135                        out.format("%4.2f %4.2f %4.2f %4.3f %d", y, x, scale, orientation, isMaxima ? 1 : 0);
136                        out.println();
137                }
138
139                @Override
140                public void readBinary(DataInput in) throws IOException {
141                        super.readBinary(in);
142                        isMaxima = in.readBoolean();
143                }
144
145                @Override
146                public void readASCII(Scanner in) throws IOException {
147                        super.readASCII(in);
148                        isMaxima = in.nextInt() == 1;
149                }
150        }
151
152        @Override
153        public MinMaxKeypointLocation getLocation() {
154                return new MinMaxKeypointLocation(x, y, ori, scale, isMaxima);
155        }
156
157        @Override
158        public void setLocation(KeypointLocation location) {
159                super.setLocation(location);
160                if (location instanceof MinMaxKeypointLocation)
161                        this.isMaxima = ((MinMaxKeypointLocation) location).isMaxima;
162        }
163}