4

I want to create an image of an object from its morphological skeleton. Is there any function in MATLAB or C,C++ code? Thanks in advance.

Original image, and its skeleton (obtained using bwmorph(image,'skel',Inf)):

hand2 handskel2

Amro
  • 123,847
  • 25
  • 243
  • 454
user461127
  • 101
  • 1
  • 2
  • 6
  • 1
    in general that is not possible, unless you have an object with a really simple shape. Can you post an example of the image you are talking about (before and after skeletonization) – Amro Oct 04 '11 at 15:51
  • Hello @Amro, Object is a simple shape. Original image: [http](http://imageshack.us/f/546/hand2.png/) Skeleton: [http](http://imageshack.us/f/406/handskel2.png/) – user461127 Oct 04 '11 at 20:31
  • 1
    Here, under "more info" you have the simple algorithm explained http://reference.wolfram.com/mathematica/ref/InverseDistanceTransform.html – Dr. belisarius Oct 05 '11 at 02:35
  • 1
    @belisarius: +1 that should be posted as the answer – Amro Oct 05 '11 at 03:16
  • @Amro Please feel free to implement (and answer!) in any of the languages the OP asked for. There is no point in posting an algorithm link as an answer when the OP is asking for code (I think) – Dr. belisarius Oct 05 '11 at 04:19
  • @belisarius: now that I think about it (I actually wrote an initial implementation of the Inverse Distance Transform in MATLAB), your proposed solution doesn't exactly fit this problem... The OP has a skeleton not a distance transform of the image, so it won't work as it requires the distance values at each pixel to determine the radius of the disks (skeleton is only a binary image) – Amro Oct 05 '11 at 21:15
  • 1
    @Amro I was using this definition for "skeleton" http://reference.wolfram.com/mathematica/ref/SkeletonTransform.html. I could be wrong, of course. Anyway, if your skeleton is just b&w, there is no way to know when to stop dilating it. (a big circle and a small circle, both give you the same "skeleton") – Dr. belisarius Oct 05 '11 at 21:29
  • @belisarius: ah, that is not the same as MATLAB's version of "skeleton", though we can combine distance transform and skeletonization to achieve the same result as Mathematica. I will post my version and let OP decide... – Amro Oct 05 '11 at 21:56

3 Answers3

7

As stated in the comments above, bwmorph(..,'skel',Inf) gives you a binary image of the skeleton, which is not enough on its own to recover the original image.

On the other, if you had, for each skeleton pixel, the values returned by the distance transform, then you can successfully apply the inverse distance transform (as suggested by @belisarius):

Note that this implementation of InverseDistanceTransform is rather slow (I based it on a previous answer). It repeatedly uses POLY2MASK to get pixels inside the specified circles, so there is room for improvement..

%# get binary image
BW = ~imread('http://img546.imageshack.us/img546/3154/hand2.png');

%# SkeletonTransform[]
skel = bwmorph(BW,'skel',Inf);
DD = double(bwdist(~BW));
D = zeros(size(DD));
D(skel) = DD(skel);

%# zero-centered unit circle
t = linspace(0,2*pi,50);
ct = cos(t);
st = sin(t);

%# InverseDistanceTransform[] : union of all disks centered around each
%# pixel of the distance transform, taking pixel values as radius
[r c] = size(D);
BW2 = false(r,c);
for j=1:c
    for i=1:r
        if D(i,j)==0, continue; end
        mask = poly2mask(D(i,j).*st + j, D(i,j).*ct + i, r, c);
        BW2(mask) = true;
    end
end

%# plot
figure
subplot(131), imshow(BW), title('original')
subplot(132), imshow(D,[]), title('Skeleton+DistanceTransform')
subplot(133), imshow(BW2), title('InverseDistanceTransform')

The result:

original Skeleton_DistanceTransform InverseDistanceTransform

Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • thank you very much for your effort indeed. Sorry, for late reply. The problem is solved as similar to yours. Actually, skeletons are given as x,y coordinates and radius/weight. Reconstruction is performed drawing closed circles at every x,y coordinate and a radius of its weight. – user461127 Oct 15 '11 at 23:49
  • I found this useful even 9 years on. A helpful tip: caching the masks as you go is helpful. I used containers.Map with dist(i,j) keys to speed this up tremendously for my application. Though you have to generalize the mask locations for this to work :) – do-the-thing-please Sep 11 '20 at 16:21
0

The function bwmorph can be used for code generation as seen here Image Processing functions for code generation. Write the code in a MATLAB function and use the codegen command. for generating code. The option for code generation is available past R2012b MATLAB Release Notes.

Lokesh A. R.
  • 2,326
  • 1
  • 24
  • 28
0

Depending on your object, you may be able to get a meaningful result using dilation (IMDILATE in Matlab).

Jonas
  • 74,690
  • 10
  • 137
  • 177