Difference between revisions of "Example Remove Perspective Distortion"

From BoofCV
Jump to navigationJump to search
(Created page with "<center> <gallery widths=240px heights=320px> file:Example_remove_perspective_input.jpg | Input file where the billboard is experiencing heavy perspective distortion. file:Exa...")
 
m
 
(8 intermediate revisions by the same user not shown)
Line 9: Line 9:


Example Code:
Example Code:
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.16/examples/src/boofcv/examples/imageprocessing/ExampleRemovePerspectiveDistortion.java ExampleRemovePerspectiveDistortion.java]
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.40/examples/src/main/java/boofcv/examples/geometry/ExampleRemovePerspectiveDistortion.java ExampleRemovePerspectiveDistortion.java]


Concepts:
Concepts:
* Homography
* Homography
* Perpsective
* Perspective
* Distortion
* Distortion


Line 24: Line 24:
/**
/**
  * Certain image processing techniques, such as Optical Character Recognition (OCR), can be performed better if
  * Certain image processing techniques, such as Optical Character Recognition (OCR), can be performed better if
  * perspective distortion is remove from an image. In this example a homography is computed from the cour corners
  * perspective distortion is remove from an image. In this example a homography is computed from the four corners
  * of a bulletin board and the image is projected into a square image without perspective distortion.
  * of a bulletin board and the image is projected into a square image without perspective distortion. The
* {@link RemovePerspectiveDistortion} class is used to perform the distortion. The class is easy to understand
* if you know what a homography is, you should look at it!
  *
  *
  * @author Peter Abeles
  * @author Peter Abeles
  */
  */
public class ExampleRemovePerspectiveDistortion {
public class ExampleRemovePerspectiveDistortion {
public static void main(String[] args) {
public static void main( String[] args ) {
 
// load a color image
// load a color image
BufferedImage buffered = UtilImageIO.loadImage("../data/applet/goals_and_stuff.jpg");
BufferedImage buffered = UtilImageIO.loadImageNotNull(UtilIO.pathExample("goals_and_stuff.jpg"));
MultiSpectral<ImageFloat32> input = ConvertBufferedImage.convertFromMulti(buffered, null, true, ImageFloat32.class);
Planar<GrayF32> input = ConvertBufferedImage.convertFromPlanar(buffered, null, true, GrayF32.class);
 
// Create a smaller output image for processing later on
MultiSpectral<ImageFloat32> output = input._createNew(400,500);
 
// Homography estimation algorithm.  Requires a minimum of 4 points
Estimate1ofEpipolar computeHomography = FactoryMultiView.computeHomography(true);
 
// Specify the pixel coordinates from destination to target
ArrayList<AssociatedPair> associatedPairs = new ArrayList<AssociatedPair>();
associatedPairs.add(new AssociatedPair(new Point2D_F64(0,0),new Point2D_F64(267,182)));
associatedPairs.add(new AssociatedPair(new Point2D_F64(output.width-1,0),new Point2D_F64(542,68)));
associatedPairs.add(new AssociatedPair(new Point2D_F64(output.width-1,output.height-1),new Point2D_F64(519,736)));
associatedPairs.add(new AssociatedPair(new Point2D_F64(0,output.height-1),new Point2D_F64(276,570)));


// Compute the homography
RemovePerspectiveDistortion<Planar<GrayF32>> removePerspective =
DenseMatrix64F H = new DenseMatrix64F(3,3);
new RemovePerspectiveDistortion<>(400, 500, ImageType.pl(3, GrayF32.class));
computeHomography.process(associatedPairs, H);


// Create the transform for distorting the image
// Specify the corners in the input image of the region.
PointTransformHomography_F32 homography = new PointTransformHomography_F32(H);
// Order matters! top-left, top-right, bottom-right, bottom-left
PixelTransform_F32 pixelTransform = new PointToPixelTransform_F32(homography);
if (!removePerspective.apply(input,
new Point2D_F64(267, 182), new Point2D_F64(542, 68),
new Point2D_F64(519, 736), new Point2D_F64(276, 570))) {
throw new RuntimeException("Failed!?!?");
}


// Apply distortion and show the results
Planar<GrayF32> output = removePerspective.getOutput();
DistortImageOps.distortMS(input,output,pixelTransform,true, TypeInterpolate.BILINEAR);


BufferedImage flat = ConvertBufferedImage.convertTo_F32(output,null,true);
BufferedImage flat = ConvertBufferedImage.convertTo_F32(output, null, true);
ShowImages.showWindow(buffered,"Original Image");
ShowImages.showWindow(buffered, "Original Image", true);
ShowImages.showWindow(flat,"Without Perspective Distortion");
ShowImages.showWindow(flat, "Without Perspective Distortion", true);
}
}
}
}
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 14:56, 17 January 2022

It is often easier to process an image after perspective distortion is removed. The billboard in this example is at an acute angle relative to the camera, making its text hard to read. A homography can be created, using the for cornerns of the billboard, and used to remove this distortion.

Example Code:

Concepts:

  • Homography
  • Perspective
  • Distortion

Relevant Examples:

Example Code

/**
 * Certain image processing techniques, such as Optical Character Recognition (OCR), can be performed better if
 * perspective distortion is remove from an image. In this example a homography is computed from the four corners
 * of a bulletin board and the image is projected into a square image without perspective distortion. The
 * {@link RemovePerspectiveDistortion} class is used to perform the distortion. The class is easy to understand
 * if you know what a homography is, you should look at it!
 *
 * @author Peter Abeles
 */
public class ExampleRemovePerspectiveDistortion {
	public static void main( String[] args ) {
		// load a color image
		BufferedImage buffered = UtilImageIO.loadImageNotNull(UtilIO.pathExample("goals_and_stuff.jpg"));
		Planar<GrayF32> input = ConvertBufferedImage.convertFromPlanar(buffered, null, true, GrayF32.class);

		RemovePerspectiveDistortion<Planar<GrayF32>> removePerspective =
				new RemovePerspectiveDistortion<>(400, 500, ImageType.pl(3, GrayF32.class));

		// Specify the corners in the input image of the region.
		// Order matters! top-left, top-right, bottom-right, bottom-left
		if (!removePerspective.apply(input,
				new Point2D_F64(267, 182), new Point2D_F64(542, 68),
				new Point2D_F64(519, 736), new Point2D_F64(276, 570))) {
			throw new RuntimeException("Failed!?!?");
		}

		Planar<GrayF32> output = removePerspective.getOutput();

		BufferedImage flat = ConvertBufferedImage.convertTo_F32(output, null, true);
		ShowImages.showWindow(buffered, "Original Image", true);
		ShowImages.showWindow(flat, "Without Perspective Distortion", true);
	}
}