views:

599

answers:

2

Hi,

i wonder if you guys know a solution (in matlab) to my problem:

I have a intensity/greyscale image and i have choosen a pixel inside this image. Now want to send vectors starting from this pixel in all directions/angles and i want to sum up all the intensities of the pixels touching one vector, for all vectors. After this step i would like to plot a histogram with the intensities on one axis and the angle on the other axis. I think i can to the last step on my own, but i don't know how to create these vectors inside my greyscale image and how to get the coordinates of the pixels a vector touches.

I did this in c++, which required a lot of code and i am sure this can be done with less effort in matlab, but i am quiet new to matlab so any help would be appreciated since i haven't found anything in the documentation.

+2  A: 

It might not be the best way to solve it, but you can do it using a bit of algebra, heres how...
We know the Point-Slope formula of a line passing through point (a,b) with angle theta is:

y = tan(theta) * (x-a) + b

Therefore a simple idea is to compute the intersection of this line with y=const for all const, and read the intensity values at the intersection. You would repeat this for all angles...
A sample code to illustrate the concept:

%% input
point = [128 128];               % pixel location
I = imread('cameraman.tif');     % sample grayscale image

%% calculations
[r c] = size(I);
angles = linspace(0, 2*pi, 4) + rand;
angles(end) = [];
clr = lines( length(angles) );   % get some colors

figure(1), imshow(I), hold on
figure(2), hold on

for i=1:length(angles)
    % line equation
    f = @(x) tan(angles(i))*(x-point(1)) + point(2);

    % get intensities along line
    x = 1:c;
    y = round(f(x));
    idx = ( y<1 | y>r );  % indices of outside intersections
    vals = diag(I(x(~idx), y(~idx)));

    figure(1), plot(x, y, 'Color', clr(i,:)) % plot line
    figure(2), plot(vals, 'Color', clr(i,:)) % plot profile
end
hold off
Amro
Hi Amro! I wrote something very similar yesterday night, using the "bresenham algorithm" instead of rounding ( y=round(f(x)) ). Thanks to your code i found the error in my code. Thanks a lot!!
zhengtonic
Indeed, rounding was just a quick fix.. You could improve this "probing" technique by interpolating intensity values along the line
Amro
+2  A: 

This example will be similar to Amro's, but it is a slightly different implementation that should work for an arbitrary coordinate system assigned to the image...

Let's assume that you have matrices of regularly-spaced x and y coordinates that are the same size as your image, such that the coordinates of pixel (i,j) are given by (x(i,j),y(i,j)). As an example, I'll create a sample 5-by-5 set of integer coordinates using MESHGRID:

>> [xGrid,yGrid] = meshgrid(1:5)

xGrid =

     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5

yGrid =

     1     1     1     1     1
     2     2     2     2     2
     3     3     3     3     3
     4     4     4     4     4
     5     5     5     5     5

Next we can define a line y = m*(x - a) + b passing through the coordinate system by selecting some values for the constants and computing y using the x coordinates of the grid:

>> a = 0;
>> b = 1;
>> m = rand

m =

    0.5469

>> y = m.*(xGrid(1,:)-a)+b

y =

    1.5469    2.0938    2.6406    3.1875    3.7344

Finally, we find the y points in the grid that differ from the points computed above by less than the grid size:

>> index = abs(yGrid-repmat(y,size(yGrid,1),1)) <= yGrid(2,1)-yGrid(1,1)

index =

     1     0     0     0     0
     1     1     1     0     0
     0     1     1     1     1
     0     0     0     1     1
     0     0     0     0     0

and use this index matrix to get the x and y coordinates for the pixels crossed by the line:

>> xCrossed = xGrid(index);
>> yCrossed = yGrid(index);
gnovice