How the streamline function is implemented?

Hello everyone,
I post this question some time ago, I am still searching about it. I found exactly what I want! However it is a MATLAB built in function and I need to know how it is done?!
Here is the link to streamline function which produces an amazing result for my problem. How these lines are generated? I need the points of these lines not only just drawing them!
Any idea how streamline finds this curved smooth lines?
Thanks a lot.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%555%%
THIS IS THE OLD QUESTION, WHICH IS NOW TURNED INTO THIS NEW ONE
Hello People,
I have an image processing question. I want to go from 1 to 2 making curved lines (curvature is probably determined by the gradient of the image).
I have the following image. I used edge detection to find the edges of the image, red and green edges are the ones that I need and I got them extracted.
I select a pixel from the red edge (lets name it Pr) and find the closest pixel to it on the green edge (lets call it Pg).
Now the problem is, I don't know how to follow the gradient path of the image (roughly showed in yellow) from red point (Pr) to green point (Pg). I don't want to do straight lines, I connected them directly before but that's not satisfying.
Any ideas how can I do that please? I am thinking of some sort of region growing?!!!
Figure.1. A non-convext gray scale image. Start and finish points are marked with red and green and yellow roughly shows the direction of gradient vectors.
Thanks a lot for your help.

Antworten (2)

Image Analyst
Image Analyst am 9 Mai 2015

1 Stimme

Just threshold and call bwboundaries
binaryImage = grayImage > 0;
boundary = bwboundaries(binaryImage);
x = boundary{1}(:, 2);
y = boundary{1}(:, 1);
If you want just the top and bottom edge, you have to identify all indexes which have the x value of the sides and then take the pixels in between. Then, if the points go closckwise along the border, you will have to call fliplr() on the flat bottom section.

9 Kommentare

Nick Earnhardt
Nick Earnhardt am 9 Mai 2015
Bearbeitet: Nick Earnhardt am 10 Mai 2015
Thanks for your answer, however I don't just want the exterior boundary.
I want a series of lines (curves), one curve from every red pixels to the closet green pixels.
I got the red pixels by thresholding and edge detection, and green pixels only by thresholding (they always have the highest value)
I put another picture, I tried to write an algorithm to first find all the neighbors of a red pixel, then pick the one with grates gradient, and then do the same thing to this point and continue just the same way. However it was a mess and didn't work at all :(
_
_
1. Figure.2. A Convex grayscale image, red and green are the start and finish points, and yellow shows the direction of the path (yellow is also matches with the gradient direction).
I want the yellow lines, starting from red to the green. in this particular image it will be straight lines, and it is exactly in the direction of the gradient vector. In fact lines should be in the direction of the gradient.
I put the image of the gradient vector
2.Figure.3: quiever plot of gradient vectors of the image in Figure.2
Any clue? algorithm that can do such?!
Thanks a lot
Image Analyst
Image Analyst am 9 Mai 2015
You can draw lines with the quiver() function once you have the vectors.
Nick Earnhardt
Nick Earnhardt am 9 Mai 2015
Bearbeitet: Nick Earnhardt am 10 Mai 2015
Thanks for your attention and help.
Actually I draw the previois gradient image using quiver(X,Y), how ever I don't just want to draw I need the pixels that leads to the green point.
The code I wrote atm takes one red pixel, and connects it to the closest green pixel. For the picture above it looks like this.
-
-
1.Figure.4. Quantizing the Figure.2 and connecting the quantized levels together (explained further in next comments).
But this just works for simple images, where the gradient vector direction is not changing when traveling from red pixel to green pixel. In oder words it just does a straight line. For if I use the same thing for the very first image I posted (image in the question) it won't work.
I'm really stocked and appreciate your help and ideas.
Many thanks.
Image Analyst
Image Analyst am 10 Mai 2015
Do you know the coordinates of every red pixel and every green pixel?
Nick Earnhardt
Nick Earnhardt am 10 Mai 2015
Bearbeitet: Nick Earnhardt am 10 Mai 2015
Yes sir, I extracted the red and green pixels ( Figure.1 is a grayscale image, I marked the start and finish pixels with red and green in paint).
I just want to connect every red to green with a curve, a straight line is not satisfactory as it gets out of the foreground pixels for non-convex images such as in Figure.1.
Apparently gradient vectors are indicating the derivative of the desired curve, I don't know how to use this information to get from red to green with a curve not line.
I tried to write an algorithm, to select a red pixel, get its eculidian distance to all green pixels and then find the closest green pixel. Next, it starts from a red pixel, and based on the gradient vector direction of current pixel (red) it finds the next pixel (within the 8 neighbors). And again based on the gradient of the current pixel finds the next and this continues till it gets to the green pixel (theoretically)
It may sounds easy, but it took me some months and never worked good, not even a single line. The moving point gets completely confused in middle of the way.
So, eventually what I did was, I quantized the grayscale image (for instance Figure.2 ) and detected its edges, Figure.5 .
-
-
1.Figure.5. Quantized and edge extracted grayscale image, the original image is showed in Figure.2 .
-
and I separated the layers based on their graylevel then starting from the lowest graylevel to the highest which lead to Figure.4 . It may be one step closer to what I need but.
  1. It's not robust.
  2. It's almost impossible to get more than 10 grayscale levels. Unless upsampling the image ridiculously.
  3. It's not scientific at all! So I don't want to discus it.
  4. I don't like how I done it up to this level. and as seen in Figure.4 its barely acceptable.
I'm sure you experts can come up with some professional ideas.
Many Thanks.
Here's a demo that will draw a line from each red dot to the closest green dot, assuming you have the coordinates for both red and green dots, which you said you do already.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Create a circle:
xCenter = 10;
yCenter = 8;
theta = linspace(0, 2*pi, 50);
radius = 7;
redx = radius * cos(theta) + xCenter;
redy = radius * sin(theta) + yCenter;
plot(redx, redy, 'r.', 'MarkerSize', 25);
axis equal;
xlim([0 20]);
ylim([0 16]);
grid on;
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'Outerposition', [0, 0, 1, 1]);
% Create green points near the middle
greenx = rand(1, 10) + xCenter - 0.5;
greeny = rand(1, 10) + yCenter - 0.5;
hold on;
plot(greenx, greeny, '.', 'Color', [0, 0.5, 0], 'MarkerSize', 20);
for redRow = 1 : length(redx)
distances = sqrt((redx(redRow) - greenx).^2 + ...
(redy(redRow) - greeny) .^ 2);
[minDistance, indexOfMin] = min(distances);
gx = greenx(indexOfMin);
gy = greeny(indexOfMin);
% Draw line to the closest green dot.
line([redx(redRow), gx], [redy(redRow), gy], 'color', 'b');
end
Nick Earnhardt
Nick Earnhardt am 10 Mai 2015
Bearbeitet: Nick Earnhardt am 10 Mai 2015
Dear Image Analyst
Thanks a lot, thats great.
However, this works for this instance not Figure.1. If I do the same thing to it, some lines will get out of the foreground pixels. As I said Figure.1 is not convex. So straight lines are not good enough.
What can we do for Figure.1?
BTY just like you did, the output doesn't need to be an image. I need the lines.
Thanks a lot for your help.
Image Analyst
Image Analyst am 10 Mai 2015
Bearbeitet: Image Analyst am 10 Mai 2015
To hug that curve on the top of your first picture, you may want to treat it as an image - it may help. See this series on finding the shortest path by Steve Eddins, the leader of the imaging team at the Mathworks. http://blogs.mathworks.com/steve/2011/11/01/exploring-shortest-paths-part-1/ first find the two points, like I just showed. Then use bwgeodesicdist() to force it to go within some region of interest.
Nick Earnhardt
Nick Earnhardt am 10 Mai 2015
Thanks a lot for the hint.
I read some part of it, which was about distance transform, last night. I'll go through the rest of it.
Thanks a lot.

Melden Sie sich an, um zu kommentieren.

Walter Roberson
Walter Roberson am 9 Mai 2015

1 Stimme

Following the gradient is equivalent to a shortest-path algorithm, such as the Dijkstra Shortest-Path algorithm.
You might also want to consider the gray-weighted distance routine, graydist

2 Kommentare

Nick Earnhardt
Nick Earnhardt am 9 Mai 2015
Bearbeitet: Nick Earnhardt am 10 Mai 2015
Thanks for the clue Walter, I'll check these things right now.
Thanks a lot
Nick Earnhardt
Nick Earnhardt am 12 Mai 2015
Dear Image Analyst & Walter,
I just read this tutorial on shortest path by Steve! That's just amazing, I love it! I'll definitely try to write something similar using graydist. Lets keep fingers crossed ;)
Thanks

Melden Sie sich an, um zu kommentieren.

Kategorien

Gefragt:

am 9 Mai 2015

Bearbeitet:

am 28 Mai 2015

Community Treasure Hunt

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

Start Hunting!

Translated by