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.demos.features; 031 032import javax.swing.JFrame; 033 034import org.openimaj.demos.Demo; 035import org.openimaj.image.DisplayUtilities; 036import org.openimaj.image.MBFImage; 037import org.openimaj.image.colour.ColourSpace; 038import org.openimaj.image.colour.RGBColour; 039import org.openimaj.image.colour.Transforms; 040import org.openimaj.image.feature.local.interest.HarrisIPD; 041import org.openimaj.image.processing.convolution.FGaussianConvolve; 042import org.openimaj.math.geometry.point.Point2dImpl; 043import org.openimaj.math.geometry.shape.Ellipse; 044import org.openimaj.math.geometry.shape.EllipseUtilities; 045import org.openimaj.math.geometry.shape.Rectangle; 046import org.openimaj.math.geometry.transforms.TransformUtilities; 047 048import Jama.Matrix; 049 050/** 051 * Demo showing harris points 052 * 053 * @author Sina Samangooei (ss@ecs.soton.ac.uk) 054 * 055 */ 056@Demo( 057 author = "Sina Samangooei", 058 description = "Shows Harris interest point detection on an animated shape", 059 keywords = { 060 "sift", "animation", "feature-selection" }, 061 title = "Animated Interest Point Visualiser") 062public class AnimatedInterestPointVisualiser { 063 private Rectangle rectangle; 064 private Point2dImpl point; 065 private Matrix transform; 066 private MBFImage image; 067 private int derivscale; 068 private HarrisIPD ipd; 069 private Ellipse ellipseToDraw; 070 private JFrame jframe; 071 private float rotation; 072 073 /** 074 * Construct the demo 075 */ 076 public AnimatedInterestPointVisualiser() { 077 this.rectangle = new Rectangle(100, 100, 200, 200); 078 this.point = new Point2dImpl(110, 110); 079 this.rotation = 0f; 080 this.transform = TransformUtilities.rotationMatrixAboutPoint(this.rotation, 200, 200); 081 derivscale = 1; 082 ipd = new HarrisIPD(derivscale, 3); 083 this.image = new MBFImage(400, 400, ColourSpace.RGB); 084 this.jframe = DisplayUtilities.display(this.image); 085 drawShape(); 086 updateEllipse(); 087 088 class Updater implements Runnable { 089 private AnimatedInterestPointVisualiser frame; 090 091 Updater(AnimatedInterestPointVisualiser frame) { 092 this.frame = frame; 093 } 094 095 @Override 096 public void run() { 097 while (true) { 098 frame.drawShape(); 099 frame.updateEllipse(); 100 frame.drawFrame(); 101 frame.updateTransform(); 102 try { 103 Thread.sleep(1000 / 30); 104 } catch (final InterruptedException e) { 105 } 106 } 107 } 108 } 109 final Thread t = new Thread(new Updater(this)); 110 t.start(); 111 } 112 113 /** 114 * Update the transform 115 */ 116 public void updateTransform() { 117 this.rotation += Math.PI / 100f; 118 this.transform = TransformUtilities.rotationMatrixAboutPoint( 119 this.rotation, 200, 200); 120 } 121 122 /** 123 * Draw the frame 124 */ 125 public void drawFrame() { 126 this.image.createRenderer() 127 .drawShape(this.ellipseToDraw, RGBColour.RED); 128 DisplayUtilities.display(this.image, this.jframe); 129 } 130 131 private void updateEllipse() { 132 ipd.findInterestPoints(Transforms.calculateIntensityNTSC(this.image)); 133 final Point2dImpl np = this.point.transform(transform); 134 final Matrix sm = ipd.getSecondMomentsAt((int) np.x, (int) np.y); 135 ellipseToDraw = EllipseUtilities.ellipseFromSecondMoments(np.x, np.y, 136 sm, 5 * 2); 137 } 138 139 /** 140 * Draw the shape 141 */ 142 public void drawShape() { 143 this.image.fill(RGBColour.WHITE); 144 this.image.createRenderer().drawShapeFilled( 145 this.rectangle.transform(transform), RGBColour.BLACK); 146 147 this.image = image.process(new FGaussianConvolve(5)); 148 this.image.createRenderer().drawPoint(this.point.transform(transform), 149 RGBColour.RED, 1); 150 } 151 152 /** 153 * The main method 154 * 155 * @param args 156 * ignored 157 */ 158 public static void main(String args[]) { 159 new AnimatedInterestPointVisualiser(); 160 } 161}