Can this be written in a much better way for fast computations?
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
ropesh goyal
el 7 de Ag. de 2019
Comentada: Guillaume
el 7 de Ag. de 2019
coast=magic(14400)
di_max=100;
mx=14400;
my=14400;
for ix=1:mx
for iy=1:my
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for dx=-di_max:di_max
for dy=-di_max:di_max
jx=ix+dx;
jy=iy+dy;
if((jx>=1) && (jx<=mx) && (jy>=1) && (jy<=my))
dd=sqrt(dx^2+dy^2);
coast(jx,jy) = min([coast(jx,jy),dd]);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
end
8 comentarios
Joel Handy
el 7 de Ag. de 2019
Editada: Joel Handy
el 7 de Ag. de 2019
@Guillaume. I see it now. Good catch.
For anyone missing it like me, the original code sweeps through every "pixel" and assigns the surrounding pixels a distance from that pixel. Since the pixel itself is being included, the minimum distance of a pixel from a neighboring pixel is always zero.
@ropesh, I kind of figured this is where this was going.
There are some bugs in this code. iscoast is only set if coast(ix,iy) == 0. That means if coast(ix,iy) ~=0 0, iscoast is in a leftover state from the last iteration of the two outer loops.
I also suspect this code is going to overwrite individual pixels more than once making results inconsistent.
Is "water"? is it the same size as coast?
Maybe if you can give us the bigger picture we can make some better suggestions. If I were to venture a guess, you have an image of some sort and you know what percentage of each pixel is water. You want to look at each pixel which is mostly water, and assign a distance from the pixel to all surrounding pixels that are not water.
Respuesta aceptada
Joel Handy
el 7 de Ag. de 2019
Editada: Joel Handy
el 7 de Ag. de 2019
The code below will do what you are asking without needing a loop.
coast=magic(14400);
di_max=100;
mx=14400;
my=14400;
[ix dx] = meshgrid(1:mx, -di_max:di_max);
[iy dy] = meshgrid(1:my, -di_max:di_max);
jx = ix+dx;
jy = iy+dy;
dd= sqrt(dx.^2+dy.^2);
mask = ((jx(:)>=1) & (jx(:)<=mx) & (jy(:)>=1) & (jy(:)<=my));
idx = sub2ind(size(coast), jx(mask), jy(mask));
coast(idx) = min(coast(idx),dd(mask));
3 comentarios
Joel Handy
el 7 de Ag. de 2019
@Guillaume. I did make a bonehead mistake like I thought I might have. Fixed now hopefully.
I dont see coast filled with zeros though and I dont see how that would hapen in the original code. Cost is initialized to non-zero values and dd is rarely zero either.
Más respuestas (1)
Guillaume
el 7 de Ag. de 2019
If Joel hypothesis that "You want to look at each pixel which is mostly water, and assign a distance from the pixel to all surrounding pixels that are not water" is true (we still haven't add a proper explanation!), then as I said in a comment, this can be achieved in just one line. This is called the distance transform and is achieved in matlab with bwdist.
If all zeros pixels in coast are to be replaced by their euclidean distance to the nearest non-zero pixel, it's simply:
dist = bwdist(coast ~= 0);
coast(coast == 0) = dist(coast == 0);
2 comentarios
Guillaume
el 7 de Ag. de 2019
I'm not clear why you'd want a window and I don't understand how you would want it to work with a window. bwdist will find the nearest non-zero pixel however far it is, and do this very fast
Again, as I've repeatedly asked, explain in words what you're trying to achieve. e.g.: I've got a matrix coast representing _____ and a matrix water representing ____ and I want to replace the (non-zeros?zeros?something?) values by the distance to the nearest _____. If there's no nearest _______ in a window of 100x100, then I want ______.
Ver también
Categorías
Más información sobre Performance and Memory en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!