I have recorded images of a calibration target which I use to determine the resolution of a camera. For that I measure the distance of the parallel bright bars by measuring the brightness variation along the center of the bars perpendicular to their long side. The thickness of the bars is given.
Usually I am not able to align the target exactly in vertical direction.
An example image is given here:
To turn the image into the vertical direction I used a code developed by Markus van Almsick.
Do you know another alternative solution for doing such an alignment automatically?
VerticalAlignment[img_Image] :=
Module[
{contours = ImageAdjust@GradientFilter[img, 1],
dims = ImageDimensions[img], lines, intersections, phis},
lines =
Map[(# - dims/2) &, ImageLines[contours, MaxFeatures -> 12], {-2}];
intersections = Apply[
Replace[
RegionIntersection[InfiniteLine[#1], InfiniteLine[#2]],
{Point[vec : {_, _}] :> ToPolarCoordinates[vec],
EmptyRegion[2] :> {\[Infinity], ArcTan @@ Subtract @@ #1}}
] &,
Subsets[lines, {2}],
{1}
];
phis = Select[
Cases[intersections, {_?(# > Norm[dims] &), phi_} :>
Mod[phi, Pi]], (Pi/3 < # < 2 Pi/3) &];
If[
phis == {},
img,
ImageRotate[img, Pi/2 - Median[phis], "MaxAreaCropping"]
]
]
VerticalAlignment[image]
gives for the upper example:
Now I can do the following (mentioned in the beginning):
ListLinePlot[data[[All, 58, 1]], ImageSize -> Medium]
and determine the peak positions and their distances.
Answer
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]]]]
Comments
Post a Comment