All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.gui.image.ProcessImageSequence Maven / Gradle / Ivy

/*
 * Copyright (c) 2011-2020, 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.misc.BoofMiscOps;
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> implements MouseListener, KeyListener {
	private SimpleImageSequence 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;

	protected ProcessImageSequence( SimpleImageSequence 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.
	 */
	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;
				}
				BoofMiscOps.sleep(5);
			}

//            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 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 mousePressed( MouseEvent e ) {}
	@Override public void mouseReleased( MouseEvent e ) {}
	@Override public void mouseEntered( MouseEvent e ) {}
	@Override public void mouseExited( MouseEvent e ) {}
	@Override public void keyPressed( KeyEvent e ) {}
	@Override public void keyReleased( KeyEvent e ) {}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy