How to align rotated images vertically
Using Radon
instead of ImageLines@EdgeDetect@
. No need for thinning the lines.
i = ImageAdjust@Import@"http://i.stack.imgur.com/rRCH5.png";
cc = ComponentMeasurements[MaxDetect[r = Radon@i, .1], "Centroid"];
angle = -cc[[All, 2, 1]] Pi/First@ImageDimensions@r// Mean;
ImageAdjust@ImageRotate[i, angle, Background -> Black]
The 0.1
in MaxDetect[r = Radon@i, .1]
is empirical, but I found it working very well when using Radon[ ]
. Otherwise you may find FindThreshold[ ]
useful for estimating an ad hoc value.
Showing the alignment:
horline[i_Image, row_] := Graphics[{Orange, Thick,
Line[{{0, row}, {Last@ImageDimensions@i, row}}]}]
With[{j = ImageAdjust@ImageRotate[i, angle, Background -> Black]},
Show[j, horline[j, #] & /@ cc[[All, 2, 2]]]]
I don't know about the generality of this method, but you seem to already have a general method. This works on the image you provided, and is adapted from the code you posted,
img = Import["http://i.stack.imgur.com/rRCH5.png"];
ImageRotate[img, -ArcTan @@
Flatten@(Differences /@
Transpose[
First@ImageLines[EdgeDetect@img,
MaxFeatures -> 1]]), "MaxAreaCropping"]
Essentially you just need to find one line using ImageLines
and then find the angle it makes with the horizontal, then rotate it through the reverse of that angle.
Another maybe interesting method strike on me with PrincipalComponents
:
img = Import["http://i.stack.imgur.com/rRCH5.png"];
inipos = Position[
ImageData@
Image@First@Values@ComponentMeasurements[Binarize[img], "Mask"],
1., {2}];
mat = FindGeometricTransform[PrincipalComponents[N@inipos],
inipos][[2]];
ImageRotate@ImageTransformation[img, mat, PlotRange -> All]