001/*******************************************************************************
002 * Permission to use and distribute this software is granted under the BSD 2-Clause
003 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause).
004 * Copyright (c) 2016-2023 Wilhelm Burger. All rights reserved.
005 * Visit https://imagingbook.com for additional details.
006 ******************************************************************************/
007package Calibration_Plugins_2;
008
009import ij.IJ;
010import ij.ImagePlus;
011import ij.ImageStack;
012import ij.plugin.PlugIn;
013import ij.process.ImageProcessor;
014import imagingbook.calibration.zhang.Camera;
015import imagingbook.calibration.zhang.RectificationMapping;
016import imagingbook.calibration.zhang.data.CalibrationImage;
017import imagingbook.calibration.zhang.data.ZhangData;
018import imagingbook.common.geometry.mappings.Mapping2D;
019import imagingbook.common.image.ImageMapper;
020import imagingbook.common.image.interpolation.InterpolationMethod;
021import imagingbook.core.jdoc.JavaDocHelp;
022import imagingbook.core.resource.ImageResource;
023
024/**
025 * This plugin opens an image stack containing the 5 Zhang test images and removes the lens distortion based on the
026 * intrinsic camera parameters estimated by calibration. The resulting (rectified) frames are shown in a new image
027 * stack. Note that this plugin uses pre-calculated camera parameters, i.e., no calibration is performed.
028 *
029 * @author W. Burger
030 * @version 2022/12/19
031 */
032public class Rectify_Camera_Demo implements PlugIn, JavaDocHelp {
033
034        private static ImageResource resource = CalibrationImage.CalibImageStack;
035
036        public void run(String arg0) {
037                // open the test image (stack):
038                ImagePlus testIm = resource.getImagePlus();
039
040                if (testIm == null) {
041                        IJ.error("Could not open calibration images!");
042                        return;
043                }
044                testIm.show();
045                String title = testIm.getShortTitle();
046
047                // get pre-calculated camera intrinsics (typically by calibration):
048                Camera camera = ZhangData.getCameraIntrinsics();
049
050                // create a special geometric mapping
051                Mapping2D mapping = new RectificationMapping(camera);   // inverse, ie., maps target to source
052
053                // get the original (distorted) image stack:
054                ImageStack distStack = testIm.getStack();
055                final int w = distStack.getWidth();
056                final int h = distStack.getHeight();
057                final int M = distStack.getSize();
058
059                // create a new stack for the rectified images:
060                ImageStack rectStack = new ImageStack(w, h);
061                for (int i = 0; i < M; i++) {
062                        ImageProcessor source = distStack.getProcessor(i + 1);
063                        ImageProcessor target = source.createProcessor(w, h);
064                        ImageMapper mapper = new ImageMapper(mapping, null, InterpolationMethod.Bicubic);
065                        mapper.map(source, target);
066                        String label = distStack.getSliceLabel(i + 1);
067                        rectStack.addSlice(label, target);
068                }
069                // display the new stack:
070                new ImagePlus(title + " (rectified)", rectStack).show();
071        }
072
073}