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.demos.video.utils;
34  
35  import java.awt.GridBagConstraints;
36  import java.awt.GridBagLayout;
37  import java.awt.event.ActionEvent;
38  import java.awt.event.ActionListener;
39  import java.io.IOException;
40  import java.util.List;
41  
42  import javax.swing.BorderFactory;
43  import javax.swing.JCheckBox;
44  import javax.swing.JPanel;
45  
46  import org.openimaj.demos.faces.Mustache;
47  import org.openimaj.image.MBFImage;
48  import org.openimaj.image.colour.RGBColour;
49  import org.openimaj.image.colour.Transforms;
50  import org.openimaj.image.processing.edges.CannyEdgeDetector;
51  import org.openimaj.image.processing.face.detection.DetectedFace;
52  import org.openimaj.image.processing.face.detection.HaarCascadeDetector;
53  import org.openimaj.image.processing.face.detection.keypoints.FKEFaceDetector;
54  import org.openimaj.image.processing.face.detection.keypoints.FacialKeypoint;
55  import org.openimaj.image.processing.face.detection.keypoints.KEDetectedFace;
56  import org.openimaj.image.renderer.MBFImageRenderer;
57  import org.openimaj.math.geometry.point.Point2d;
58  import org.openimaj.math.geometry.shape.Shape;
59  import org.openimaj.video.VideoDisplay;
60  import org.openimaj.video.VideoDisplayListener;
61  
62  /**
63   * @author David Dupplaw (dpd@ecs.soton.ac.uk)
64   * 
65   * @created 28 Sep 2011
66   */
67  public class ProcessingPanel extends JPanel
68  		implements VideoDisplayListener<MBFImage>
69  {
70  	/** */
71  	private static final long serialVersionUID = 1L;
72  
73  	private boolean edgeDetect = false;
74  	private boolean faceDetect = false;
75  	private boolean faceKPDetect = false;
76  	private boolean moustache = false;
77  
78  	private final FKEFaceDetector fkp;
79  
80  	private final HaarCascadeDetector d;
81  
82  	/**
83  	 * 
84  	 */
85  	public ProcessingPanel()
86  	{
87  		this.d = new HaarCascadeDetector(100);
88  		this.fkp = new FKEFaceDetector(
89  				HaarCascadeDetector.BuiltInCascade.frontalface_alt.load());
90  		this.init();
91  	}
92  
93  	/**
94  	 * 
95  	 */
96  	private void init()
97  	{
98  		this.setLayout(new GridBagLayout());
99  		this.setBorder(BorderFactory.createTitledBorder("Processing"));
100 
101 		final GridBagConstraints gbc = new GridBagConstraints();
102 		gbc.gridx = gbc.gridy = 0;
103 		gbc.fill = GridBagConstraints.HORIZONTAL;
104 		gbc.weightx = 1;
105 		gbc.weighty = 0;
106 		gbc.gridwidth = 1;
107 
108 		// -----------------------------------------------------
109 		final JCheckBox edgeDetectButton = new JCheckBox("Edge Detect", this.edgeDetect);
110 		edgeDetectButton.addActionListener(new ActionListener()
111 		{
112 			@Override
113 			public void actionPerformed(final ActionEvent e)
114 			{
115 				ProcessingPanel.this.edgeDetect = edgeDetectButton.isSelected();
116 			}
117 		});
118 		gbc.gridy++;
119 		this.add(edgeDetectButton, gbc);
120 
121 		// -----------------------------------------------------
122 		final JCheckBox faceDetectorButton = new JCheckBox("Face Detection", this.faceDetect);
123 		faceDetectorButton.addActionListener(new ActionListener()
124 		{
125 			@Override
126 			public void actionPerformed(final ActionEvent e)
127 			{
128 				ProcessingPanel.this.faceDetect = faceDetectorButton.isSelected();
129 			}
130 		});
131 		gbc.gridy++;
132 		this.add(faceDetectorButton, gbc);
133 
134 		// -----------------------------------------------------
135 		final JCheckBox faceKPDetectorButton = new JCheckBox("Facial Keypoint Detection", this.faceKPDetect);
136 		faceKPDetectorButton.addActionListener(new ActionListener()
137 		{
138 			@Override
139 			public void actionPerformed(final ActionEvent e)
140 			{
141 				ProcessingPanel.this.faceKPDetect = faceKPDetectorButton.isSelected();
142 			}
143 		});
144 		gbc.gridy++;
145 		this.add(faceKPDetectorButton, gbc);
146 
147 		// -----------------------------------------------------
148 		final JCheckBox moustacheButton = new JCheckBox("Add Moustaches", this.moustache);
149 		moustacheButton.addActionListener(new ActionListener()
150 		{
151 			@Override
152 			public void actionPerformed(final ActionEvent e)
153 			{
154 				ProcessingPanel.this.moustache = moustacheButton.isSelected();
155 			}
156 		});
157 		gbc.gridy++;
158 		this.add(moustacheButton, gbc);
159 
160 	}
161 
162 	/**
163 	 * {@inheritDoc}
164 	 * 
165 	 * @see org.openimaj.video.VideoDisplayListener#afterUpdate(org.openimaj.video.VideoDisplay)
166 	 */
167 	@Override
168 	public void afterUpdate(final VideoDisplay<MBFImage> display)
169 	{
170 	}
171 
172 	/**
173 	 * {@inheritDoc}
174 	 * 
175 	 * @see org.openimaj.video.VideoDisplayListener#beforeUpdate(org.openimaj.image.Image)
176 	 */
177 	@Override
178 	public void beforeUpdate(final MBFImage frame)
179 	{
180 		if (this.edgeDetect)
181 			frame.processInplace(new CannyEdgeDetector());
182 
183 		if (this.faceDetect)
184 		{
185 			final List<DetectedFace> faces = this.d.detectFaces(
186 					Transforms.calculateIntensityNTSC(frame));
187 
188 			for (final DetectedFace face : faces)
189 			{
190 				final Shape transBounds = face.getBounds();
191 				final MBFImageRenderer renderer = frame.createRenderer();
192 				renderer.drawPolygon(transBounds.asPolygon(), RGBColour.RED);
193 			}
194 		}
195 
196 		if (this.faceKPDetect)
197 		{
198 			final List<KEDetectedFace> faces = this.fkp.detectFaces(
199 					Transforms.calculateIntensityNTSC(frame));
200 
201 			for (final KEDetectedFace face : faces)
202 			{
203 				final Shape transBounds = face.getBounds();
204 				final MBFImageRenderer renderer = frame.createRenderer();
205 				renderer.drawPolygon(transBounds.asPolygon(), RGBColour.RED);
206 
207 				for (final FacialKeypoint kp : face.getKeypoints())
208 				{
209 					final Point2d pt = kp.position.clone();
210 					pt.translate((float) transBounds.minX(), (float) transBounds.minY());
211 					renderer.drawPoint(pt, RGBColour.GREEN, 3);
212 				}
213 			}
214 		}
215 
216 		if (this.moustache)
217 			try {
218 				frame.internalAssign(new Mustache().addMustaches(frame));
219 			} catch (final IOException e) {
220 				e.printStackTrace();
221 			}
222 	}
223 }