How to get the values of a circle of pixels on an image? - matlab

I'm currently using MatLab as part of a Digital Imaging course and trying to get the values of a circle of pixels on an image. The idea is to start with a central pixel (x, y) and then collect all of the pixels with the radius r and return their values.
So far, all I've managed to create is this (where A_grey is an image):
function [localMean] = getLocalMean(x, y, radius)
for x = 1:size(A_grey, 1)
for y = 1:size(A_grey, 2)
<code>
end
end
But I'm not entirely sure what I'm doing and I could really do with some beginner level advice here. Any tips?

I'll throw you a bone. This is actually quite easy. Given the size of the image / viewing window, stored in width and height that you want to examine, generate a meshgrid of points, then search for those (x,y) values that satisfy the equation of the circle. In other words, you want to search for all (x,y) values given a centre of your circle (x0,y0) such that:
(x - x0)^2 + (y - y0)^2 = r^2
r is the radius of your desired circle. As such, it's as simple as:
[x,y] = meshgrid(1:width, 1:height);
p = (x - x0).^2 + (y - y0).^2 == r^2;
pts = [x(p) y(p)];
We first generate a meshgrid of points. Think of a meshgrid as a set of 2D arrays where each unique spatial location in the same spot of these arrays gives you the x and y coordinates at that spatial location in 2D. Take a look at the following example:
[x,y] = meshgrid(1:3, 1:3)
x =
1 2 3
1 2 3
1 2 3
y =
1 1 1
2 2 2
3 3 3
In terms of pixel coordinates, the top-left corner is (x,y) = (1,1). The top right corner is (x,y) = (3,1) and so on. Note that the convention is that x is horizontal while y is vertical, as what most digital image processing literature will give you. If this is not what you want, replace meshgrid with ndgrid to respect the row/column convention.
Once we generate this grid of points, we simply put this through our circle equation and see which values of (x,y) at a given centre (x0,y0) satisfy the equation of the circle. Once we find such locations, we simply index into our meshgrid of points and return those (x,y) values, corresponding to those points that lie along the perimeter of your circle.

Related

How to Find the 4 furthest points of this rectangle

I have plotted a list of corners I've obtained using Harris Corner detection.
Now I need to find the 4 furthers points that will represent the corners of the rectangle
I know I can get the two top and bottom diagonal corners using
max(C);
min(C);
Where C is an n row matrix with a column for x and y like
x y
0 1
2 3
4 5
6 6
But how do I get the other two corners?
I thought I could rotate the matrix and use min and max again, but of course that just returns me a huge n column matrix (and I want a 2 column matrix)
I feel like the answer is obvious, but I'm blanking :(
i don't know how limited is the following method but it worked for an example similar to yours:
% detect possible corners
points = detectHarrisFeatures(BW);
C = points.Location;
% compute par-wise distances between all points
D = pdist2(C,C);
p = zeros(1,4);
% compute maximum distance to find first pair
[m,idx1] = max(D,[],2);
[~,idx2] = max(m);
idx1 = idx1(idx2);
p(1:2) = [idx1, idx2];
% add first pair distance to distance matrix so the next pair will be
% distant from this pair as well, and compute max distance again
D = bsxfun(#plus,D,sum(D([idx1 idx2],:),1));
[m,idx1] = max(D,[],2);
[~,idx2] = max(m);
idx1 = idx1(idx2);
p(3:4) = [idx1, idx2];
% plot
imshow(BW);
hold on;
plot(C(:,1),C(:,2),'g.');
plot(C(p,1),C(p,2),'rx','LineWidth',2);
another option is to use FEX functions like Polygon simplification and Decimate Polygon, and to set the number of desired vertexes to 4.
Another alternative solution, if you dont want to use corner detection:
im=zeros(100);
im(40:70,30:80)=1;
im=imrotate(im,rand*100);
[x,y]=find(im);
x=x+2*randn(size(x));
y=y+2*randn(size(y));
X=[x(:),y(:)];
d=ceil(pdist2(X,X)*10)/10;
[a,b]=find(d==max(d(:)));
xm=x(a);
ym=y(a);
figure,plot(x,y,'ks')
hold on, plot(xm,ym,'ro','MarkerSize',12,'MArkerFaceColor','r')
axis image

How to generate random positions with distance between them?

Assume that I have a vector with 6 distance elements as
D = [10.5 44.8 30.01 37.2 23.4 49.1].
I'm trying to create random pair positions of a given distances, inside a 200 meters circle. Note that the distance D created by using (b - a).*rand(6,1) + a, with a = 10 and b = 50 in Matlab. I do not know how to generate the random pairs with given the distances.
Could anybody help me in generating this kind of scenario?
This is an improvement to Alessiox's answer. It follows same logic, first generate a set of points ([X1 Y1]) that have at least distance D from the main circle border, then generate the second set of points ([X2 Y2]) that have exact distance D from the first set.
cx = 50; cy = -50; cr = 200;
D = [10.5 44.8 30.01 37.2 23.4 49.1]';
n = numel(D);
R1 = rand(n, 1) .* (cr - D);
T1 = rand(n, 1) * 2 * pi;
X1 = cx+R1.*cos(T1);
Y1 = cy+R1.*sin(T1);
T2 = rand(n, 1) * 2 * pi;
X2 = X1+D.*cos(T2);
Y2 = Y1+D.*sin(T2);
You can tackle the problem using a two-steps approach. You can
randomly generate the first point and then you can consider the circle whose center is that point and whose radius is the distance in D
once you did draw the circle, every point lying on that circle will have distance D from the first point previously created and by random selection of one of these candidates you'll have the second point
Let's see with an example: let's say you main circle has radius 200 and its center is (0,0) so we start by declaring some main variables.
MAINCENTER_x=0;
MAINCENTER_y=0;
MAINRADIUS=200;
Let's now consider the first distance, D(1)=10.5 and we now generate the first random point which (along with its paired point - I reckon you don't want one point inside and the other outside of the main circle) must lie inside the main circle
r=D(1); % let's concentrate on the first distance
while true
x=((MAINRADIUS-2*r) - (-MAINRADIUS+2*r))*rand(1,1) + (-MAINRADIUS+2*r);
y=((MAINRADIUS-2*r) - (-MAINRADIUS+2*r))*rand(1,1) + (-MAINRADIUS+2*r);
if x^2+y^2<=(MAINRADIUS-2*r)^2
break;
end
end
and at the end of this loop x and y will be our first point coordinates.
Now we shall generate all its neighbours, thus several candidates to be the second point in the pair. As said before, these candidates will be the points that lie on the circle whose center is (x,y) and whose radius is D(1)=10.5. We can create these candidates as follows:
% declare angular spacing
ang=0:0.01:2*pi;
% build neighbour points
xp=r*cos(ang)+x;
yp=r*sin(ang)+y;
Now xp and yp are two vectors that contain, respectively, the x-coordinates and y-coordinates of our candidates, thus we shall now randomly select one of these
% second point
idx=randsample(1:length(xp),1);
secondPoint_x=xp(idx);
secondPoint_y=yp(idx);
Finally, the pair (x,y) is the first point and the pair (secondPoint_x, secondPoint_y) is our second point. The following plot helps summarizing these steps:
The red circle is the main area (center in (0,0) and radius 200), the red asterisk is the first point (x,y) the blue little circle has center (x,y) and radius 10.5 and finally the black asterisk is the second point of the pair (secondPoint_x, secondPoint_y), randomly extracted amongst the candidates lying on the blue little circle.
You must certainly can repeat the same process for all elements in D or rely on the following code, which does the very same thing without iterating through all the elements in D.
MAINCENTER_x=0;
MAINCENTER_y=0;
MAINRADIUS=200;
D = [10.5 44.8 30.01 37.2 23.4 49.1];
% generate random point coordinates
while true
x=((MAINRADIUS-2*D) - (-MAINRADIUS+2*D)).*rand(1,6) + (-MAINRADIUS+2*D);
y=((MAINRADIUS-2*D) - (-MAINRADIUS+2*D)).*rand(1,6) + (-MAINRADIUS+2*D);
if all(x.^2+y.^2<=(MAINRADIUS-2*D).^2)
break;
end
end
% declare angular spacing
ang=0:0.01:2*pi;
% build neighbour points
xp=bsxfun(#plus, (D'*cos(ang)),x');
yp=bsxfun(#plus, (D'*sin(ang)),y');
% second points
idx=randsample(1:size(xp,2),length(D));
secondPoint_x=diag(xp(1:length(D),idx));
secondPoint_y=diag(yp(1:length(D),idx));
%plot
figure(1);
plot(MAINRADIUS*cos(ang)+MAINCENTER_x,MAINRADIUS*sin(ang)+MAINCENTER_y,'r'); %main circle
hold on; plot(xp',yp'); % neighbours circles
hold on; plot(x,y,'r*'); % first points (red asterisks)
hold on; plot(secondPoint_x,secondPoint_y,'k*'); %second points (black asterisks)
axis equal;
Now x and y (and secondPoint_x and secondPoint_y by extension) will be vector of length 6 (because 6 are the distances) in which the i-th element is the i-th x (or y) component for the first (or second) point.

How to create a 2D image by rotating 1D vector of numbers around its center element?

I have 1D vector of numbers which represents a center cut of a circular symmetric object. The vector itself is symmetric around its center element. I want to create in MATLAB a 2D image of the original object by rotating the 1D vector around its center element.
I tried the following code (with a dummy original vector of numbers) , but the center cut I get from the generated 2D image does not match the original 1D vector, as can be seen if you run the code.
I'll appreciate any help !!!
close all; clc
my1D_vector=[ zeros(1,20) ones(1,15) zeros(1,20)]; % original vector
len=length(my1D_vector);
img=zeros(len, len);
thetaVec=0:0.1:179.9; % angles through which to rotate the original vector
numRotations=length(thetaVec);
% the coordinates of the original vector and the generated 2D image:
x=(1:len)-(floor(len/2)+1);
y=x;
[X,Y]=meshgrid(x,y);
for ind_rotations=1:numRotations
theta=pi/180*thetaVec(ind_rotations);
t_theta=X.*cos(theta)+Y.*sin(theta);
cutContrib=interp1(x , my1D_vector , t_theta(:),'linear');
img=img+reshape(cutContrib,len,len);
end
img=img/numRotations;
figure('name','original vector');plot(x,my1D_vector,'b.-')
figure('name','generated 2D image'); imagesc(x,y,img); colormap(gray) ;
figure('name','comparison between the original vector and a center cut from the generated 2D image');
plot(x,my1D_vector,'b.-')
hold on
plot(x,img(find(x==0),:),'m.-')
legend('original 1D vector','a center cut from the generated 2D image')
I didn't follow your code but how about this:
V = [ zeros(1,20) ones(1,15) zeros(1,20)]; % Any symmetrical vector
n = floor(numel(V)/2);
r = [n:-1:0, 1:n]; % A vector of distance (measured in pixels) from the center of vector V to each element of V
% Now find the distance of each element of a square 2D matrix from it's centre. #(x,y)(sqrt(x.^2+y.^2)) is just the Euclidean distance function.
ri = bsxfun(#(x,y)(sqrt(x.^2+y.^2)),r,r');
% Now use those distance matrices to interpole V
img = interp1(r(1:n+1),V(1:n+1),ri);
% The corners will contain NaN because they are further than any point we had data for so we get rid of the NaNs
img(isnan(img)) = 0; % or instead of zero, whatever you want your background colour to be
So instead of interpolating on the angle, I interpolate on the radius. So r represents a vector of the distance from the centre of each of the elements of V, in 1D. ri then represents the distance from the centre in 2D and these are the values we want to interpolate to. I then only use half of r and V because they are symmetrical.
You might want to set all the NaNs to 0 afterwards because you can't interpolate the corners because their radius is larger than the radius of your furthest point in V.
Using your plotting code I get
and
The blue and magenta curves overlap exactly.
Explanation
Imagine that your vector, V, was only a 1-by-5 vector. Then this diagram shows what r and ri would be:
I didn't mark it on the diagram but r' would be the middle column. Now from the code we have
ri = bsxfun(#(x,y)(sqrt(x.^2+y.^2)),r,r');
and according to the diagram r = [2,1,0,1,2] so now for each pixel we have the euclidean distance from the centre so pixel (1,1) is going to be sqrt(r(1).^2+r(1).^2) which is sqrt(2.^2+2.^2) which is sqrt(8) as shown in the diagram.
Also you will notice that I have "greyed" out the corners pixels. These pixels are further from the centre than any point we have data for because the maximum radius (distance from the centre) of our data is 2 but sqrt(8) > sqrt(5) > 2 so you can't interpolate those data, you would have to extrapolate to get values for them. interp1 returns NaN for these points.
Why does the interpolation work? Think of the position of each pixel as referring to the centre of the pixel. Now in this diagram, the red circle is what happens when you rotate the outer elements (i.e. r==2) and the green is rotating the elements 1 further in (i.e. r==1). You'll see that the pixel that gets the distance of sqrt(2) (blue arrow) lies between these two radii when we rotate them and so we have to interpolate that distance between those two pixels.

Define points within a radius for post analysis

I'm new to matlab an I'm trying for figure something out. I have a matrix that is 50x50. It represents data I recorded behind a turbine. The turbine is essentially placed in the center of this plane at the point (25,25). It has a radius of 5. Therefore it reaches to (20,25) to the left and (30,25) to the right of the center of the matrix. I know the formula for distance calculation is pdist([dpx,dpy;centerx,centery]). But how do I set this up so that matlab will identify all the points within the radius of 5. Im trying to multiple all these points (only the points within the radius of the turbine) by their distance from the center of the matrix. I imagine a for loop is required but I have no idea how to apply it.
Create a coordinate grid:
[x, y] = meshgrid(1 : 50);
Compute the distance of each grid point from (25, 25):
d = sqrt((x - 25) .^ 2 + (y - 25) .^ 2);
Generate a logical array that contains 1 (true) for every grid place within the turbine area:
turb = (d <= 5);
You can plot the result:
imagesc(turb)
axis equal tight
Or use turb for selecting values from a measurement matrix m
m(turb)
using logical indexing.
Note that indices (25, 25) do not denote the center of a 50 x 50 grid, but rather (25.5, 25.5).
Using logical indexing, you can find the relevant indexes in the matrix and select only them:
[x,y] = meshgrid(1:50);
centered_valued = ((x-25).^2+(y-25).^2 <= 5^2);
requested_matrix = originalMatrix(centered_values);
The meshgrid function computes two matrices: the first one contains the x indexes in every row, the second one contains the y indexes of every column.
You then use boolean computation to find the indexes which are within the radius from the center (located in (25,25).
This logical array then can be used as an "index" for the original matrix. The result will be a smaller matrix (though you might be forced to use the (:) operator, as the result is not necessarily a rectangular matrix).
If you have the image processing toolbox, you can also use the bwdist command to do the distance calculation for you.
Create a mask with the center point selected:
bw = zeros(50,50); bw(25,25) = 1;
Calculate the distance to each point from the center (note bwdist also allows for a variety of distance calculations, see doc bwdist for details)
distance = bwdist(bw);
Create a mask of the turbine pixels:
turbine = (distance <= 5);
You asked about multiplying pixels in the turbine by their distance from the center. If the original data is stored in the 50x50 matrix orig, then you can do:
orig(turbine) = orig(turbine) .* distance(turbine);

What is an simple way to compute the overlap between an image and a polygon?

I have a closed non-self-intersecting polygon. Its vertices are saved in two vectors X, and Y. Finally the values of X and Y are bound between 0 and 22.
I'd like to construct a matrix of size 22x22 and set the value of each bin equal to true if part of the polygon overlaps with that bin, otherwise false.
My initial thought was to generate a grid of points defined with [a, b] = meshgrid(1:22) and then to use inpolygon to determine which points of the grid were in the polygon.
[a b] = meshgrid(1:22);
inPoly1 = inpolygon(a,b,X,Y);
However this only returns true if if the center of the bin is contained in the polygon, ie it returns the red shape in the image below. However what need is more along the lines of the green shape (although its still an incomplete solution).
To get the green blob I performed four calls to inpolygon. For each comparison I shifted the grid of points either NE, NW, SE, or SW by 1/2. This is equivalent to testing if the corners of a bin are in the polygon.
inPoly2 = inpolygon(a-.5,b-.5,X,Y) | inpolygon(a+.5,b-.5,X,Y) | inpolygon(a-.5,b+5,X,Y) | inpolygon(a+.5,b+.5,X,Y);
While this does provide me with a partial solution it fails in the case when a vertex is contain in a bin but none of the bin corners are.
Is there a more direct way of attacking this problem, with preferably a solution that produces more readable code?
This plot was drawn with:
imagesc(inPoly1 + inPoly2); hold on;
line(a, b, 'w.');
line(X, Y, 'y);
One suggestion is to use the polybool function (not available in 2008b or earlier). It finds the intersection of two polygons and returns resulting vertices (or an empty vector if no vertices exist). To use it here, we iterate (using arrayfun) over all of the squares in your grid check to see whether the output argument to polybool is empty (e.g. no overlap).
N=22;
sqX = repmat([1:N]',1,N);
sqX = sqX(:);
sqY = repmat(1:N,N,1);
sqY = sqY(:);
intersects = arrayfun((#(xs,ys) ...
(~isempty(polybool('intersection',X,Y,[xs-1 xs-1 xs xs],[ys-1 ys ys ys-1])))),...
sqX,sqY);
intersects = reshape(intersects,22,22);
Here is the resulting image:
Code for plotting:
imagesc(.5:1:N-.5,.5:1:N-.5,intersects');
hold on;
plot(X,Y,'w');
for x = 1:N
plot([0 N],[x x],'-k');
plot([x x],[0 N],'-k');
end
hold off;
How about this pseudocode algorithm:
For each pair of points p1=p(i), p2=p(i+1), i = 1..n-1
Find the line passing through p1 and p2
Find every tile this line intersects // See note
Add intersecting tiles to the list of contained tiles
Find the red area using the centers of each tile, and add these to the list of contained tiles
Note: This line will take a tiny bit of effort to implement, but I think there is a fairly straightforward, well-known algorithm for it.
Also, if I was using .NET, I would simply define a rectangle corresponding to each grid tile, and then see which ones intersect the polygon. I don't know if checking intersection is easy in Matlab, however.
I would suggest using poly2mask in the Image Processing Toolbox, it does more or less what you want, I think, and also more or less what youself and Salain has suggested.
Slight improvement
Firstly, to simplify your "partial solution" - what you're doing is just looking at the corners. If instead of considering the 22x22 grid of points, you could consider the 23x23 grid of corners (which will be offset from the smaller grid by (-0.5, -0.5). Once you have that, you can mark the points on the 22x22 grid that have at least one corner in the polygon.
Full solution:
However, what you're really looking for is whether the polygon intersects with the 1x1 box surrounding each pixel. This doesn't necessarily include any of the corners, but it does require that the polygon intersects one of the four sides of the box.
One way you could find the pixels where the polygon intersects with the containing box is with the following algorithm:
For each pair of adjacent points in the polygon, calling them pA and pB:
Calculate rounded Y-values: Round(pA.y) and Round(pB.y)
For each horizontal pixel edge between these two values:
* Solve the simple linear equation to find out at what X-coordinate
the line between pA and pB crosses this edge
* Round the X-coordinate
* Use the rounded X-coordinate to mark the pixels above and below
where it crosses the edge
Do a similar thing for the other axis
So, for example, say we're looking at pA = (1, 1) and pB = (2, 3).
First, we calculated the rounded Y-values: 1 and 3.
Then, we look at the pixel edges between these values: y = 1.5 and y = 2.5 (pixel edges are half-offset from pixels
For each of these, we solve the linear equation to find where pA->pB intersects with our edges. This gives us: x = 1.25, y = 1.5, and x = 1.75, y = 2.5.
For each of these intersections, we take the rounded X-value, and use it to mark the pixels either side of the edge.
x = 1.25 is rounded to 1 (for the edge y = 1.5). We therefore can mark the pixels at (1, 1) and (1, 2) as part of our set.
x = 1.75 is rounded to 2 (for the edge y = 2.5). We therefore can mark the pixels at (2, 2) and (2, 3).
So that's the horizontal edges taken care of. Next, let's look at the vertical ones:
First we calculate the rounded X-values: 1 and 2
Then, we look at the pixel edges. Here, there is only one: x = 1.5.
For this edge, we find the where it meets the line pA->pB. This gives us x = 1.5, y = 2.
For this intersection, we take the rounded Y-value, and use it to mark pixels either side of the edge:
y = 2 is rounded to 2. We therefore can mark the pixels at (1, 2) and (2, 2).
Done!
Well, sort of. This will give you the edges, but it won't fill in the body of the polygon. However, you can just combine these with your previous (red) results to get the complete set.
First I define a low resolution circle for this example
X=11+cos(linspace(0,2*pi,10))*5;
Y=11+sin(linspace(0,2.01*pi,10))*5;
Like your example it fits with in a grid of ~22 units. Then, following your lead, we declare a meshgrid and check if points are in the polygon.
stepSize=0.1;
[a b] = meshgrid(1:stepSize:22);
inPoly1 = inpolygon(a,b,X,Y);
Only difference is that where your original solution took steps of one, this grid can take smaller steps. And finally, to include anything within the "edges" of the squares
inPolyFull=unique( round([a(inPoly1) b(inPoly1)]) ,'rows');
The round simply takes our high resolution grid and rounds the points appropriately to their nearest low resolution equivalents. We then remove all of the duplicates in a vector style or pair-wise fashion by calling unique with the 'rows' qualifier. And that's it
To view the result,
[aOrig bOrig] = meshgrid(1:22);
imagesc(1:stepSize:22,1:stepSize:22,inPoly1); hold on;
plot(X,Y,'y');
plot(aOrig,bOrig,'k.');
plot(inPolyFull(:,1),inPolyFull(:,2),'w.'); hold off;
Changing the stepSize has the expected effect of improving the result at the cost of speed and memory.
If you need the result to be in the same format as the inPoly2 in your example, you can use
inPoly2=zeros(22);
inPoly2(inPolyFull(:,1),inPolyFull(:,2))=1
Hope that helps. I can think of some other ways to go about it, but this seems like the most straightforward.
Well, I guess I am late, though strictly speaking the bounty time was till tomorrow ;). But here goes my attempt. First, a function that marks cells that contain/touch a point. Given a structured grid with spacing lx, ly, and a set of points with coordinates (Xp, Yp), set containing cells:
function cells = mark_cells(lx, ly, Xp, Yp, cells)
% Find cell numbers to which points belong.
% Search by subtracting point coordinates from
% grid coordinates and observing the sign of the result.
% Points lying on edges/grid points are assumed
% to belong to all surrounding cells.
sx=sign(bsxfun(#minus, lx, Xp'));
sy=sign(bsxfun(#minus, ly, Yp'));
cx=diff(sx, 1, 2);
cy=diff(sy, 1, 2);
% for every point, mark the surrounding cells
for i=1:size(cy, 1)
cells(find(cx(i,:)), find(cy(i,:)))=1;
end
end
Now, the rest of the code. For every segment in the polygon (you have to walk through the segments one by one), intersect the segment with the grid lines. Intersection is done carefully, for horizontal and vertical lines separately, using the given grid point coordinates to avoid numerical inaccuracies. For the found intersection points I call mark_cells to mark the surrounding cells to 1:
% example grid
nx=21;
ny=51;
lx = linspace(0, 1, nx);
ly = linspace(0, 1, ny);
dx=1/(nx-1);
dy=1/(ny-1);
cells = zeros(nx-1, ny-1);
% for every line in the polygon...
% Xp and Yp contain start-end points of a single segment
Xp = [0.15 0.61];
Yp = [0.1 0.78];
% line equation
slope = diff(Yp)/diff(Xp);
inter = Yp(1) - (slope*Xp(1));
if isinf(slope)
% SPECIAL CASE: vertical polygon segments
% intersect horizontal grid lines
ymax = 1+floor(max(Yp)/dy);
ymin = 1+ceil(min(Yp)/dy);
x=repmat(Xp(1), 1, ymax-ymin+1);
y=ly(ymin:ymax);
cells = mark_cells(lx, ly, x, y, cells);
else
% SPECIAL CASE: not horizontal polygon segments
if slope ~= 0
% intersect horizontal grid lines
ymax = 1+floor(max(Yp)/dy);
ymin = 1+ceil(min(Yp)/dy);
xmax = (ly(ymax)-inter)/slope;
xmin = (ly(ymin)-inter)/slope;
% interpolate in x...
x=linspace(xmin, xmax, ymax-ymin+1);
% use exact grid point y-coordinates!
y=ly(ymin:ymax);
cells = mark_cells(lx, ly, x, y, cells);
end
% intersect vertical grid lines
xmax = 1+floor(max(Xp)/dx);
xmin = 1+ceil(min(Xp)/dx);
% interpolate in y...
ymax = inter+slope*lx(xmax);
ymin = inter+slope*lx(xmin);
% use exact grid point x-coordinates!
x=lx(xmin:xmax);
y=linspace(ymin, ymax, xmax-xmin+1);
cells = mark_cells(lx, ly, x, y, cells);
end
Output for the example mesh/segment:
Walking through all polygon segments gives you the polygon 'halo'. Finally, the interior of the polygon is obtained using standard inpolygon function. Let me know if you need more details about the code.