1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.openimaj.demos.video;
31
32 import java.io.File;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.List;
36
37 import org.openimaj.image.DisplayUtilities;
38 import org.openimaj.image.MBFImage;
39 import org.openimaj.image.processing.transform.MBFProjectionProcessor;
40 import org.openimaj.image.processing.transform.ProjectionProcessor;
41 import org.openimaj.image.renderer.MBFImageRenderer;
42 import org.openimaj.math.geometry.point.Point2d;
43 import org.openimaj.math.geometry.point.Point2dImpl;
44 import org.openimaj.math.geometry.shape.Polygon;
45 import org.openimaj.math.geometry.shape.Rectangle;
46 import org.openimaj.math.geometry.transforms.TransformUtilities;
47 import org.openimaj.util.pair.IndependentPair;
48 import org.openimaj.video.VideoDisplay;
49 import org.openimaj.video.VideoDisplayListener;
50 import org.openimaj.video.capture.VideoCapture;
51 import org.openimaj.video.xuggle.XuggleVideo;
52
53 import Jama.Matrix;
54
55 public class VideoWithinVideo implements VideoDisplayListener<MBFImage> {
56 public File videoFile;
57 public XuggleVideo video;
58 public VideoCapture capture;
59 public VideoDisplay<MBFImage> display;
60 public Polygon targetArea;
61 public MBFImageRenderer renderer;
62 public List<IndependentPair<Point2d, Point2d>> pointList;
63 public Point2dImpl topLeftS = new Point2dImpl(), topLeftB = new Point2dImpl();
64 public Point2dImpl topRightS = new Point2dImpl(), topRightB = new Point2dImpl();
65 public Point2dImpl bottomLeftS = new Point2dImpl(), bottomLeftB = new Point2dImpl();
66 public Point2dImpl bottomRightS = new Point2dImpl(), bottomRightB = new Point2dImpl();
67 public Matrix captureToVideo;
68 public Rectangle videoRect;
69 private MBFImage nextCaptureFrame;
70
71 public VideoWithinVideo(String videoPath) throws IOException {
72 this.videoFile = new File(videoPath);
73 this.video = new XuggleVideo(videoFile, true);
74 this.capture = new VideoCapture(320, 240);
75 nextCaptureFrame = capture.getNextFrame().clone();
76
77 this.videoRect = new Rectangle(0, 0, video.getWidth(), video.getHeight());
78 this.captureToVideo = TransformUtilities.makeTransform(
79 new Rectangle(0, 0, capture.getWidth(), capture.getHeight()),
80 videoRect
81 );
82
83 display = VideoDisplay.createVideoDisplay(video);
84 new CaptureVideoSIFT(this);
85 display.addVideoListener(this);
86
87
88
89
90
91
92
93
94
95
96 pointList = new ArrayList<IndependentPair<Point2d, Point2d>>();
97 pointList.add(IndependentPair.pair((Point2d) topLeftB, (Point2d) topLeftS));
98 pointList.add(IndependentPair.pair((Point2d) topRightB, (Point2d) topRightS));
99 pointList.add(IndependentPair.pair((Point2d) bottomRightB, (Point2d) bottomRightS));
100 pointList.add(IndependentPair.pair((Point2d) bottomLeftB, (Point2d) bottomLeftS));
101
102 }
103
104 @Override
105 public void afterUpdate(VideoDisplay<MBFImage> display) {
106 }
107
108 @Override
109 public void beforeUpdate(MBFImage frame) {
110 DisplayUtilities.displayName(frame, "video");
111 if (renderer == null) {
112 this.renderer = frame.createRenderer();
113
114 }
115
116 updatePolygon();
117 final ProjectionProcessor<Float[], MBFImage> proc = new MBFProjectionProcessor();
118 proc.setMatrix(captureToVideo);
119
120 proc.accumulate(nextCaptureFrame);
121 if (this.targetArea != null) {
122 final Matrix transform = TransformUtilities.homographyMatrixNorm(pointList);
123 proc.setMatrix(transform);
124 proc.accumulate(frame.clone());
125 }
126 synchronized (this) {
127 proc.performProjection(0, 0, frame);
128 }
129 }
130
131 public void updatePolygon() {
132 if (this.targetArea != null) {
133 final Point2dImpl stl = (Point2dImpl) targetArea.points.get(0);
134 final Point2dImpl str = (Point2dImpl) targetArea.points.get(1);
135 final Point2dImpl sbr = (Point2dImpl) targetArea.points.get(2);
136 final Point2dImpl sbl = (Point2dImpl) targetArea.points.get(3);
137 this.topLeftS.x = stl.x;
138 this.topLeftS.y = stl.y;
139 this.topRightS.x = str.x;
140 this.topRightS.y = str.y;
141 this.bottomRightS.x = sbr.x;
142 this.bottomRightS.y = sbr.y;
143 this.bottomLeftS.x = sbl.x;
144 this.bottomLeftS.y = sbl.y;
145 }
146
147 this.topLeftB.x = videoRect.x;
148 this.topLeftB.y = videoRect.y;
149 this.topRightB.x = videoRect.x + videoRect.width;
150 this.topRightB.y = videoRect.y;
151 this.bottomRightB.x = videoRect.x + videoRect.width;
152 this.bottomRightB.y = videoRect.y + videoRect.height;
153
154 this.bottomLeftB.x = videoRect.x;
155 this.bottomLeftB.y = videoRect.y + videoRect.height;
156
157 }
158
159 public static void main(String[] args) throws IOException {
160 new VideoWithinVideo("/Users/jsh2/Movies/Screen Recording.mov");
161 }
162
163 public synchronized void copyToCaptureFrame(MBFImage frameWrite) {
164 this.nextCaptureFrame.internalCopy(frameWrite);
165 }
166 }