/* * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package boofcv.gui.image; import boofcv.io.image.SimpleImageSequence; import boofcv.io.image.UtilImageIO; import boofcv.struct.image.ImageGray; import javax.swing.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; /** * An abstract class that takes case of basic GUI and loading of images when processing a sequence. * * @author Peter Abeles */ public abstract class ProcessImageSequence<T extends ImageGray> implements MouseListener, KeyListener { private SimpleImageSequence<T> sequence; private T image; private volatile boolean paused; private volatile boolean step; protected int imgWidth; protected int imgHeight; // how many images have been saved protected int savedIndex; public ProcessImageSequence(SimpleImageSequence<T> sequence) { this.sequence = sequence; if (sequence.hasNext()) image = sequence.next(); else throw new IllegalArgumentException("Image sequence must have at least one image in it."); this.imgWidth = image.getWidth(); this.imgHeight = image.getHeight(); System.out.println("Input Image size = " + imgWidth + " " + imgHeight); System.out.println(); } /** * If a component is added here then keyboard and mouse events will be used to control the * image processing. * * @param comp */ public void addComponent(JComponent comp) { comp.addMouseListener(this); comp.addKeyListener(this); } public void process() { long totalTime = 0; int numFrames = 0; paused = false; step = false; long startNano = System.nanoTime(); while (true) { long before = System.nanoTime(); processFrame(image); long after = System.nanoTime(); // don't compute time statistics on the first frame since it seems to // often be much slower if (numFrames > 0) { totalTime += after - before; printFPS(totalTime, numFrames, startNano); } else { System.out.println("First frame processed."); } numFrames++; updateGUI((BufferedImage)sequence.getGuiImage(), image); while (paused) { if (step) { step = false; break; } Thread.yield(); } // if( stabilizer.getKeyFrameChanged() && numFrames > 2 ) { //// if( numFrames > 80 ) { // try { // Thread.sleep(200000); // } catch (InterruptedException e) { // throw new RuntimeException(e); // } // } if (sequence.hasNext()) { image = sequence.next(); } else { break; } } finishedSequence(); printFPS(totalTime, numFrames, startNano); sequence.close(); } private void printFPS(long totalTime, int numFrames, long startNano) { double seconds = totalTime / 1e9; double allSeconds = (System.nanoTime() - startNano) / 1e9; double fps = numFrames / seconds; double tfps = numFrames / allSeconds; System.out.printf("Frame # = %5d FPS = %6.2f TFPS = %6.2f ET = %7.1f\n", numFrames, fps, tfps, allSeconds); } public abstract void processFrame(T image); public abstract void updateGUI(BufferedImage guiImage, T origImage); /** * Called after all the frames in the sequence have been processed. */ public void finishedSequence(){} @Override public void mouseClicked(MouseEvent e) { // thsi is needed so that key events are processed if (e.getSource() instanceof JComponent) { JComponent jc = (JComponent) e.getSource(); jc.requestFocusInWindow(); } paused = !paused; System.out.println("Pause = " + paused); } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() == 'p') { paused = false; } else if (e.getKeyChar() == 's') { System.out.println("Saving image"); String name = String.format("image%05d.jpg", savedIndex++); UtilImageIO.saveImage(image, name); } else { paused = true; step = true; } } @Override public void keyPressed(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } }