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.affine; 031 032import java.io.DataInput; 033import java.io.DataOutput; 034import java.io.IOException; 035import java.io.PrintWriter; 036import java.util.Scanner; 037 038import org.openimaj.image.feature.local.keypoints.Keypoint; 039import org.openimaj.image.feature.local.keypoints.KeypointLocation; 040import org.openimaj.image.processing.transform.AffineParams; 041 042/** 043 * An extension of a {@link Keypoint} that holds the {@link AffineParams} and 044 * simulation index of the affine simulation from which it was detected. 045 * 046 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 047 * 048 */ 049public class AffineSimulationKeypoint extends Keypoint { 050 private static final long serialVersionUID = 1L; 051 052 /** 053 * The affine simulation parameters of the keypoint 054 */ 055 public AffineParams affineParams; 056 057 /** 058 * The simulation index of the keypoint; this corresponds to the simulation 059 * in which the keypoint was detected. 060 */ 061 public int index; 062 063 /** 064 * Construct with the given feature vector length. The parameters are set to 065 * zero tilt and rotation. 066 * 067 * @param length 068 * the length of the feature vector 069 */ 070 public AffineSimulationKeypoint(int length) { 071 super(length); 072 073 this.affineParams = new AffineParams(); 074 } 075 076 /** 077 * Construct from the given parameters 078 * 079 * @param k 080 * a keypoint 081 * @param afParams 082 * the affine simulation parameters 083 * @param index 084 * the affine simulation index 085 */ 086 public AffineSimulationKeypoint(Keypoint k, AffineParams afParams, int index) { 087 super(k); 088 this.affineParams = new AffineParams(); 089 this.affineParams.theta = afParams.theta; 090 this.affineParams.tilt = afParams.tilt; 091 this.index = index; 092 } 093 094 /** 095 * A {@link KeypointLocation} extended to hold a rotation, tilt and index 096 * corresponding to an affine simulation. 097 * 098 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 099 * 100 */ 101 public static class AffineSimulationKeypointLocation extends KeypointLocation { 102 private static final long serialVersionUID = 1L; 103 104 /** 105 * The rotation angle 106 */ 107 public float theta; 108 109 /** 110 * The amount of tilt 111 */ 112 public float tilt; 113 114 /** 115 * The simulation index 116 */ 117 public int index; 118 119 /** 120 * Construct with zero tilt and rotation. 121 */ 122 public AffineSimulationKeypointLocation() { 123 super(); 124 } 125 126 /** 127 * Construct with the given parameters 128 * 129 * @param x 130 * x-ordinate of feature 131 * @param y 132 * y-ordinate of feature 133 * @param scale 134 * scale of feature 135 * @param ori 136 * orientation of feature 137 * @param theta 138 * rotation of the simulation from which the feature was 139 * extracted 140 * @param tilt 141 * tilt of the simulation from which the feature was 142 * extracted 143 * @param index 144 * index of the simulation from which the feature was 145 * extracted 146 */ 147 public AffineSimulationKeypointLocation(float x, float y, float scale, float ori, float theta, float tilt, 148 int index) 149 { 150 super(x, y, ori, scale); 151 152 this.theta = theta; 153 this.tilt = tilt; 154 this.index = index; 155 } 156 157 @Override 158 public void writeBinary(DataOutput out) throws IOException { 159 out.writeFloat(this.x); 160 out.writeFloat(this.y); 161 out.writeFloat(this.scale); 162 out.writeFloat(this.orientation); 163 out.writeFloat(theta); 164 out.writeFloat(tilt); 165 out.writeInt(index); 166 } 167 168 @Override 169 public void writeASCII(PrintWriter out) throws IOException { 170 /* Output data for the keypoint. */ 171 out.format("%4.2f %4.2f %4.2f %4.3f %4.3f %4.3f %d", y, x, scale, orientation, theta, tilt, index); 172 out.println(); 173 } 174 175 @Override 176 public void readBinary(DataInput in) throws IOException { 177 super.readBinary(in); 178 theta = in.readFloat(); 179 tilt = in.readFloat(); 180 index = in.readInt(); 181 } 182 183 @Override 184 public void readASCII(Scanner in) throws IOException { 185 super.readASCII(in); 186 theta = in.nextFloat(); 187 tilt = in.nextFloat(); 188 String indexString = in.next(); 189 final int dotIndex = indexString.indexOf("."); 190 if (dotIndex != -1) 191 indexString = indexString.substring(0, dotIndex); 192 index = Integer.parseInt(indexString); 193 } 194 195 @Override 196 public Float getOrdinate(int dimension) { 197 final float[] pos = { x, y, scale, orientation, theta, tilt, index }; 198 return pos[dimension]; 199 } 200 } 201 202 @Override 203 public AffineSimulationKeypointLocation getLocation() { 204 return new AffineSimulationKeypointLocation(x, y, scale, ori, this.affineParams.theta, this.affineParams.tilt, 205 this.index); 206 } 207 208 @Override 209 public void setLocation(KeypointLocation location) { 210 super.setLocation(location); 211 this.affineParams = new AffineParams(); 212 this.affineParams.theta = ((AffineSimulationKeypointLocation) location).theta; 213 this.affineParams.tilt = ((AffineSimulationKeypointLocation) location).tilt; 214 this.index = ((AffineSimulationKeypointLocation) location).index; 215 } 216 217 @Override 218 public Float getOrdinate(int dimension) { 219 final float[] pos = { x, y, scale, ori, this.affineParams.theta, this.affineParams.tilt, index }; 220 return pos[dimension]; 221 } 222 223 @Override 224 public String toString() { 225 return "AffineKeypoint(" + this.affineParams.theta + "," + this.affineParams.tilt + "," + super.toString() + ")"; 226 } 227}