Example Equirectangular To Pinhole

From BoofCV
Revision as of 13:24, 17 January 2022 by Peter (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Equirectangular images encode a full 360 view inside a rectangular image. This creates a highly distorted view, which can be visually displeasing and can't be processed directly by computer vision algorithms. Part of the view can be rendered inside a synthetic pinhole camera. The synthetic view could then be feed to fiducial detection algorithms, SFM, ... etc. This example shows to generate the synthetic pinhole camera view at an arbtirary orientation and intrinsic parameters.

Example File: ExampleEquirectangularToPinhole.java

Concepts:

  • Spherical View
  • Pinhole Camera

Related Examples:

Videos:

Example Code

/**
 * Demonstration for how to project a synthetic pinhole camera view given an equirectangular image. To
 * specify the projection the camera model needs to be configured and the orientation of the view needs to bet set.
 *
 * @author Peter Abeles
 */
public class ExampleEquirectangularToPinhole {
	public static void main( String[] args ) {

		// Specify what the pinhole camera should look like
		CameraPinhole pinholeModel = new CameraPinhole(200, 200, 0, 250, 250, 500, 500);

		// Load equirectangular RGB image
		BufferedImage bufferedEqui =
				UtilImageIO.loadImageNotNull(UtilIO.pathExample("spherical/equirectangular_half_dome_01.jpg"));
		Planar<GrayU8> equiImage =
				ConvertBufferedImage.convertFrom(bufferedEqui, true, ImageType.pl(3, GrayU8.class));

		// Declare storage for pinhole camera image
		Planar<GrayU8> pinholeImage = equiImage.createNew(pinholeModel.width, pinholeModel.height);

		// Create the image distorter which will render the image
		InterpolatePixel<Planar<GrayU8>> interp = FactoryInterpolation.
				createPixel(0, 255, InterpolationType.BILINEAR, BorderType.EXTENDED, equiImage.getImageType());
		ImageDistort<Planar<GrayU8>, Planar<GrayU8>> distorter =
				FactoryDistort.distort(false, interp, equiImage.getImageType());

		// This is where the magic is done. It defines the transform rfom equirectangular to pinhole
		CameraToEquirectangular_F32 pinholeToEqui = new CameraToEquirectangular_F32();
		pinholeToEqui.setEquirectangularShape(equiImage.width, equiImage.height);
		pinholeToEqui.setCameraModel(pinholeModel);

		// Pass in the transform to the image distorter
		distorter.setModel(pinholeToEqui);

		// change the orientation of the camera to make the view better
		ConvertRotation3D_F32.eulerToMatrix(EulerType.YXZ, 0, 1.45f, 2.2f, pinholeToEqui.getRotation());

		// Render the image
		distorter.apply(equiImage, pinholeImage);
		BufferedImage bufferedPinhole0 = ConvertBufferedImage.convertTo(pinholeImage, null, true);

		// Let's look at another view
		ConvertRotation3D_F32.eulerToMatrix(EulerType.YXZ, 0, 1.25f, -1.25f, pinholeToEqui.getRotation());

		distorter.apply(equiImage, pinholeImage);
		BufferedImage bufferedPinhole1 = ConvertBufferedImage.convertTo(pinholeImage, null, true);

		// Display the results
		ListDisplayPanel panel = new ListDisplayPanel();
		panel.addImage(bufferedPinhole0, "Pinehole View 0");
		panel.addImage(bufferedPinhole1, "Pinehole View 1");
		panel.addImage(bufferedEqui, "Equirectangular");
		panel.setPreferredSize(new Dimension(equiImage.width, equiImage.height));

		ShowImages.showWindow(panel, "Equirectangular to Pinhole", true);
	}
}