1 /**
2 * Copyright (c) 2011, The University of Southampton and the individual contributors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * * Neither the name of the University of Southampton nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 package org.openimaj.image.feature.dense.gradient.dsift;
31
32 import java.io.DataInput;
33 import java.io.DataOutput;
34 import java.io.IOException;
35 import java.io.PrintWriter;
36 import java.util.Scanner;
37 import java.util.StringTokenizer;
38
39 import org.openimaj.feature.FloatFV;
40
41 /**
42 * Dense SIFT keypoint with a location and float feature vector. Also includes
43 * the energy of the feature prior to normalisation in case low-contrast
44 * features need removing.
45 *
46 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
47 *
48 */
49 public class FloatDSIFTKeypoint
50 extends
51 AbstractDSIFTKeypoint<FloatFV, float[]>
52 {
53 static final long serialVersionUID = 12345545L;
54
55 /**
56 * Construct with the default feature vector length for SIFT (128).
57 */
58 public FloatDSIFTKeypoint() {
59 this(DEFAULT_LENGTH);
60 }
61
62 /**
63 * Construct with the given feature vector length.
64 *
65 * @param length
66 * the length of the feature vector
67 */
68 public FloatDSIFTKeypoint(int length) {
69 this.descriptor = new float[length];
70 }
71
72 /**
73 * Construct with the given parameters.
74 *
75 * @param x
76 * the x-ordinate of the keypoint
77 * @param y
78 * the y-ordinate of the keypoint
79 * @param descriptor
80 * the feature vector of the keypoint
81 * @param energy
82 * the energy of the keypoint
83 */
84 public FloatDSIFTKeypoint(final float x, final float y, final float[] descriptor, final float energy) {
85 this.x = x;
86 this.y = y;
87 this.descriptor = descriptor;
88 this.energy = energy;
89 }
90
91 @Override
92 public FloatFV getFeatureVector() {
93 return new FloatFV(descriptor);
94 }
95
96 @Override
97 public String toString() {
98 return ("FloatDSIFTKeypoint(" + this.x + ", " + this.y + ")");
99 }
100
101 @Override
102 public void writeBinary(DataOutput out) throws IOException {
103 out.writeFloat(x);
104 out.writeFloat(y);
105 out.writeFloat(energy);
106
107 for (final float f : descriptor)
108 out.writeFloat(f);
109 }
110
111 @Override
112 public void writeASCII(PrintWriter out) throws IOException {
113 /* Output data for the keypoint. */
114 out.write(x + " " + y + " " + energy + "\n");
115
116 for (int i = 0; i < descriptor.length; i++) {
117 if (i > 0 && i % 20 == 0)
118 out.println();
119 out.format(" %f", descriptor[i]);
120 }
121 out.println();
122 }
123
124 @Override
125 public void readBinary(DataInput in) throws IOException {
126 x = in.readFloat();
127 y = in.readFloat();
128 energy = in.readFloat();
129 for (int i = 0; i < descriptor.length; i++)
130 descriptor[i] = in.readFloat();
131 }
132
133 @Override
134 public void readASCII(Scanner in) throws IOException {
135 x = in.nextFloat();
136 y = in.nextFloat();
137 energy = in.nextFloat();
138
139 int i = 0;
140 while (i < descriptor.length) {
141 final String line = in.nextLine();
142 final StringTokenizer st = new StringTokenizer(line);
143
144 while (st.hasMoreTokens()) {
145 descriptor[i] = Float.parseFloat(st.nextToken());
146 i++;
147 }
148 }
149 }
150 }