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.HashMap;
36 import java.util.Map;
37
38 import org.openimaj.image.FImage;
39 import org.openimaj.math.geometry.point.Point2d;
40 import org.openimaj.math.geometry.point.Point2dImpl;
41 import org.openimaj.math.geometry.shape.Rectangle;
42 import org.openimaj.video.Video;
43 import org.openimaj.video.VideoFrame;
44 import org.openimaj.video.VideoSubFrame;
45
46 /**
47 * Estimates the motion field over a grid.
48 *
49 * @author David Dupplaw (dpd@ecs.soton.ac.uk)
50 * @created 1 Mar 2012
51 *
52 */
53 public class GridMotionEstimator extends MotionEstimator
54 {
55 private int x, y;
56 private boolean fixed;
57
58 /**
59 * Construct a grid-based motion estimator. If <code>fixed</code> is
60 * true, the x and y values represent the width and height of the pixel
61 * blocks. If <code>fixed</code> is false, the x and y represent the number
62 * of grid elements to spread evenly across the frame.
63 *
64 * @param alg The estimator algorithm to use
65 * @param x The x value
66 * @param y The y value
67 * @param fixed Whether x and y represent pixels or grid count.
68 */
69 public GridMotionEstimator( MotionEstimatorAlgorithm alg,
70 int x, int y, boolean fixed )
71 {
72 super( alg );
73 this.x = x; this.y = y;
74 this.fixed = fixed;
75 }
76
77 /**
78 * Construct a chained grid-based motion estimator. If <code>fixed</code> is
79 * true, the x and y values represent the width and height of the pixel
80 * blocks. If <code>fixed</code> is false, the x and y represent the number
81 * of grid elements to spread evenly across the frame.
82 *
83 * @param v The video to chain to
84 * @param alg The estimator algorithm to use
85 * @param x The x value
86 * @param y The y value
87 * @param fixed Whether x and y represent pixels or grid count.
88 */
89 public GridMotionEstimator( Video<FImage> v, MotionEstimatorAlgorithm alg,
90 int x, int y, boolean fixed )
91 {
92 super( v, alg );
93 this.x = x; this.y = y;
94 this.fixed = fixed;
95 }
96
97 /**
98 * {@inheritDoc}
99 * @see org.openimaj.video.analysis.motion.MotionEstimator#estimateMotionField(org.openimaj.video.analysis.motion.MotionEstimator.MotionEstimatorAlgorithm, org.openimaj.image.FImage, org.openimaj.image.FImage[])
100 */
101 @Override
102 protected Map<Point2d, Point2d> estimateMotionField(
103 MotionEstimatorAlgorithm estimator, VideoFrame<FImage> vf,
104 VideoFrame<FImage>[] array )
105 {
106 if( array.length < 1 )
107 return new HashMap<Point2d,Point2d>();
108
109 int gw = 0, gh = 0;
110 if( fixed )
111 {
112 gw = x;
113 gh = y;
114 }
115 else
116 {
117 gw = vf.frame.getWidth()/x;
118 gh = vf.frame.getHeight()/y;
119 }
120
121 Map<Point2d,Point2d> out = new HashMap<Point2d, Point2d>();
122
123 @SuppressWarnings( "unchecked" )
124 VideoSubFrame<FImage>[] otherFrames = new VideoSubFrame[array.length];
125
126 for( int yy = 0; yy < vf.frame.getHeight(); yy += gh )
127 {
128 for( int xx = 0; xx < vf.frame.getWidth(); xx += gw )
129 {
130 for( int ff = 0; ff < array.length; ff++ )
131 otherFrames[ff] = new VideoSubFrame<FImage>(
132 array[ff].frame,
133 array[ff].timecode,
134 new Rectangle(xx, yy, gw, gh));
135
136 // vf.frame.drawShape( new Rectangle(xx,yy,gw,gh), 1, 0f );
137
138 out.put( new Point2dImpl(xx+gw/2f,yy+gh/2f),
139 estimator.estimateMotion( new VideoSubFrame<FImage>(
140 vf.frame,
141 vf.timecode,
142 new Rectangle(xx, yy, gw, gh)),
143 otherFrames ) );
144 }
145 }
146
147 return out;
148 }
149 }