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.engine.ipd; 031 032import org.openimaj.image.FImage; 033import org.openimaj.image.Image; 034import org.openimaj.image.feature.local.extraction.ScaleSpaceImageExtractorProperties; 035import org.openimaj.image.feature.local.interest.InterestPointData; 036import org.openimaj.image.processing.transform.ProjectionProcessor; 037import org.openimaj.image.processor.SinglebandImageProcessor; 038import org.openimaj.math.geometry.transforms.TransformUtilities; 039import Jama.Matrix; 040 041public class InterestPointImageExtractorProperties<P, I extends Image<P, I> & SinglebandImageProcessor.Processable<Float, FImage, I>> 042 extends ScaleSpaceImageExtractorProperties<I> { 043 044 private boolean affineInvariant; 045 public int halfWindowSize; 046 public int featureWindowSize; 047 public InterestPointData interestPointData; 048 049 public InterestPointImageExtractorProperties(I image, 050 InterestPointData point) { 051 this(image, point, true); 052 } 053 054 public InterestPointImageExtractorProperties(I image, 055 InterestPointData point, boolean affineInvariant) { 056 this.affineInvariant = affineInvariant; 057 this.image = extractSubImage(image, point); 058 if (this.image == null) 059 System.out.println(); 060 this.scale = point.getScale(); 061 this.x = this.image.getWidth() / 2; 062 this.y = this.image.getHeight() / 2; 063 this.interestPointData = point; 064 } 065 066 private I extractSubImage(I image, InterestPointData point) { 067 // First extract the window around the point at the window size 068 // double scaleFctor = 5 * point.scale; 069 double scaleFctor = (int) Math.max(9, Math.round(3 * point.scale)); 070 this.halfWindowSize = (int) scaleFctor; 071 this.featureWindowSize = halfWindowSize * 2; 072 I subImage = null; 073 Matrix transformMatrix = null; 074 if (this.affineInvariant) { 075 transformMatrix = calculateTransformMatrix(point); 076 } else { 077 transformMatrix = TransformUtilities.translateMatrix(-point.x, 078 -point.y); 079 } 080 081 subImage = extractSubImage(image, transformMatrix, halfWindowSize, 082 featureWindowSize); 083 return subImage; 084 } 085 086 private I extractSubImage(I image, Matrix transformMatrix, int windowSize, 087 int featureWindowSize) { 088 ProjectionProcessor<P, I> pp = new ProjectionProcessor<P, I>(); 089 pp.setMatrix(transformMatrix); 090 image.accumulateWith(pp); 091 I patch = pp.performProjection((int) -windowSize, (int) windowSize, 092 (int) -windowSize, (int) windowSize, null); 093 if (patch.getWidth() > 0 && patch.getHeight() > 0) { 094 I patchToReturn = patch.extractCenter(featureWindowSize, 095 featureWindowSize); 096 return patchToReturn; 097 } 098 return null; 099 } 100 101 private Matrix calculateTransformMatrix(InterestPointData point) { 102 Matrix transform = point.getTransform(); 103 104 this.halfWindowSize = (int) (this.halfWindowSize); 105 this.featureWindowSize = this.halfWindowSize * 2; 106 107 Matrix center = TransformUtilities.translateMatrix(-point.x, -point.y); 108 transform = transform.times(center); 109 110 return transform; 111 } 112 113}