Posted is a picture of a cross section of a vein. I have transformed the red interior line into a circle and need to have the pixels on the black line surround the new circular red line, both red and black lines having the same centers. The transformed black line should not be a perfect circle. As you can see in the picture, the distance between the black and red lines differ and once the black line is transformed, it should maintain the same varying distance between it and the red line as before. My question is how can I do this?
It's not too hard if you think about it systematically. Just take it one step at a time. The key is to convert the lines into masks and use bwdist().
(4) The region thickness is twice the EDT value at the center. Let's say you had a region 20 pixels wide. Well, at the center it will be 10 pixels to either side because if you're at the center line it has to go only half the thickness to get outside the region. So you need to double the value at the center to get the full thickness.
6) You multiply by the skeleton to give you the value along the centerline of the region. The EDT you get in (4) is a thick image. It's like a wide swatch the same size as the region in between your two curves. And the values of the EDT go from 0 or 1 at the edge (where a pixel inside the swath does not have far to go to get outside) all the way to half the thickness at the centerline. If you're 3 pixels away from the background, the EDT value is 3, if you're 4 pixels away it's 5, if you're 5 pixels away it's 5, and so on until you're the radius (half thickness) away from the edge. If you proceed toward the other side, it starts going down again until it again reaches 0 at the other edge (boundary).
Think of it like this. You're taking an inflatable ball and running it along the region between the two lines. The ball is always inflated as much as it can go and still be a circle. Sometimes, when the thickness is large, you can fit a large ball, and sometimes, when the thickness is small, you'll have a small ball. The EDT along the centerline (skeleton, spine) is the radius of the ball at that point.
Does that explain it better?
Thanks for the clarification, I understand what the EDT and skeleton are now. So far I have: #1 created the masks #2 gotten the "in between" region and made it hollow #3 did a EDT calc between the two boundary lines of the region #4 found the skeleton of the hollow region #5 removed the branches from the skeleton (don't know purpose of branches) #6 found the perimeter of the region that will be transformed in a circle #7 used that perimeter to find the diameter for the transformed circle
When I did the EDT it gave me a giant "logic" matrix. So now how can I use MATLAB to go through all of the pixels on a boundary of the matrix and find the distance to the nearest pixel on the opposing line?
I appreciate your help.
So now how can I use MATLAB to go through all of the pixels on a boundary of the matrix and find the distance to the nearest pixel on the opposing line?
If the rows of A are the pixel coordinates on the black line and B the red line, then you can use
http://www.mathworks.com/matlabcentral/fileexchange/18937-ipdm-inter-point-distance-matrix
as follows
s=ipdm(A,B,'Subset', 'NearestNeighbor','Result','Structure');
Then s.columnindex will be the indices in B of the closest points on the red line. The corresponding distances will be in s.distance.
When run with this specific syntax, the column index is what will be most useful. It tells you that
B(short_dist.columnindex(i), :)
is the closest point on the red line to A(i,:). And if you want the vector between the two points, just do
B(short_dist.columnindex(i), :) - A(i,:)
for all i=1...1856. Or, in vectorized form, simply
B(short_dist.columnindex, :) - A
Can you see any way in which I can do the transform that I want using the given specifications?
Well, here's another idea. You're already using imfreehand or similar to trace the boundary of the curves. It seems to me that it would be essentially the same manual effort to use IMLINE or similar to draw lots of closely spaced line segments connecting the black curve to the red curve (essentially the pre-chords that we've been talking about). You would do this according to your own visual idea of which points on the black and red curves correspond, as opposed to using IPDM.
Once you've done that, you map all the points on the black curve to the desired circle. You would probably do this so that the distances between neighboring black points are all the same post-transformation as they were pre-transformation. You then use the lengths of the pre-chords to construct post-chords of the same length, except that the post chords are all directed inward toward the center of the black circle. The inner endpoints of the post-chords define the points on the transformed red curve and you're done.
Assuming you pack the pre-chords densely enough, you should get a pretty good approx of the curve you're looking for. Assuming, further, that a transform preserving both chord length and area does exist, I would expect this manual approach to do a fair bit better than the 8% area agreement you got via IPDM. If you don't get good area preservation, it would suggest to me that the requirements of chord length preservation and area preservation are in conflict. In either case, I wonder if you should really be caring about preserving distance and area so precisely. It sounds to me like you're planning to use this anyway as nothing more than an ad hoc initial approximation to something that's going to be refined later using something more principled (FEA?).
Could I preserve area by multiplying the transformed curves by sqrt(A_orig/A_new)?
0 Comments