UPDATE to the question
I have reformulated the question in order to make it distinct from the one suggested as a duplicate: "Line Intensity Profile From Image." The key difference is that I'm interested in obtaining a pixel profile where the PixelValue
s are placed according to their distances from the ends of the Line
and no interpolation of PixelValue
s is allowed. The referenced thread does not contain a suitable solution and does not imply these restrictions.
The basic question
I find quite interesting this recent question on the Wolfram Community for which I wish to find a more efficient and general solution than the one I have at the moment.
The general problem: having a raster Image
what is an efficient way to find the PixelValues
profile along a straight Line
(of thickness 1 pixel) defined by two points in the standard coordinate system of the image? My current approach requires creation of a rasterized version of a Graphics
object containing Line
what is very inefficient when the original image is large. Probably the best approach to the problem would be to implement an algorithm which allows to generate pixel positions in the original image along the Line
without using the FrontEnd.
The following is my inefficient solution via Rasterize
:
img = Import["https://i.sstatic.net/Tc8hR.png"]
Here we find the variation of brightness along the radial profile defined via angle α
.
α = Pi/10;
id = ImageDimensions[img];
pr = {0, #} & /@ id;
center = Round[Mean /@ pr];
gr = Graphics[{White, AbsoluteThickness[1],
Line[{center, AngleVector[center, {Norm[id], α}]}]}, Background -> Black,
PlotRangePadding -> None, ImageSize -> id, PlotRange -> pr, AspectRatio -> Automatic];
mask = Binarize@Rasterize[Style[gr, Antialiasing -> False], "Image"];
radialProfile =
PixelValue[img, SortBy[PixelValuePositions[mask, 1], N@EuclideanDistance[center, #] &]];
Length@radialProfile
Row[{ListLinePlot[radialProfile, ImageSize -> Medium],
Show[img, gr /. White -> Red, ImageSize -> Small]}]
502