How to plot the radial profile of a 2D image

My goal is to plot the image values (interpolated but not averaged) along an arbitrary diameter (arbitrary azimuth angle). I have attached my attempt to do that but it only works for 1/2 the diameter and only for square (nxn) images. Furthermore, it fails on some test images, even if represented by a squared array, printing the following error that I cannot interpret:
>> sampled_radial_slice = interp2(X,Y,img,x,y); Error using griddedInterpolant Sample values must be a single or double array. Error in interp2>makegriddedinterp (line 228) F = griddedInterpolant(varargin{:}); Error in interp2 (line 136) F = makegriddedinterp(X, Y, V, method,extrap);
I would like to extend this script to rectangular 2D images and to plot the profile along a diameter not just a radius for arbitrary azimuthal angle. The diameter should pass through the image center. Any suggestion and helpis welcome. Thank you in advance. maura

Réponses (4)

Image Analyst
Image Analyst le 31 Mar 2016
Modifié(e) : Image Analyst le 25 Jan 2019

1 vote

See attached demo to get the average radial profile.

8 commentaires

I would like someone to explain to me:
1. Matlab pixel indices convention. That is growing direction of row index and growing direction of column index
2. How to convert cartesian coordinates, centered in the image center, to pixel coordinates
Thank you in advance. maura.monville@gmail.com
arnold
arnold le 25 Jan 2019
Is there any elegant way to to the inversion of this?
I have a profile vector and want to generate a radially symmetrical distribution which follows this profile.
Image Analyst
Image Analyst le 25 Jan 2019
I've done that. It's different than what this Answer is answering, which is to start with an image and get the profile. You're starting with a profile vector and wanting to generate the image. It's very easy. Just have a 2-d nested for loop and compute the radius for every pixel, then pluck that value out from your profile vector at the index that corresponds to that radius. Trivial. If you can't figure it out, start a new question and attach your profile vector in a .mat file.
arnold
arnold le 26 Jan 2019
Modifié(e) : arnold le 26 Jan 2019
thanks. Yeah, that's the obvious approach with a loop over rows and columns and it works of course. The result is rather coarse though, because it is binned to integer pixel positions, I'm lacking the proper formal terms here. I should have elaborated more what I meant with 'more elegant'.
I've been looking for a solution which does this less coarsely, with subpixel accuracy, so to speak. I've applied blurring or anti-aliasing which works but isn't really 'accurate'. Calculating new pixel values for non orthogonal pixels and/or in case I want to center the 'rotational profile' not exactly at the origin of one pixel but give it a non-integer position. All I can think of now is interpolating the profile to then be able to set any pixel with a 'more accurate' profile-value at its center.
Image Analyst
Image Analyst le 28 Jan 2019
Of course locations have to be digitized into integer locations if you want an array because computers are digital. If you want more accuracy you can simply have a larger matrix. Why not make it a million by a million?
Everything in computers is quantized. If you don't want a digital image, then you can just have a formula and get the value for that one particular floating point location. But of course, the result will also be quantized. There is no way around it with digital computers.
arnold
arnold le 29 Jan 2019
obviously.
thanks for your input. Maybe I'll find something by mself, maybe an AA filter is applicable or some kind of oversampling ;-)
Image Analyst
Image Analyst le 29 Jan 2019
Yes, you can oversample like I, and you, said. In other words, just have a larger matrix and you'll have a lot more samples and higher precision.
alic rou
alic rou le 14 Juil 2020
Modifié(e) : alic rou le 14 Juil 2020
Worked great for me. Thank you.

Connectez-vous pour commenter.

The proposed function seems very complicated to me. Here is my version :
function profile = radialAverage(IMG, cx, cy, w)
% computes the radial average of the image IMG around the cx,cy point
% w is the vector of radii starting from zero
[a,b] = size(IMG);
[X, Y] = meshgrid( (1:a)-cx, (1:b)-cy);
R = sqrt(X.^2 + Y.^2);
profile = [];
for i = w % radius of the circle
mask = (i-1<R & R<i+1); % smooth 1 px around the radius
values = (1-abs(R(mask)-i)) .* double(IMG(mask)); % smooth based on distance to ring
% values = IMG(mask); % without smooth
profile(end+1) = mean( values(:) );
end
end
Maura Monville
Maura Monville le 5 Avr 2016

0 votes

I would like someone to explain to me:
1. Matlab pixel indices convention. That is growing direction of row index and growing direction of column index
2. How to convert cartesian coordinates, centered in the image center, to pixel coordinates
Thank you in advance. maura.monville@gmail.com

2 commentaires

1. When linear indexing, it goes down rows first, then over column-by-column.
2. The left and top pixels are 1. The middle would be (columns/2, rows/2). To get from the middle of the picture to pixel coordinates, you need to add half the width or height in pixels, taking special care for whether the dimension has an odd or even number of pixels in that direction.
Thank you so much. maura

Connectez-vous pour commenter.

Sergey Loginov
Sergey Loginov le 5 Nov 2021

0 votes

Accumarray function allows to build both radial profiler (like this one: https://www.mathworks.com/matlabcentral/fileexchange/101480-very-fast-radial-profile) or an azimutal profiler as well.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by