View Javadoc

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  /**
31   *
32   */
33  package org.openimaj.video.processing.motion;
34  
35  import java.util.LinkedList;
36  import java.util.Map;
37  import java.util.Queue;
38  
39  import org.openimaj.image.FImage;
40  import org.openimaj.math.geometry.point.Point2d;
41  import org.openimaj.video.Video;
42  import org.openimaj.video.VideoFrame;
43  import org.openimaj.video.analyser.VideoAnalyser;
44  import org.openimaj.video.timecode.HrsMinSecFrameTimecode;
45  
46  
47  /**
48   *	A motion estimator will estimate the motion of parts of a video frame.
49   *	This class includes a set of algorithms for calculating the motion estimation.
50   *	<p>
51   *	This class deals with the buffering of frames from the video which to pass
52   *	to the motion estimation. The class is abstract and the method
53   *	{@link #estimateMotionField(MotionEstimatorAlgorithm, VideoFrame, VideoFrame[])}
54   *	must be overridden by an implementing class to provide the field over which
55   *	the motion estimation will take place. This field may, for example, be a grid
56   *	or an overlapping grid. This overridden method must also determine the appropriate
57   *	way to call the motion estimation algorithm while returning a map which maps
58   *	a point to a displacement vector.
59   *
60   *	@author David Dupplaw (dpd@ecs.soton.ac.uk)
61   *  @created 1 Mar 2012
62   *
63   */
64  @SuppressWarnings( "javadoc" )
65  public abstract class MotionEstimator extends VideoAnalyser<FImage>
66  {
67  	/** The estimator to use */
68  	private MotionEstimatorAlgorithm estimator = null;
69  
70  	/** The old frame stack. It's a queue so the oldest frame is popped off */
71  	private Queue<VideoFrame<FImage>> oldFrames = null;
72  
73  	/** The estimated motion vectors for the last analysed frame */
74  	public Map<Point2d,Point2d> motionVectors = null;
75  
76  	/**
77  	 * 	Constructor a new motion estimator using the given algorithm.
78  	 *	@param alg The algorithm to use to estimate motion.
79  	 */
80  	public MotionEstimator( MotionEstimatorAlgorithm alg )
81  	{
82  		this.estimator = alg;
83  		oldFrames = new LinkedList<VideoFrame<FImage>>();
84  	}
85  
86  	/**
87  	 * 	Create a chainable motion estimator.
88  	 *	@param v The video to chain to
89  	 *	@param alg The algorithm to use to estimate motion
90  	 */
91  	public MotionEstimator( Video<FImage> v, MotionEstimatorAlgorithm alg )
92  	{
93  		super(v);
94  		this.estimator = alg;
95  		oldFrames = new LinkedList<VideoFrame<FImage>>();
96  	}
97  
98  	/**
99  	 *	{@inheritDoc}
100 	 * 	@see org.openimaj.video.analyser.VideoAnalyser#analyseFrame(org.openimaj.image.Image)
101 	 */
102 	@SuppressWarnings( "unchecked" )
103 	@Override
104 	public void analyseFrame( FImage frame )
105 	{
106 		VideoFrame<FImage> vf = new VideoFrame<FImage>( frame,
107 				new HrsMinSecFrameTimecode( getTimeStamp(), getFPS() ) );
108 
109 		motionVectors = estimateMotionField( estimator, vf,
110 				oldFrames.toArray( new VideoFrame[0] ) );
111 
112 		oldFrames.offer( vf );
113 
114 		// Make sure there's never too many frames in the queue
115 		if( oldFrames.size() > estimator.requiredNumberOfFrames() )
116 			oldFrames.poll();
117 	}
118 
119 	/**
120 	 * 	Return the estimated motion vectors for the last processed frame.
121 	 *	@return The estimated motion vectors
122 	 */
123 	public Map<Point2d,Point2d> getMotionVectors()
124 	{
125 		return motionVectors;
126 	}
127 
128 	/**
129 	 * 	This method needs to be overridden for specific layouts of motion
130 	 * 	field within the image.
131 	 *
132 	 *	@param frame The current frame
133 	 *	@param array The list of previous frames (based on the estimator)
134 	 *	@return The motion field
135 	 */
136 	protected abstract Map<Point2d, Point2d> estimateMotionField(
137 			MotionEstimatorAlgorithm estimator, VideoFrame<FImage> frame,
138 			VideoFrame<FImage>[] array );
139 }