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.campusview;
031
032import java.awt.BorderLayout;
033import java.awt.Color;
034import java.awt.EventQueue;
035import java.awt.Graphics;
036//import java.awt.image.BufferedImage;
037import java.io.File;
038import java.io.IOException;
039import java.util.ArrayList;
040import java.util.List;
041
042//import javax.imageio.ImageIO;
043import javax.swing.JFrame;
044import javax.swing.JPanel;
045
046import org.joda.time.DateTime;
047import org.openimaj.hardware.compass.CompassData;
048import org.openimaj.image.ImageUtilities;
049import org.openimaj.image.MBFImage;
050
051/**
052 * The CampusView capture application
053 * 
054 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
055 * @author David Dupplaw (dpd@ecs.soton.ac.uk)
056 *
057 */
058public class CampusView implements CaptureControlsDelegate {
059
060        private JFrame frame;
061        
062        private List<CaptureComponent> captureComponents = new ArrayList<CaptureComponent>();
063        
064        private int captureCount = 0;
065
066        private CaptureControls captureControls;
067        
068        private GPSPositionComponent gpsComp;
069        
070        private CompassComponent compassComp;
071        
072        private JPanel contentPanel;
073        
074        private double captureRate = 5;
075        private boolean runCapture = false;
076
077        private File imageDir;
078
079        private File imageMetadata;
080
081        private File batchMetadata;
082        
083        /**
084         * Launch the application.
085         * @param args 
086         */
087        public static void main(String[] args) {
088                EventQueue.invokeLater(new Runnable() {
089                        @Override
090                        public void run() {
091                                try {
092                                        CampusView window = new CampusView();
093                                        window.frame.setVisible(true);
094                                } catch (Exception e) {
095                                        e.printStackTrace();
096                                }
097                        }
098                });
099        }
100
101        /**
102         * Create the application.
103         * @throws IOException 
104         */
105        public CampusView() throws IOException {
106                initialize();
107        }
108
109        /**
110         * Initialize the contents of the frame.
111         * @throws IOException 
112         */
113        private void initialize() throws IOException 
114        {
115                contentPanel = new JPanel()
116                {
117//                      private BufferedImage img = ImageIO.read( CampusView.class.getResource( "/sea.jpg" ) );
118            private static final long serialVersionUID = 1L;
119                        @Override
120                        public void paintComponent( Graphics g ) 
121                        {
122//                              setOpaque( false );
123//                              g.drawImage( img, 0, 0, getWidth(), getHeight(), null );
124//                              super.paintComponent( g );
125                        };
126                };
127                contentPanel.setLayout( null );
128                
129                frame = new JFrame();
130                frame.getContentPane().setBackground( Color.black );
131//              frame.setUndecorated(true);
132//              frame.setResizable(false);
133                frame.setBounds(0, 0, 1680, 1050);
134                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
135                frame.getContentPane().setLayout( new BorderLayout() );
136                frame.getContentPane().add( contentPanel );
137                
138                int numCameras = 6;
139                int rowSize = 3;
140                int x = 0; int y = 50;
141                int maxX = 0;
142                for( int i = 0; i < numCameras; i++ )
143                {
144                        CaptureComponent captureComponent = new CaptureComponent();
145                        captureComponent.setTitle("Camera #"+(i+1));
146                        captureComponent.setBounds( x, y, captureComponent.getWidth(), 
147                                        captureComponent.getHeight());
148                        contentPanel.add(captureComponent);
149                        captureComponents.add(captureComponent);
150                        
151                        if( i % rowSize == rowSize-1 )
152                        {
153                                y += captureComponent.getHeight()+40;
154                                x = 0;
155                        }
156                        else    x += captureComponent.getWidth()+30;
157                        
158                        maxX = Math.max( x+captureComponent.getWidth()+30, maxX );
159                }
160                                
161                captureControls = new CaptureControls();
162                captureControls.setBounds(maxX+50, 50, 563, 350);
163                captureControls.setDelegate(this);
164                contentPanel.add(captureControls);
165                
166                gpsComp = new GPSPositionComponent();
167        gpsComp.setBackground( new Color(255,255,255,210) );
168                gpsComp.setBounds( maxX+50,
169                                captureControls.getBounds().y+captureControls.getBounds().height+10,
170                                563,50 );
171                contentPanel.add( gpsComp );
172                
173                compassComp = new CompassComponent();
174        compassComp.setBackground( new Color(255,255,255,210) );
175                compassComp.setBounds( maxX+50,                         
176                                gpsComp.getBounds().y+gpsComp.getBounds().height+10,
177                                563,50 );
178                contentPanel.add( compassComp );
179                
180//              GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
181//        gd.setFullScreenWindow(frame);
182//        frame.setVisible(true);        
183        }
184        
185        @Override
186        public void snapshot() {
187                MBFImage[] images = new MBFImage[captureComponents.size()];
188                
189                for (CaptureComponent cc : captureComponents) {
190                        int id = Integer.parseInt(cc.getTitle().substring(cc.getTitle().indexOf("#")+1)) - 1;
191                        MBFImage f = cc.getCurrentFrame();
192                        if( f != null )
193                                images[id] = f.clone();
194                }
195                
196                // Write all the images
197                for (int i=0; i<images.length; i++) {
198                        try {
199                                if( images[i] != null )
200                                {
201                                        System.out.println( "Writing image "+captureCount+"-"+i );
202                                        
203                                        File captureDir = new File(this.imageDir, ""+captureCount);
204                                        captureDir.mkdirs();
205                                        
206                                        ImageUtilities.write(images[i], new File(captureDir, i+".png"));
207                                }
208                        } catch (IOException e) {
209                                throw new RuntimeException(e);
210                        }
211                }
212                
213                // Get some data together
214                ArrayList<String> dataList = new ArrayList<String>();
215                dataList.add( ""+captureCount );
216                dataList.add( ""+gpsComp.getGPS().getLatitude() );
217                dataList.add( ""+gpsComp.getGPS().getLongitude() );
218                dataList.add( ""+new DateTime() );
219                
220                CompassData c = compassComp.getCompass().getCompassData();
221                if( c != null )
222                {
223                                dataList.add( ""+c.compass );
224                                dataList.add( ""+c.pitch );
225                                dataList.add( ""+c.roll );
226                                dataList.add( ""+c.ax );
227                                dataList.add( ""+c.ay );
228                                dataList.add( ""+c.az );
229                }
230                else    
231                {
232                        dataList.add( "" );
233                        dataList.add( "" );
234                        dataList.add( "" );
235                        dataList.add( "" );
236                        dataList.add( "" );
237                        dataList.add( "" );
238                }
239                
240                dataList.add( "Notes" );
241                
242                // Write the data
243                System.out.println( "Writing CSV File: "+this.imageMetadata );
244                CSVWriter.writeLine( this.imageMetadata, dataList.toArray( new String[0] ) );
245                
246                captureCount++;
247        }
248
249        @Override
250        public void startRecording( int rateSeconds ) 
251        {
252                this.runCapture = true;
253                new Thread( new Runnable()
254                {
255                        @Override
256                        synchronized public void run()
257                        {
258                                while( runCapture )
259                                try
260                {
261                        snapshot();
262                        wait( (int)captureRate*1000 );
263                }
264                catch( InterruptedException e )
265                {
266                        e.printStackTrace();
267                }
268                        }
269                }).start();
270        }
271
272        @Override
273        public void stopRecording() 
274        {
275                this.runCapture = false;
276        }
277
278        @Override
279        public void updateCaptureSettings(int capWidth, int capHeight, double capRate) 
280        {
281                this.captureRate = capRate;
282        }
283
284        @Override
285    public void startBatch( File dir, File md, String capturer, String type )
286    {
287                dir.mkdirs();
288                
289                this.imageDir = new File(dir+File.separator+captureControls.getBatchId());
290                this.imageDir.mkdirs();
291
292                this.imageMetadata = new File(this.imageDir+File.separator+"metadata.csv");
293                
294                this.batchMetadata = new File( dir+File.separator+"batchMetadata.csv" );
295                
296                ArrayList<String> batchData = new ArrayList<String>();
297                batchData.add( ""+captureControls.getBatchId() );
298                batchData.add( capturer );
299                batchData.add( type );
300                
301                CSVWriter.writeLine( this.batchMetadata, batchData.toArray(new String[0]) );
302    }
303
304        @Override
305    public void stopBatch()
306    {
307                captureCount = 0;
308    }
309}