Can a skeleton be defined on a neighbourhood of 8 pixels ?
Hi, Is it possible to skeletonize a binary 2D shape such that its skeleton is defined on a neighbourhood of 8 pixels? When skeletonizing with : *morphology.medial_axis()* , I tried two structuring elements (se8 or se4) as mask : se8 = np.array([[True,True,True],[True,True,True],[True,True,True]]) se4 = np.array([[False,True,False],[True,True,True],[False,True,False]]) imK = makeLetterImage('K', 70) skel = *morphology.medial_axis*(imK,mask=se8) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel) The skeletons returned using se8 or se4 are very similar and look defined on a neighbourhood of 4 pixels (left). To me, this is a problem when trying to label the skeleton edges (right). <https://lh4.googleusercontent.com/-curcY_g5N9A/U5BfJdpe6yI/AAAAAAAAB0w/1PbxFHLHJ6s/s1600/labeling+edges.png> Jean-Patrick <https://lh4.googleusercontent.com/-curcY_g5N9A/U5BfJdpe6yI/AAAAAAAAB0w/1PbxFHLHJ6s/s1600/labeling+edges.png>
Hi Jean-Patrick, I'm not sure I understand your question. Neither connectivity will allow you to label the skeleton branches. For that, you will need a graph representation of the skeleton, with branch points represented by nodes that have more than two edges. It would also help if you provide complete code with example expected and actual output. (I don't understand what the middle panels are; full code with the actual matplotlib calls would help.) Thanks, Juan. On Thu, Jun 5, 2014 at 10:24 PM, Jean-Patrick Pommier < jeanpatrick.pommier@gmail.com> wrote:
Hi, Is it possible to skeletonize a binary 2D shape such that its skeleton is defined on a neighbourhood of 8 pixels?
When skeletonizing with : *morphology.medial_axis()* , I tried two structuring elements (se8 or se4) as mask :
se8 = np.array([[True,True,True],[True,True,True],[True,True,True]]) se4 = np.array([[False,True,False],[True,True,True],[False,True,False]])
imK = makeLetterImage('K', 70) skel = *morphology.medial_axis*(imK,mask=se8) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel)
The skeletons returned using se8 or se4 are very similar and look defined on a neighbourhood of 4 pixels (left). To me, this is a problem when trying to label the skeleton edges (right).
Jean-Patrick
-- You received this message because you are subscribed to the Google Groups "scikit-image" group. To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Hi Juan, I don't understand the option "mask" in implemented in *skimage.morphology.medial.axis()*. I supposed that mask set as a square structuring element would yield a "thick" skeleton.When applied on a test image (top green), the medial_axis with two kinds of mask (middle top) yield the same results (red). These results can be compared with mahotas.thin() (top left) or skimage.morpholgy.skeletonize() (top right). The branched points are overlaid on their skeleton (down). <https://lh3.googleusercontent.com/-rTKvmWQfn9g/U5G9ypm34jI/AAAAAAAAB2U/Q2TxChNk4Jw/s1600/skeletonsa-bp.png>
The code is: se8 = np.array([[True,True,True], [True,True,True], [True,True,True]]) se4 = np.array([[False,True,False], [True,True,True], [False,True,False]]) imK = makeLetterImage('a', 80) skel0 = morphology.medial_axis(imK,mask=se8) skel1= morphology.medial_axis(imK,mask=se4) skel2 = morphology.skeletonize(imK) skel = mh.thin(imK) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel) BP1 = branchedPoints(skel1) BP2 = branchedPoints(skel2) figsize(15,10) subplot(241,xticks=[],yticks=[]) title('mahotas thin') imshow(skel+1*imK, interpolation='nearest') subplot(242,xticks=[],yticks=[]) title('skimage medial axis se8') imshow(skel0+1*imK, interpolation='nearest') subplot(243,xticks=[],yticks=[]) title('skimage medial axis se4') imshow(skel1+1*imK, interpolation='nearest') subplot(244,xticks=[],yticks=[]) title('skimage skeletonize') imshow(skel2+1*imK, interpolation='nearest') subplot(245,xticks=[],yticks=[]) title('maho thin()+branched-points') imshow(skel+1*Bp, interpolation='nearest') subplot(246,xticks=[],yticks=[]) title('sk medial axis+branched-points') imshow(skel1+1*BP1, interpolation='nearest') subplot(248,xticks=[],yticks=[]) title('skeletonize+branched-points') imshow(skel2+1*BP2, interpolation='nearest') The complete code is in an ipython notebook (joined). Thanks Jean-Patrick Le jeudi 5 juin 2014 14:24:02 UTC+2, Jean-Patrick Pommier a écrit :
Hi, Is it possible to skeletonize a binary 2D shape such that its skeleton is defined on a neighbourhood of 8 pixels?
When skeletonizing with : *morphology.medial_axis()* , I tried two structuring elements (se8 or se4) as mask :
se8 = np.array([[True,True,True],[True,True,True],[True,True,True]]) se4 = np.array([[False,True,False],[True,True,True],[False,True,False]])
imK = makeLetterImage('K', 70) skel = *morphology.medial_axis*(imK,mask=se8) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel)
The skeletons returned using se8 or se4 are very similar and look defined on a neighbourhood of 4 pixels (left). To me, this is a problem when trying to label the skeleton edges (right).
Jean-Patrick
The ipython notebook is here <http://nbviewer.ipython.org/gist/jeanpat/da77a3b10c903f340d5c> Le jeudi 5 juin 2014 14:24:02 UTC+2, Jean-Patrick Pommier a écrit :
Hi, Is it possible to skeletonize a binary 2D shape such that its skeleton is defined on a neighbourhood of 8 pixels?
When skeletonizing with : *morphology.medial_axis()* , I tried two structuring elements (se8 or se4) as mask :
se8 = np.array([[True,True,True],[True,True,True],[True,True,True]]) se4 = np.array([[False,True,False],[True,True,True],[False,True,False]])
imK = makeLetterImage('K', 70) skel = *morphology.medial_axis*(imK,mask=se8) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel)
The skeletons returned using se8 or se4 are very similar and look defined on a neighbourhood of 4 pixels (left). To me, this is a problem when trying to label the skeleton edges (right).
Jean-Patrick
Hi Jean-Patrick, I've just had a look at the code, and it seems you've misunderstood the purpose of the `mask` keyword argument. This is not the morphological structuring element, but a binary mask overlaying the entire image and determining which pixels can and cannot be part of the skeleton. See the relevant part of the code here: https://github.com/scikit-image/scikit-image/blob/master/skimage/morphology/... My intuition is that your calls should have resulted in some kind of ValueError (since you are indexing an array with a boolean array of a different shape), but evidently that's not true. We'll have to look into updating the docs and maybe adding some input sanitising. As to your broader question, I don't think it's possible with the current codebase to do what you ask. We would need to update the lookup table connectivity parameter, which is currently hardcoded here: https://github.com/scikit-image/scikit-image/blob/master/skimage/morphology/... Is there any reason why you can't just use Mahotas? =) (Incidentally, the resolution on your characters is pretty low, which explains the wonky skeletons... Thicker characters should produce more regular skeletons, regardless of connectivity.) Juan. On Fri, Jun 6, 2014 at 11:59 PM, Jean-Patrick Pommier < jeanpatrick.pommier@gmail.com> wrote:
The ipython notebook is here <http://nbviewer.ipython.org/gist/jeanpat/da77a3b10c903f340d5c>
Le jeudi 5 juin 2014 14:24:02 UTC+2, Jean-Patrick Pommier a écrit :
Hi,
Is it possible to skeletonize a binary 2D shape such that its skeleton is defined on a neighbourhood of 8 pixels?
When skeletonizing with : *morphology.medial_axis()* , I tried two structuring elements (se8 or se4) as mask :
se8 = np.array([[True,True,True],[True,True,True],[True,True,True]]) se4 = np.array([[False,True,False],[True,True,True],[False,True,False]])
imK = makeLetterImage('K', 70) skel = *morphology.medial_axis*(imK,mask=se8) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel)
The skeletons returned using se8 or se4 are very similar and look defined on a neighbourhood of 4 pixels (left). To me, this is a problem when trying to label the skeleton edges (right).
Jean-Patrick
-- You received this message because you are subscribed to the Google Groups "scikit-image" group. To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Hi Juan, You're right, I thought that the mask was a structuring element. Regarding the way a skeleton is computed (C4 with skimage or C8 with mahotas), there's different advantages/difficulties. With a C4 skeleton, the branched points of the skeleton seems to be a unique pixel. The difficulties come when the edges (skeleton-branched points) are being labelled (on a neighbourhood of 4 or 8 pixels). If the edges derive from a c8 skeleton (mahotas.thin), labelling the edges with a neighbourhood of 4 pixel is easy. However, the use of a C8 skeleton leads to branched "domain" which can be more than one pixel. I was wondering if it was possible to have a C8 skeleton with branched domain of only one pixel. This difficulty with C8 skeletons may be bypassed now. The aim would be to convert a skeleton into a graph : some results are visible in an ipython notebook, <http://nbviewer.ipython.org/gist/jeanpat/c261d254c139d11eb6dd> up to now the code works for some cases (some explanations) .. <http://dip4fish.blogspot.fr/2014/06/graph-again.html>.By the way is there a "regular" way way to solve that problem? Best regards Jean-Patrick Le jeudi 5 juin 2014 14:24:02 UTC+2, Jean-Patrick Pommier a écrit :
Hi, Is it possible to skeletonize a binary 2D shape such that its skeleton is defined on a neighbourhood of 8 pixels?
When skeletonizing with : *morphology.medial_axis()* , I tried two structuring elements (se8 or se4) as mask :
se8 = np.array([[True,True,True],[True,True,True],[True,True,True]]) se4 = np.array([[False,True,False],[True,True,True],[False,True,False]])
imK = makeLetterImage('K', 70) skel = *morphology.medial_axis*(imK,mask=se8) Ep_Bp, Bp_Bp, Bp, Ep = SkeletonDecomposition(skel)
The skeletons returned using se8 or se4 are very similar and look defined on a neighbourhood of 4 pixels (left). To me, this is a problem when trying to label the skeleton edges (right).
Jean-Patrick
participants (2)
-
Jean-Patrick Pommier
-
Juan Nunez-Iglesias