/*
 * 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.demonstrations.calibration;

import boofcv.abst.fiducial.calib.ConfigChessboard;
import boofcv.abst.geo.calibration.CalibrateMonoPlanar;
import boofcv.abst.geo.calibration.CalibrationDetector;
import boofcv.factory.calib.FactoryCalibrationTarget;
import boofcv.gui.VisualizeApp;
import boofcv.gui.calibration.MonoPlanarPanel;
import boofcv.io.MediaManager;
import boofcv.io.ProgressMonitorThread;
import boofcv.io.UtilIO;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.io.wrapper.DefaultMediaManager;
import boofcv.misc.BoofMiscOps;
import boofcv.struct.calib.IntrinsicParameters;
import boofcv.struct.image.GrayF32;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Collections;
import java.util.List;

/**
 * Computes intrinsic camera calibration parameters from a set of calibration images.  Results
 * are displayed in a window allowing their accuracy to be easily seen.
 *
 * @author Peter Abeles
 */
public class CalibrateMonoPlanarGuiApp extends JPanel
		implements VisualizeApp {

	// computes calibration parameters
	CalibrateMonoPlanar calibrator;
	// displays results
	MonoPlanarPanel gui = new MonoPlanarPanel();
	// needed by ProcessThread for displaying its dialog
	JPanel owner;

	List images;
	MediaManager media = DefaultMediaManager.INSTANCE;

	public CalibrateMonoPlanarGuiApp() {
		setLayout(new BorderLayout());
		setPreferredSize(new Dimension(800,525));
		this.owner = this;

		add(gui,BorderLayout.CENTER);
	}

	public void configure( CalibrationDetector detector ,
						   List images  ,
						   int numRadial, boolean includeTangential )
	{
		if( images.size() == 0 )
			throw new IllegalArgumentException("No images!");
		Collections.sort(images);
		calibrator = new CalibrateMonoPlanar(detector);
		calibrator.configure(true,numRadial,includeTangential);
		this.images = images;
	}

	@Override
	public void loadConfigurationFile(String fileName) {
		ParseMonoCalibrationConfig parser = new ParseMonoCalibrationConfig(media);

		if( parser.parse(fileName) ) {
			configure(parser.detector,parser.images,
					parser.numRadial,parser.includeTangential);
		} else {
			System.err.println("Configuration failed");
		}
	}

	public void process( String outputFileName ) {
		calibrator.reset();
		final ProcessThread monitor = new ProcessThread();
		monitor.start();

		for( int i = 0; i < images.size(); i++ ) {
			final File file = new File(images.get(i));
			final BufferedImage orig = media.openImage(images.get(i));
			if( orig != null ) {
				GrayF32 input = ConvertBufferedImage.convertFrom(orig,(GrayF32)null);
				if( calibrator.addImage(input) ) {
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							gui.addImage(file.getName(), orig);
							gui.repaint();
							monitor.setMessage(0, file.getName());
						}
					});
				} else {
					System.out.println("Failed to detect image.  "+file.getName());
				}
			} else {
				System.out.println("Failed to load "+images.get(i));
			}
		}

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				gui.setObservations(calibrator.getObservations());
			}});
		gui.repaint();

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				monitor.setMessage(1,"Estimating Parameters");
			}});

		final IntrinsicParameters param = calibrator.process();
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				gui.setResults(calibrator.getErrors());
				gui.setCalibration(calibrator.getZhangParam());
			}});
		monitor.stopThread();

		if( outputFileName != null )
			UtilIO.saveXML(param, outputFileName);

		// tell it how to undistort the image
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				gui.setCorrection(param);

				gui.repaint();
			}});

		// print the output
		calibrator.printStatistics();
		System.out.println();
		System.out.println("--- Intrinsic Parameters ---");
		System.out.println();
		param.print();
	}

	@Override
	public void setMediaManager(MediaManager manager) {
		media = manager;
	}

	/**
	 * Displays a progress monitor and updates its state periodically
	 */
	public class ProcessThread extends ProgressMonitorThread
	{
		public ProcessThread() {
			super(new ProgressMonitor(owner, "Computing Calibration", "", 0, 2));
		}

		public void setMessage( final int state , final String message ) {
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					monitor.setProgress(state);
					monitor.setNote(message);
				}});
		}

		@Override
		public void doRun() {
		}
	}

	@Override
	public void loadInputData(String fileName) {
		new Thread() {
			public void run() {
				process(null);
			}
		}.start();
	}

	@Override
	public boolean getHasProcessedImage() {
		return true;
	}

	public static void main( String args[] ) {
		CalibrationDetector detector =
//				FactoryCalibrationTarget.detectorSquareGrid(new ConfigSquareGrid(8, 8, 0.5, 7.0 / 18.0));
//				FactoryCalibrationTarget.detectorSquareGrid(new ConfigSquareGrid(4,3,30,30));
				FactoryCalibrationTarget.detectorChessboard(new ConfigChessboard(7, 5, 30));

//		String directory = UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_Square");
//		String directory = UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_Chess");
//		String directory = UtilIO.pathExample("calibration/mono/PULNiX_CCD_6mm_Zhang");
		String directory = UtilIO.pathExample("calibration/stereo/Bumblebee2_Chess");
//		String directory = UtilIO.pathExample("calibration/stereo/Bumblebee2_Square");

		CalibrateMonoPlanarGuiApp app = new CalibrateMonoPlanarGuiApp();
//		app.configure(detector,BoofMiscOps.directoryList(directory, "frame" ),2,false);
		app.configure(detector,BoofMiscOps.directoryList(directory, "left" ),2,false);
//		app.configure(detector,BoofMiscOps.directoryList(directory, "CalibIm" ),2,false);

		JFrame frame = new JFrame("Planar Calibration");
		frame.add(app, BorderLayout.CENTER);
		frame.pack();
		frame.setVisible(true);
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

		app.process("intrinsic.xml");
	}
}

 

Ads help maintain this website.