SkewCorrector implements ImageProcessor<FImage> { @Override public void processImage( FImage image) { CannyEdgeDetector2 cad = new CannyEdgeDetector2(); FImage edgeImage = image.process(cad).inverse(); HoughLines hl = new HoughLines( 360*accuracy ); edgeImage.analyseWith( hl ); if( DEBUG ) debugLines( edgeImage, Matrix.identity(3,3), "Detection of Horizontal Lines", hl.getBestLines(2) ); double rotationAngle = hl.calculatePrevailingAngle(); FImage rotImg = null; FImage outImg = null; if( rotationAngle == Double.MIN_VALUE ) { System.out.println( "WARNING: Detection of rotation angle failed."); rotImg = edgeImage.clone(); outImg = image.clone(); } else { rotationAngle -= 90; rotationAngle %= 360; if( DEBUG ) System.out.println( "Rotational angle: "+rotationAngle ); rotationAngle *= 0.0174532925 ; Matrix rotationMatrix = new Matrix( new double[][] { {Math.cos(-rotationAngle), -Math.sin(-rotationAngle), 0}, {Math.sin(-rotationAngle), Math.cos(-rotationAngle), 0}, {0,0,1} }); rotImg = ProjectionProcessor.project( edgeImage, rotationMatrix, 1f ). process( new OtsuThreshold() ); outImg = ProjectionProcessor.project( image, rotationMatrix, 0f ); } if( DEBUG ) DisplayUtilities.display( outImg, "Rotated Image" ); rotImg.analyseWith( hl ); float shearAngleRange = 20; if( DEBUG ) debugLines( rotImg, Matrix.identity(3,3), "Detection of Vertical Lines", hl.getBestLines(2,-shearAngleRange,shearAngleRange) ); double shearAngle = hl.calculatePrevailingAngle( -shearAngleRange,shearAngleRange ); if( shearAngle == Double.MIN_VALUE ) { System.out.println( "WARNING: Detection of shear angle failed."); } else { shearAngle %= 360; if( DEBUG ) System.out.println( "Shear angle = "+shearAngle ); shearAngle *= 0.0174532925 ; Matrix shearMatrix = new Matrix( new double[][] { {1, Math.tan( shearAngle ), 0}, {0,1,0}, {0,0,1} }); outImg = outImg.transform( shearMatrix ); } if( DEBUG ) DisplayUtilities.display( outImg, "Final Image" ); image.internalAssign( outImg ); }  @Override void processImage( FImage image); void setAccuracy( int accuracy );  }
@Test public void testSkewCorrector() { try { FImage testImage = ImageUtilities.readF( getClass().getResource("italic--20.png") ).normalise(); SkewCorrector sc = new SkewCorrector(); sc.processImage( testImage ); } catch( IOException e ) { e.printStackTrace(); } }