Region of interest definition algorithm

I am trying to build an algorithm that can detect the edges of a particle. The function attached itterates radially outword from a point and detects if each location that is either a localmaximum or exceeds a threshold. As shown in the attached image this should allow the code to independently identify the edges of each low point in the data matrix.
The problem that I have with my current code is that because it iterates both radially and outward it is incredibly time consuming. Can anyone suggest something better?
I have also attached some sample data:
function [S_boarderx,S_boardery,Board_val] = shadowedge(im,shadowx,shadowy,R, dirmax, thres, PM)
SS = im;
[dimx, dimy] = size(SS,1,2);
xx = shadowx;
yy = shadowy;
shadow_loc = sub2ind([dimx dimy], xx, yy);
shadow_Val = SS(shadow_loc);
thres_val = shadow_Val+shadow_Val*thres;
for t = 1:dirmax
for j=1:R
theta = (2*pi*t)/dirmax;
Sx = xx+round(j*cos(theta));
Sy = yy+round(j*sin(theta));
Sx(Sx<= 1) = 2;
Sy(Sy<= 1) = 2;
Sx(Sx>= dimx-1) = dimx-1;
Sy(Sy>= dimy-1) = dimy-1;
val = SS(sub2ind([dimx dimy], Sx, Sy));
if val >= thres_val
S_boarderx(t,:) = Sx;
S_boardery(t,:) = Sy;
break
elseif sum(sub2ind([dimx dimy],Sx,Sy) == find(islocalmax(SS,'MinProminence',PM)))...
|| sum(sub2ind([dimx dimy],Sx+1,Sy+1) == find(islocalmax(SS,'MinProminence',PM)))...
|| sum(sub2ind([dimx dimy],Sx+1,Sy) == find(islocalmax(SS,'MinProminence',PM)))...
|| sum(sub2ind([dimx dimy],Sx,Sy+1) == find(islocalmax(SS,'MinProminence',PM)))...
|| sum(sub2ind([dimx dimy],Sx-1,Sy-1) == find(islocalmax(SS,'MinProminence',PM)))...
|| sum(sub2ind([dimx dimy],Sx-1,Sy) == find(islocalmax(SS,'MinProminence',PM)))...
|| sum(sub2ind([dimx dimy],Sx,Sy-1) == find(islocalmax(SS,'MinProminence',PM)))
S_boarderx(t,:) = Sx;
S_boardery(t,:) = Sy;
break
else
S_boarderx(t,:) = Sx;
S_boardery(t,:) = Sy;
end
end
end
Board_loc = sub2ind([dimx dimy], S_boarderx(:), S_boardery(:));
Board_val = SS(Board_loc);

10 Comments

Is there any reason you're not using the Image Processing Toolbox? For example, edge will analyze a grayscale or binary image to determine the edges of items in it. Take a look at this example implementation for detecting a cell.
If you can't use the Image Processing Toolbox, you could take a look at the algorithms that it uses and try to develop your own function to do so.
Clayton,
This is helpful I will see if I can implement the edge detection into my function. My concern is that I want to detect very particular edges that surround local minima.
My apologies - I thought the edge detection was the hangup! You can use islocalmin to find the local minima in an array:
test_array = [];
localmin_cols = islocalmin(test_array); % Since islocalmin only tests one direction
localmin_rows = islocalmin(test_array.').';
% Taking advantage of the fact that a 2D local min must be a local minimum
% in both directions
local_min = localmin_cols.*(localmin_cols==localmin_rows);
% Preparing to make chart of local minima
colormat = repmat(local_min,1,1,3);
color(1,1,1:3) = [0 0.5 0.5]; % Cyan-ish - [0 0 0] is black and [1 1 1] is white
colormat = colormat.*color;
imshow(colormat) % All of the minima are highlighted against a black background
colormat(colormat==0)=1; % Changes it to white background and pinkish points
imshow(colormat)
You should be able to marry the edge detection to the minimum finder to determine which are your regions of interest.
Something else I've just remembered is the boundary tracing capability, which may be more what you're looking for than the edge detection. For example, I got this using your sample image and the below code:
bw_Image = im2bw(Image);
boundaries = bwboundaries(bw_Image);
imshow(test);
hold on
for k=1:size(boundaries,1)
b = boundaries{k};
plot(b(:,2),b(:,1),'g','LineWidth',3);
end
Where is the original image? Is it in the .mat file? Or is that gray scale screenshot with the contours overlaid on it your image?
Image Analyst it is the .mat file
How did you call it? What are the arguments in shadowedge(image,shadowx,shadowy,R, dirmax, thres, PM)?
Don't use image as the name of a variable since it's the name of an important built-in function.
It is called Image right now, but I renamed is before use
So you won't answer the first question??? Why not?
Give us code that we can run, which means the function's m-file, and an m-file that assigns all the arguments and sends them to the function, along with any other data files or images needed.
I am sorry, I think I misunderstood your question. I call it with the following command.
[S_boarderx,S_boardery,Board_val] = shadowedge(Image,shadowx,shadowy,10, 45, .5, 0);
This should take the point in the Image array at [shadowx,shadowy] and search radially outward until the threshold of 1.5*the value at [shadowx,shadowy] is reached or a local maxima.
10 = maximum radius
45 = the number of radial directions it searches
Specifically I use the function above and run it through a loop on many points within image file SS.mat
[dimx,dimy] = size(SS,1,2);
mask = zeros(dimx,dimy,size(shadow_loc,1));
for i=1:size(shadow_loc,1)
[sboardx, sboardy, Board_val] = shadowedge(SS,shadow(i,1),shadow(i,2),10, 45, .5, 0);
R = roipoly(SS,sboardy(:),sboardx(:));
mask(:,:,i) = R;
end
smask = sum(mask,3);
smask(smask>0) = 1;
@Brittney Gorman, Sorry I didn't see your reply until now. Are you still having a problem with this code?

Sign in to comment.

Answers (0)

Asked:

on 27 Apr 2021

Commented:

on 26 Jun 2021

Community Treasure Hunt

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

Start Hunting!