Last active
August 29, 2015 14:02
-
-
Save jeanpat/fed4d964976a4bbbec8d to your computer and use it in GitHub Desktop.
A ipython notebook showing how to convert the skeleton of a binary image into a networkw graph
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "from skeleton to graph" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "import networkx as nx\nfrom PIL import Image, ImageDraw, ImageFont", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "\nfrom skimage import morphology as mo\nfrom skimage import measure as mea\nimport mahotas as mh", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 4, | |
"metadata": {}, | |
"source": "Some functions need to work: extraction from a skeleton of branched points, of end-points, pruning is also needed" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "def branchedPoints(skel, showSE=True):\n X=[]\n #cross X\n X0 = np.array([[0, 1, 0], \n [1, 1, 1], \n [0, 1, 0]])\n X1 = np.array([[1, 0, 1], \n [0, 1, 0], \n [1, 0, 1]])\n X.append(X0)\n X.append(X1)\n #T like\n T=[]\n #T0 contains X0\n T0=np.array([[2, 1, 2], \n [1, 1, 1], \n [2, 2, 2]])\n \n T1=np.array([[1, 2, 1], \n [2, 1, 2],\n [1, 2, 2]]) # contains X1\n \n T2=np.array([[2, 1, 2], \n [1, 1, 2],\n [2, 1, 2]])\n \n T3=np.array([[1, 2, 2],\n [2, 1, 2],\n [1, 2, 1]])\n \n T4=np.array([[2, 2, 2],\n [1, 1, 1],\n [2, 1, 2]])\n \n T5=np.array([[2, 2, 1], \n [2, 1, 2],\n [1, 2, 1]])\n \n T6=np.array([[2, 1, 2],\n [2, 1, 1],\n [2, 1, 2]])\n \n T7=np.array([[1, 2, 1],\n [2, 1, 2],\n [2, 2, 1]])\n T.append(T0)\n T.append(T1)\n T.append(T2)\n T.append(T3)\n T.append(T4)\n T.append(T5)\n T.append(T6)\n T.append(T7)\n #Y like\n Y=[]\n Y0=np.array([[1, 0, 1], \n [0, 1, 0], \n [2, 1, 2]])\n \n Y1=np.array([[0, 1, 0], \n [1, 1, 2], \n [0, 2, 1]])\n \n Y2=np.array([[1, 0, 2], \n [0, 1, 1], \n [1, 0, 2]])\n \n Y2=np.array([[1, 0, 2], \n [0, 1, 1], \n [1, 0, 2]])\n \n Y3=np.array([[0, 2, 1], \n [1, 1, 2], \n [0, 1, 0]])\n \n Y4=np.array([[2, 1, 2], \n [0, 1, 0], \n [1, 0, 1]])\n Y5=np.rot90(Y3)\n Y6 = np.rot90(Y4)\n Y7 = np.rot90(Y5)\n Y.append(Y0)\n Y.append(Y1)\n Y.append(Y2)\n Y.append(Y3)\n Y.append(Y4)\n Y.append(Y5)\n Y.append(Y6)\n Y.append(Y7)\n \n bp = np.zeros(skel.shape, dtype=int)\n for x in X:\n bp = bp + mh.morph.hitmiss(skel,x)\n for y in Y:\n bp = bp + mh.morph.hitmiss(skel,y)\n for t in T:\n bp = bp + mh.morph.hitmiss(skel,t)\n \n if showSE==True:\n fig = plt.figure(figsize=(4,5))\n tX =['X0','X1']\n tY =['Y'+str(i) for i in range(0,8)]\n tT =['T'+str(i) for i in range(0,8)]\n ti= tX+tY+tT\n SE=X+Y+T\n print len(SE), len(ti)\n n = 1\n ti = iter(ti)\n for se in SE:\n #print next(ti)\n #print se\n mycmap = mpl.colors.ListedColormap(['black','blue','red'])\n ax = fig.add_subplot(4,5,n,frameon=False, xticks=[], yticks=[])\n title(str(next(ti)))\n imshow(se, interpolation='nearest',vmin=0,vmax=2,cmap=mycmap)\n n = n+1\n fig.subplots_adjust(hspace=0.1,wspace=0.08)\n #ax_cb = fig.add_axes([.9,.25,.1,.3])#\n color_vals=[0,1,2]\n #cb = mpl.colorbar.ColorbarBase(ax_cb,cmap=mycmap, ticks=color_vals)\n #cb.set_ticklabels(['back', 'hit', 'don\\'t care'])\n \n plt.show()\n return bp > 0\n\ndef endPoints(skel):\n endpoint1=np.array([[0, 0, 0],\n [0, 1, 0],\n [2, 1, 2]])\n \n endpoint2=np.array([[0, 0, 0],\n [0, 1, 2],\n [0, 2, 1]])\n \n endpoint3=np.array([[0, 0, 2],\n [0, 1, 1],\n [0, 0, 2]])\n \n endpoint4=np.array([[0, 2, 1],\n [0, 1, 2],\n [0, 0, 0]])\n \n endpoint5=np.array([[2, 1, 2],\n [0, 1, 0],\n [0, 0, 0]])\n \n endpoint6=np.array([[1, 2, 0],\n [2, 1, 0],\n [0, 0, 0]])\n \n endpoint7=np.array([[2, 0, 0],\n [1, 1, 0],\n [2, 0, 0]])\n \n endpoint8=np.array([[0, 0, 0],\n [2, 1, 0],\n [1, 2, 0]])\n \n ep1=mh.morph.hitmiss(skel,endpoint1)\n ep2=mh.morph.hitmiss(skel,endpoint2)\n ep3=mh.morph.hitmiss(skel,endpoint3)\n ep4=mh.morph.hitmiss(skel,endpoint4)\n ep5=mh.morph.hitmiss(skel,endpoint5)\n ep6=mh.morph.hitmiss(skel,endpoint6)\n ep7=mh.morph.hitmiss(skel,endpoint7)\n ep8=mh.morph.hitmiss(skel,endpoint8)\n ep = ep1+ep2+ep3+ep4+ep5+ep6+ep7+ep8\n return ep > 0\n\ndef pruning(skeleton, size):\n '''remove iteratively end points \"size\" \n times from the skeleton\n '''\n for i in range(0, size):\n endpoints = endPoints(skeleton)\n endpoints = np.logical_not(endpoints)\n skeleton = np.logical_and(skeleton,endpoints)\n return skeleton", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "def edges_from_C8skel(c8skeleton):\n '''given a skeleton defined on c8 neighborhood (use mahotas),\n \\ returns labeled edges\n '''\n branchedP = branchedPoints(c8skeleton, showSE = False) > 0\n endP = endPoints(c8skeleton) > 0\n edges = np.logical_not(branchedP)*c8skeleton\n label_edges,ne = mh.label(edges)\n return label_edges", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 3, | |
"metadata": {}, | |
"source": "Model images will be used, images of letters can do the job, so we need to produce images of letters using PIL" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "def makeLetterImage(character, size):\n image = Image.new(\"RGBA\", (600,150), (255,255,255))\n draw = ImageDraw.Draw(image)\n font = ImageFont.truetype(\"verdana.ttf\", size)\n \n draw.text((5, 0), character, (0,0,0), font=font)\n img_resized = np.array(image.resize((300,75), Image.ANTIALIAS))\n letter = img_resized[0:40,0:30,0]<64\n r1 = mh.bbox(letter)[0]\n r2 = mh.bbox(letter)[1]\n c1 = mh.bbox(letter)[2]\n c2 = mh.bbox(letter)[3]\n letter = letter[r1-1:r2+1,c1-1:c2+1]\n return letter", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "imA = makeLetterImage(\"A\", 70)\nimB = makeLetterImage(\"B\", 70)\nimH = makeLetterImage(\"H\", 70)", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "\nsubplot(131)\nimshow(imA, interpolation='nearest')\nsubplot(132)\nimshow(imB, interpolation='nearest')\nsubplot(133)\nimshow(imH, interpolation='nearest')", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 7, | |
"text": "<matplotlib.image.AxesImage at 0x3338490>" | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "display_data", | |
"png": "iVBORw0KGgoAAAANSUhEUgAAAW8AAACdCAYAAAB7EfmyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEelJREFUeJzt3V9sU+UbB/Dv+Sl3YMCEdZVOzwQGCOxPmGCIczXQIRcM\nCIZAdC5suyHBhIwYdsfwgpVENIhcIEEzNFnAC/5cyARiOnFGd2GniRghceeXBbtGQAKDRGC8vwto\nf+3WdafnnLen7+n3kzTruu7psz7d09P3Pee8mhBCgIiIlPIftxMgIqLcsXkTESmIzZuISEFs3kRE\nCmLzJiJSEJs3EZGC2Lxpgt7eXixcuBDz58/H/v373U6HHMK6eovG/bwp1djYGBYsWICLFy9izpw5\nePnll9HT04NFixa5nRrZwLp6z9NuJ0CFZWBgAPPmzYOu6wCALVu24MyZM2n/5JqmA/ivG+lRmhcg\nhGHqnqyrSszVlc2b0ly7dg1lZWXJ7wOBAH766adx9/ovgD0AIgCCkjKRGVt2fJmxU+PvNf0bhVNX\nSI6vauzU+ObqyjFvSqNpmtspkASsq/eweVOaOXPmYHh4OPn98PAwAoFAhntGABgpX0k+A+nPu3ms\nayEzYKWulodNent7sXPnToyNjaGtrQ27d++2GooKSG1tLa5evQrDMPDcc8/hxIkT6OnpyXDPIB6/\n2HQAwJ4cPsKb8Thyn6MxnY6/F3sm+YluK+7k9CcX48lX8/nnu66TPzeAvOfH3dj2nisdudbVUvMe\nGxvDjh070mauGxsbOXPtAU8//TQ++eQTrFmzBmNjY2htbc1SV11aHvIi5yO+3OhW4hdKXeXHVzV2\n7vEtNW/OXKvG/F4JALB27VqsXbtWXjrkCtbVWyw179xmrgE5s7SqxJQVN5eYzg5pEJH7LDVv8zPX\nkSdfDaSOo5FsBjjZJJ+ZMc7sY79E1llq3uZnroNPvkZQSI17sn+6CICgjUmswvlH1ZH+fMub+CMi\nd1jaVTB15vr+/fs4ceIEGhsbs/yGbi27rJyP6XxEmZFlxCQiVVja8s5t5hpQpXk5H1FmZBkxiUgV\nlvfz5sw1EZF7eG4TclXhzBOkc+qgo0xxCvVvJrXw8HgiIgWxeRMRKYjNm4hIQWzeREQKKooJS6fP\neGf2cTgxpS4ztcvX64ooE255ExEpiM2biEhBbN5ERAoqijFvK8aPeRbT+Kau63jmmWfw1FNPYdq0\naRgYGHA7JXIA6+otbN40gaZpiEQiePbZZ91OpaBlmtQ08ybv1lGXrKu3cNiEMhJCuJ0CScC6eoet\n5q3rOiorK1FTU4Ply5c7lRO5TNM0rF69GrW1tTh69Kjb6ZBDWFdvsTVswo9h3tTf3w+/34+///4b\noVAICxcuRF1d3bh7RVKu6/lLrqgZsLNCEutaqAxYqavtMW9+DPMev98PAJg9ezY2btyIgYGBDP/k\nwbznRTrsrJDEuhYqHVbqamvYhB/DvOfevXu4c+cOAODu3bs4f/48li5d6nJWZBfr6j22tryn/hgW\nSbmugx/D8sWA1Y/X8XgcGzduBAA8fPgQb731FhoaGhzLjNzBunqPreY99cewoJ3wZJkOqx+vy8vL\nMTg46HA+5DbW1XssN+979+5hbGwMM2bMSH4M27PH/RMxWTmYxsw+tlb26eUqKkQki+XmzY9hRETu\nsdy8+TGMiMg9PMKSiEhBbN5ERApi8yYiUhDPKkiUZ9zjiJzALW8iIgWxeRMRKYjNm4hIQWzeREQK\n4oQlkUXFtK4pFR5ueRMRKUj5LW9ZJ6KyEsfK4rPcbYyIrOCWd5FqaWmBz+dLOyH/zZs3EQqFUFFR\ngYaGBty6dcvFDMkK1rV4TNm8+WLwpm3btqG3tzfttnA4jFAohCtXrmDVqlUIh8MuZVd49mDvhIsZ\nE39L7ict1rV4TNm8+WLwprq6OsyaNSvttrNnz6K5uRkA0NzcjNOnT7uRGtnAuhaPKZs3XwzFIx6P\nw+fzAQB8Ph/i8bjLGZETWFdvsjRhyReD92maBk3TstwjknJdl5sMPWHA6tqkCaxrITJgpa629zaZ\n+sVAqvD5fBgZGUFpaSlisRhKSkqy3DuYr7QoSYeVtUlZ10Knw0pdLTVv8y+GSJYESR4DVt7JGxsb\n0d3djd27d6O7uxsbNmxwOrEJvHagSyHu+sm6epOlXQUTLwYAU7wYgikX3cpDkSU60p/7ibZu3YqV\nK1fijz/+QFlZGT7//HN0dHTgwoULqKiowLfffouOjo58JUwOYV2Lx5Rb3lu3bkVfXx+uX7+OsrIy\nvP/+++jo6MDmzZtx7Ngx6LqOkydP5iNXclBPT0/G2y9evJjnTMhJrGvxmLJ588VARFR4eIQlEZGC\nlD+3CVEh4blrKF+Ua95unogq18fhiaqISBYOmxARKYjNm4hIQWzeREQKUm7Mm0gluZw61ku89veY\nke+jSrnlTUSkIDZvIiIFsXkTESmooMe8C3mfblky/c2q/03ZeO1vszruWWx1J/u45U1EpCA2byIi\nBVlaPb6zsxOBQAA1NTWoqamZsEAxERHJZWn1eE3T0N7ejmg0img0ijfeeENagirbiz0TLoWCb8re\nxLoWjyknLOvq6mAYxoTbhRAy8qE82bZtG95991288847ydsSb8rt7e0uZqY2KycncxLrWjwsj3kf\nOnQIVVVVaG1txa1bt5zMifKgrq4Os2bNmnA735TVxroWD0vNe/v27RgaGsLg4CD8fj927do1yT0j\nKRfDykORJQbSn3vz+KbsTayr91hq3iUlJdA0DZqmoa2tDQMDA5PcMwguQOwGHVMtQJyJ+TdlgG/M\nbjBg5U2ZdS10BqzU1dJBOrFYDH6/HwBw6tSptMkRt+V7jNFLSkpKktfb2tqwbt26LPcOSs+HxtOR\nvhHUZ+q3WNdCp8NKXXNePX7v3r2IRCIYHByEpmkoLy/HkSNHLKVMhaWQ35SLkVOrLLGu3mRp9fiW\nlhYpyVD+8E3Zm1jX4lHQ5zYhefim7E2sa/EoqObN8erMuEgxEY3Hc5sQESmooLa8ibwm06ckfsIk\nJ3DLm4hIQWzeREQKYvMmIlIQmzcRkYLYvImIFMTmTUSkIOV3FVT9gBXuNkZEVnDLm4hIQVmb9/Dw\nMF5//XUsXrwYS5YswccffwwAuHnzJkKhECoqKtDQ0MCTuxMR5VnW5j1t2jR89NFH+O233/Djjz/i\n8OHD+P333xEOhxEKhXDlyhWsWrUK4XA4X/kSERGmGPMuLS1FaWkpAGD69OlYtGgRrl27hrNnz6Kv\n7/EJw5ubmxEMBi01cCvjvaqPcY9nZcFanqiKiEyPeRuGgWg0ihUrViAej8Pn8wEAfD4f4vG4tATJ\neRwO8y7WtniYat6jo6PYtGkTDh48iBkzZqT9LLGWZWYRcD08NxjItiYeh8O8i7UtHlPuKvjgwQNs\n2rQJTU1N2LBhA4DHW9sjIyMoLS1FLBZLWyMvXdDBVMk8HdnWxJM9HEb/Z2dXUCvDYaxt8ci65S2E\nQGtrK1566SXs3LkzeXtjYyO6u7sBAN3d3cmmTurhcJh3sbbelnXLu7+/H19++SUqKytRU1MDAOjq\n6kJHRwc2b96MY8eOQdd1nDx5Mi/JkrOsD4cB6cMxuoTsaCIDZocf7Q11Jug5Z0hWGLAyrJy1eb/6\n6qt49OhRxp9dvHgx5wejwmFvOAzgkJgbdGQbDkvgUKdqdJip63g8wrIIcTjMu1jb4qH8uU0odxwO\n8y7WtniweRchDod5F2tbPDhsQkSkIDZvIiIFcdiEyCInz8XO89NQrvLWvHkSKnMy/c1TPXeZfl6M\nzx1RMeGwCRGRgti8iYgUxOZNRKQgTliSq7gAM5E13PImIlIQmzcRkYIsrR7f2dmJQCCAmpoa1NTU\noLe3Ny/JEhHRY1nHvBNLKlVXV2N0dBTLli1DKBSCpmlob29He3t7vvIkIqIUllaPBx6fepKIsuPB\nUiRLzqvHv/LKKwCAQ4cOoaqqCq2trVyJmogoz0yvHv/mm2/i4MGDmD59OrZv346hoSEMDg7C7/dj\n165dk/xmJHkxnMmXTDAAZFs9nnMZ3sXaFg/Tq8e//fbbydU3UpdQamtrw7p16yb57WDymm5yaR+y\nTweQvpxV+nPPuQzvYm2LR9bmPdmSSrFYDH6/HwBw6tQpLF26dIqHMSSM/RlwfoFUGTHtx8383FmP\nybkM72Jti0fOq8fv27cPPT09GBwchKZpKC8vx5EjR6Z4GANqNFoZMWXFdSZm6lxGf38/Dh06hOPH\nj6O2thYHDhzAzJkzbT+GF6g48cjaelvWMe/EkkqDg4OIRqOIRqNYu3Ytjh8/jl9//RW//PILTp8+\nDZ/Pl698yUHW5zKo0LG23sdzmxQpe3MZQPpEqC4jRZrAAExM/durbSTlum4tTcqRATN1HU9a866v\nr0dfX+pJh2RMWKoSU1ZcczHr6+vTvndmLiOYa7Jkm470hjqx/vZrG3QoVzJPx1R1zUQTnMUoOt9/\n/z1ee+01VFZWQtM0AJPPZWQaEnv8O+qNAXvP3gmTkHZqy7oWiol1zYTNm3L2/39yA/I+WsuMLTu+\nzNip8c39k5uVn7pCcnxVY6fGN1dXnlWQbDAUjS07vszYjO/N2LnHZ/MmIlKQ1Obd29uLhQsXYv78\n+di/f79jcXVdT+57vnz5cksxWlpa4PP50iZubt68iVAohIqKCjQ0NOR8zpZMMZ04LHmyQ57t5ktE\nChOSPHz4UMydO1cMDQ2J+/fvi6qqKnH58mVHYuu6Lm7cuGErxnfffSd+/vlnsWTJkuRt7733nti/\nf78QQohwOCx2795tO2ZnZ6c4cOCArVxjsZiIRqNCCCHu3LkjKioqxOXLl23na1V9fb0AwIvLl/r6\netbVgxezdZW2q+DAwADmzZsHXdcBAFu2bMGZM2ewaNEiR+ILmxM1dXV1MAwj7bazZ8+ir+/xbjrN\nzc0IBoMIh8O2YgL2c53skGe7+VoViUSkPwblH+uqFmnDJteuXUNZWVny+0AgkDzHgl2apmH16tWo\nra3F0aNHHYkJAPF4PLn7lM/nQzwedySuk6fPTRzyvGLFCmn5ElHhk9a8E/uYytDf349oNIpz587h\n8OHDuHTpkuOPoWmaI3+Dk4clj46OYtOmTTh48CBmzJiR9jOn8iUiNUhr3nPmzMHw8HDy++HhYQQC\nAUdiJ44Umz17NjZu3IiBgQFH4vp8PoyMjAB4fERa6iHFVpWUlCQba1tbm+VcE4c8NzU1JQ95lpGv\nGbImohOcmJBOkDExPVV8p86d7cZEtczaOllXQG5tlairozMeKR48eCBefPFFMTQ0JP7991/HJizv\n3r0rbt++LYQQYnR0VKxcuVJ88803lmINDQ1NmLAMh8NCCCG6urosTQCOj/nXX38lr3/44Ydi69at\nOcd89OiRaGpqEjt37ky73Yl8cyVzIjrBiQnpBBkT01PFd2KSWoj8T1TLrq2TdRVCbm1VqKu05i2E\nEF9//bWoqKgQc+fOFfv27XMk5p9//imqqqpEVVWVWLx4seW4W7ZsEX6/X0ybNk0EAgHx2WefiRs3\nbohVq1aJ+fPni1AoJP755x9bMY8dOyaamprE0qVLRWVlpVi/fr0YGRnJOddLly4JTdNEVVWVqK6u\nFtXV1eLcuXO287Xihx9+EGvWrEl+39XVJbq6uhx9DF3XxfXr1x2LN/4NdcGCBck6xGIxsWDBAkfj\nd3Z2ig8++MBWzEzWr18vLly44Hj+CbJr63RdhZBb20Kvq9TmTd7z1Vdfiba2tuT3X3zxhdixY4ej\nj1FeXi6qq6vFsmXLxKeffmo73vh/wpkzZyavP3r0KO17J+J3dnaKF154QVRWVoqWlhZH3lSHhobE\n888/L27fvu14/gmya+t0XYWQW9tCryuPsKSc5GNSNB8T0gkyJnqdPnd2viaqZdc2n3UFnK9todWV\nzZtyInMiOkHWhHSC7IlepyapgfxOVMuurey6AnJrW2h1ZfOmnNTW1uLq1aswDAP379/HiRMn0NjY\n6Fj8e/fu4c6dOwCAu3fv4vz58ybWSM1NY2Mjuru7AQDd3d3Jfx6nxGKx5HVza7xmJiY5N7es/GXW\nNh91BeTWtuDqanvQhoqOjInoBKcmpBNkTExni+/UJLUQ7kxUy6qt03UVQm5tVagrz+dNRKQgDpsQ\nESmIzZuISEFs3kRECmLzJiJSEJs3EZGC2LyJiBTE5k1EpCA2byIiBf0P/Kc980sPqqQAAAAASUVO\nRK5CYII=\n", | |
"text": "<matplotlib.figure.Figure at 0x3285510>" | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 3, | |
"metadata": {}, | |
"source": "Let's generate the C4 skeleton (medial axis) of a binary image with scikits-image" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "medaxA = mo.medial_axis(imA)\nma_bpA = branchedPoints(medaxA, showSE = False)\nma_epA = endPoints(medaxA)\nma_edgesA = edges_from_C8skel(mo.skeletonize(imA))#np.logical_not(ma_bpA)*medaxA", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "figsize(12,12)\nsubplot(141, xticks=[],yticks=[])\ntitle('Medial Axis (C4)')\nimshow(medaxA, interpolation='nearest')\nsubplot(142, xticks=[],yticks=[])\ntitle('Branched Points')\nimshow(ma_bpA, interpolation='nearest')\nsubplot(143, xticks=[],yticks=[])\ntitle('End Points')\nimshow(ma_epA, interpolation='nearest')\nsubplot(144, xticks=[],yticks=[])\ntitle('Labeling of medial axis-BP')\nimshow(ma_edgesA, interpolation='nearest')", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 15, | |
"text": "<matplotlib.image.AxesImage at 0x56ffb10>" | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "display_data", | |
"png": "iVBORw0KGgoAAAANSUhEUgAAArIAAADICAYAAAAUXwIOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAH9NJREFUeJzt3XlwFGX+x/HPhEuOnJwJMYnAIrgcy5JFYFVQFAFhjSII\nyuUqK4oHlwf7AxOQAtHCc0tE5RRQdFUQJQoIUcFCthYFBJSFlSDhSiCEBAiB5Pv7g0pvJpkZAoSQ\nxveraqqYvp5nep7u/uSZ7gePmZkAAAAAlwm61BUAAAAAzgdBFgAAAK5EkAUAAIArEWQBAADgSgRZ\nAAAAuBJBFgAAAK50WQfZoKAg/fe//5UkPfTQQ5o0aVKp1uvcubNmzpxZ5vXZvXu3goODdT4jnm3d\nulV/+tOfyqwu1157rbZu3Vpm28OlVbStX6iL0f6nTJmioUOHluk2cflISkrSwIEDy3Sb33zzjZo1\na1am28SFuZBzS9F1FyxYoFtvvbUsq1YqJ06cUK9evRQWFqa77767XMvetWuXgoKCVFBQIEnq0aOH\n3nnnnVKtGxcXpy+//LLM6xQcHKxdu3aV+XbPVYUIsnFxcapWrZoOHTrkNb1NmzYKCgrS7t27L7iM\n6dOna9y4caVa1uPxyOPxBFxmzpw5CgoK0vvvv1/qOsTExCg7O/us2/Zl/PjxeuKJJ7ymLVy4UPHx\n8QoODlZUVJR69OihtWvXlli3S5cuXgeAJI0ZM0bPPPPMOdcD/xMXF6caNWooODhYERER6tmzp/bs\n2XOpq3XBArX/pKQkValSRcHBwQoPD9ef//xnrVu37qzbHDt2rN56661SlX8xQg3KXtH2X/h67LHH\nzmtbgc6JKSkpCgoKUnBwsEJCQtSsWTPNmTPnrNu8/vrr9dNPP5Wq/JSUFF155ZWlre5v3vkGo9Jc\nW0uz7r333qsvvvjivLZzIf75z3/q4MGDOnz4sBYtWlTu5Re1bNmyUp8nL2S/B5Kdna24uLhzWqfo\n8RwcHKzo6GglJSV5LRMUFKRatWo580ePHu2VX4qrEEHW4/GoUaNGevfdd51pmzdv1okTJy7Kzi8L\nc+fOVcuWLTVv3ryLXta+ffuUkpKihIQEZ9qLL76okSNHaty4cTp48KB+/fVXDR8+XJ988onXugsW\nLNDp06dL7MdevXpp9erVOnDgwEWv/+XK4/Ho008/VXZ2tvbt26f69evr0Ucf9bt8oAPRLTwej/r3\n76/s7Gylp6fruuuu05133nmpq4VLoGj7L3y9+uqrF6Wshg0bKjs7W0ePHtXUqVM1dOhQbdu27aKU\nhbO7WMGooktNTVXTpk0VFFQhopNrFR7P2dnZWrNmjWbOnKklS5Z4LbNp0yZlZ2fryy+/1MKFCwN2\nhFSYb2PAgAFeoXDu3LkaNGiQ18/wJ0+e1JgxYxQbG6sGDRrooYceUm5urjP/hRdeUFRUlKKjozVr\n1iyv7Q8ZMkTjx4+XJGVmZqpnz56qV6+eIiIi1KtXL6WlpZW6rqmpqVq7dq1mz56tFStWeIXBqVOn\nqn379srPz5d0pie4RYsWysvLK/HTwJw5c9S4cWOFhISoUaNGWrhwoc/yVqxYobZt26pq1aqSpKys\nLCUmJur1119XQkKCqlevrkqVKum2227T1KlTnfWysrI0ceJEPf/88yVuZ7jiiivUtm3bS/JX7eWo\nWrVq6t27t9ftGkOGDNFDDz2kHj16qFatWkpJSdFnn32mNm3aKDQ0VDExMZowYYKzfGH7mDdvnmJj\nY1W3bl1NnjzZmV9QUKDJkyerSZMmCgkJUXx8vFe7XbFihZo2barw8HA98sgjXvWbNWuWrrnmGkVE\nRKhbt25ev3KsWLFCzZo1U1hYmB599FGZmd/bX4rOq1y5sgYNGqT9+/fr8OHD2rt3r/7yl7+odu3a\n+t3vfqe3337bWa9oL2ugz/n5559rypQpWrRokYKDg9WmTRtJpT9WUDHMmTNH1113nZ544glFRESo\nUaNG+vzzz535v/zyizp16qSQkBB17dpVGRkZpd727bffrvDwcG3btk15eXkaMWKEGjZsqIYNG2rk\nyJHKy8uTVLKXNS4uTtOmTVPr1q0VFhamfv366eTJkzp27Ji6d++uvXv3Or2++/fv1/r16xUfH6/Q\n0FA1aNBAo0ePLrsddJk6cuTIWa+tO3bs0LXXXqvQ0FAlJCQoMzPTmbdu3Tp17NhR4eHh+sMf/qCv\nvvrKZzlz5szR9ddf77wPCgrSjBkzfJ7/CgoKNHr0aNWtW1eNGjXSP/7xjxK/UBa1bds2de7cWeHh\n4WrRooWWLl0qSUpMTNSzzz7rnJtmz55dYt2kpCT16dNHAwcOVEhIiFq1aqX//Oc/mjJliurXr6/Y\n2FitWLHCWT4rK0v333+/k1vGjx/v1KugoEBjxoxR3bp11bhxY3322WdeZRW91WLnzp266aabVKdO\nHdWtW1cDBgxQVlaWz89XXKBr0qJFi9SoUSNlZ2dLkpKTkxUZGen8el70lrZly5bp97//vUJCQhQd\nHa1p06aVqvy4uDh17NjR762OV199ta6//npt2bLF/0asAoiLi7OVK1fa1Vdfbdu2bbPTp09bdHS0\npaammsfjsdTUVDMzGzFihN1+++2WmZlp2dnZ1qtXLxs7dqyZmSUnJ1v9+vVty5YtduzYMevfv795\nPB7buXOnmZkNGTLExo8fb2Zmhw4dso8++shOnDhh2dnZ1qdPH0tISHDq07lzZ5s5c6bf+k6cONFu\nvvlmMzPr2LGjTZs2zZlXUFBgN9xwgyUlJdn27dstPDzcfvjhBzMz++WXX8zj8Vh+fr7l5ORYSEiI\nbd++3czM9u/fb1u2bPFZ3pgxY+yRRx5x3icnJ1vlypUtPz8/4H59+OGH7eWXX/Yqt6jHHnvMRo0a\nFXAb8K+w3ZqZHTt2zAYNGmSDBw925g8ePNhCQ0Pt22+/NTOz3NxcS0lJsR9//NHMzDZt2mT169e3\nxYsXm9n/2sff/vY3y83NtY0bN1q1atXsp59+MjOz559/3lq2bOm0mY0bN9qhQ4fMzMzj8VivXr0s\nKyvLdu/ebXXr1rXPP//czMwWL15sTZo0sZ9++sny8/Nt0qRJ1rFjRzMzS09Pt+DgYPvwww/t9OnT\n9tJLL1nlypX9tv/ExEQbMGCA83nGjBljsbGxZmZ2/fXX2/Dhw+3kyZP2ww8/WN26dW3VqlVmZpaU\nlOSsd7bPmZSUZAMHDnTKPJdjBeWnaPsvbvbs2ValShV7++23raCgwKZPn25RUVHO/Pbt29vo0aMt\nLy/Pvv76awsODvb6zotavXq1RUdHm5lZfn6+ffTRR1a1alXbvn27jR8/3jp06GDp6emWnp5uHTt2\ndM7zRdcrrO+1115r+/bts8OHD1vz5s3tjTfeMDOzlJQUr2UL6zh//nwzO3N8r1u37jz31OUnLi7O\nvvzyyxLTz3Zt7dSpkzVs2NC5Tvfu3ds5L+zZs8dq165tycnJZma2YsUKq127tmVkZJiZ93V59uzZ\ndt111znbDXT+mz59ul1zzTWWlpZmmZmZ1qVLFwsKCvJ5/czLy7PGjRvblClT7NSpU7Zq1SoLDg62\nn3/+2cxKnpuKS0xMtCuuuMKWL19up0+ftkGDBllsbKxNnjzZTp8+bW+99ZZdddVVzvIJCQk2bNgw\nO378uB08eNDatWtnM2bMcOrdrFkz27Nnjx0+fNg6d+7sVe+i+2PHjh22cuVKy8vLs/T0dLvhhhts\nxIgRZ/2+zCzgNcnM7N5777UhQ4ZYRkaGRUVF2Weffea13wszVoMGDWzNmjVmZnbkyBHbsGGDz/KK\nH5fbt2+3hg0b2urVq722u2PHDjMz27JlizVo0MBmzZrld79XqCA7adIkGzt2rCUnJ1vXrl3t9OnT\nTpAtKCiwmjVrOjvNzOzbb791GsV9993nhFqzMzuneJAdN26cz/K///57Cw8Pd96fLcg2adLEaWwv\nvfSStW7d2mv+rl27LCIiwpo3b27PPfecM714kA0LC7MPP/zQjh8/HnD/DB061J5++mnn/fz5861B\ngwYB1/nXv/5lbdq0sfz8fL9B9v/+7//sr3/9a8DtwL/Y2FirVauWhYWFWZUqVaxhw4a2efNmZ/6Q\nIUO8gq0vjz/+uI0cOdLM/tc+0tLSnPnt2rWzRYsWmZlZ06ZN7ZNPPvG5HY/HY2vXrnXe9+3b16ZO\nnWpmZt26dfNqz/n5+VajRg1LTU21uXPnWocOHby2FR0dHTDIVq1a1cLCwqxevXrWpUsX27Bhg+3e\nvdsqVapkOTk5zrJjx461IUOGOOsVD7L+PmfRZc3snI4VlJ+i7b/w9fbbb5vZmaDRpEkTZ9ljx46Z\nx+OxAwcOWGpqqlWuXNnru7znnnu8vvOiVq9ebUFBQRYWFmYRERHWpk0bp600btzYCT5mZl988YXF\nxcU56xUPsgsWLHDeP/nkkzZs2DCfy5qZ3XDDDZaYmGjp6enntX8uZ4GCUVG+rq1Fr9Nbt261qlWr\nWn5+vj333HMlQuKtt95qc+fOddYNFGT9nf9uvPFGe/PNN515K1eu9Hk9NDP7+uuvS1xb+/fvb0lJ\nSWZW8txUXGJionXt2tV5/8knn1itWrWsoKDAzMyOHj1qHo/HsrKybP/+/VatWjU7ceKEs/zChQvt\nxhtvdOpdmDPMzJYvX+5V70A55eOPP7Y2bdo470v7fZl5X5PMzoTSmJgYa9mypXO8FCqasWJiYmzG\njBmWlZUVcPtFj+eQkBDzeDzWu3dvy8vL89puSEiIhYeHW+PGjW38+PHOPvSlwtxa4PF4NHDgQC1Y\nsMDnbQXp6ek6fvy42rZtq/DwcIWHh6t79+7OT1L79u3z+hkpJibGb1nHjx/Xgw8+qLi4OIWGhqpT\np07Kysoq1WgCa9eu1a5du5z7Au+66y5t3rxZGzdudJaJjY1V586dlZqaquHDh/vcTs2aNbVo0SK9\n8cYbioqKUs+ePfXzzz/7XDY8PNzp2pek2rVrKyMjw+9PIwUFBXr44Yf18ssve93LU/zzHT16VOHh\n4Wf9zPDN4/FoyZIlyszM1MmTJ/Xaa6+pU6dOOnjwoLNM8QdIvvvuO914442qV6+ewsLCNGPGjBIP\nOTZo0MD5d40aNZSTkyNJ2rNnjxo3buy3Pv7WS01N1eOPP+4cN7Vr15YkpaWlad++fYqOjvbaztke\nern77ruVmZmpAwcOaOXKlWrTpo327t2riIgI1axZ01kuJiYm4C07/upb3LkcKyg/Rdt/4ev+++93\n5hf/fiUpJydHe/fuVXh4uKpXr+7Mj42NDVhWVFSUMjMzdejQIW3YsEF9+/aVJO3du9dr3ZiYGO3d\nu9fvdorWqXr16n7bnCTNnDlT27dvV/PmzdWuXbsSP+2ipNJcW4tfp0+dOqWMjAylpqbqgw8+cM5T\n4eHhWrt2rfbv31+qsv2dT4png+Lnu6L27t1b4vwXGxt7Trce1qtXz/l39erVVadOHed+4sI2n5OT\no9TUVJ06dUqRkZHO5x02bJjS09N91jtQpjlw4ID69eun6OhohYaGauDAgSWuK/6c7ZoUGhqqu+66\nSz/++GPA22s+/PBDLVu2THFxcercubPzEHD37t2dB7sKn4MqPJ6zsrJ05MgRXXHFFRo8eLDX9r7/\n/nsdPnxYO3bs0MSJEwPek11hgqx05otq1KiRkpOTSzxAUqdOHVWvXl1bt251TppHjhzR0aNHJUmR\nkZFe9/35GumgcEdMmzZN27dv1/r165WVlaWvvvoq4H2BRc2dO1dmppYtWyoyMtIZEmvu3LnOMp99\n9pnWrVunLl26aMyYMX631bVrVy1fvlz79+9Xs2bN/A5P1KpVK23fvt1536FDB1WrVk0ff/yxz+WP\nHj2qf//737r77rsVGRmpdu3aSTpzABcd1WDbtm1q3br1WT8zzs7j8eiOO+5QpUqVtGbNGr/L3XPP\nPUpISNCePXt05MgRDRs2rNQPgV155ZXasWPHOdctJiZGb775plfgOHbsmDp06KDIyEj9+uuvzrJm\n5vW+OI/H4/M4iYqK0uHDh72Cwe7duwNeNAKVUVxpjxVUfJGRkcrMzNTx48edaampqef18FBUVJTX\n8D+7d+9WVFTUOW/HV9lNmjTRwoULlZ6erqeeekp33XWXTpw4cc7b/i0pzbW1+HW6SpUqqlu3rmJi\nYjRw4ECv81R2draefPLJC6pT8XNcoPNbVFSUfv31V6/6pqamlvo8di5t+Morr3RGayr8vFlZWdq8\nebNT77NlmkJ///vfValSJf3444/KysrSO++8U+rrytmuST/88INmz56te+65J+DDzPHx8Vq8eLHS\n09OVkJDg/LGZnJzsPNjVv3//EuuFhISof//+zr3I56NCBVnpzF/Bq1at8vprXTpzU/HQoUM1YsQI\n5y+WtLQ0LV++XJLUt29fzZkzR9u2bdPx48e9bliWvB9SycnJUfXq1RUaGqrDhw+XWLZw+eJyc3P1\n/vvv66233tLGjRud12uvvaaFCxcqPz9fGRkZGjp0qGbOnKk5c+Zo6dKlSk5OLrGtgwcPasmSJTp2\n7JiqVKmimjVrqlKlSj73yc0336wNGzY4DzGEhoZq4sSJGj58uJYsWaLjx4/r1KlTSk5O1lNPPaWw\nsDDt27fPqd+yZcskSRs2bHBCbW5urjZs2KBbbrnF/5eBsypsJ2bm9E41b97ca15ROTk5Cg8PV9Wq\nVbV+/XotXLiw1Ce/Bx54QOPHj9eOHTtkZtq0aZMOHz7st16F5Q8bNkyTJ092bqbPysrSBx98IOnM\nWIRbtmzRxx9/rNOnT+vVV18N2APi74+9K6+8Uh07dtTYsWN18uRJbdq0SbNmzdKAAQNK9dmKatCg\ngXbt2uWUdS7HCspXaf74Ly42Nlbx8fFKTEzUqVOntGbNGn366afnVX7//v01adIkZWRkKCMjQxMn\nTjyvodvq16+vQ4cOOR0jkjR//nznWhMaGiqPx8PT6kXk5eUpNzfXeZ0+ffqs11Yz0/z5853r9DPP\nPKM+ffrI4/FowIABWrp0qZYvX678/Hzl5uYqJSXlnHpDi5ZT2Db79u2rV155RXv37tWRI0c0depU\nv+fc9u3bq0aNGnr++ed16tQppaSk6NNPP1W/fv1KXW5pRUZGqmvXrho1apSys7NVUFCgnTt36uuv\nv3bq/eqrryotLU2ZmZl67rnn/G4rJydHNWvWVEhIiNLS0vTCCy+Uuh6Brkm5ubkaMGCApkyZolmz\nZiktLU3Tp08vsY1Tp05pwYIFysrKUqVKlRQcHFzqc3ROTo7ee+89tWjRotR1Lq7CHZWNGjXSH//4\nR+d90QY3depUNWnSRO3bt1doaKhuueUWp6eyW7duGjFihG666SY1bdpUXbp08Vq36HAhI0aM0IkT\nJ1SnTh117NhR3bt3L9GwfTX0xYsXq2bNmho0aJDq1avnvO677z7l5+fr888/14MPPqiEhAR169ZN\nERERmjlzph544AHnyczC7RYUFOill15Sw4YNVbt2bX3zzTc+G4h05iR70003afHixc60UaNG6cUX\nX9SkSZNUr149xcTE6PXXX9cdd9whSV71K/xpo379+qpSpYokaenSpbrxxhu9fo7BuevVq5eCg4MV\nGhqq8ePHa968eU6Q9TVEzeuvv65nnnlGISEhevbZZ0sMqh0o1I4aNUp9+/ZV165dFRoaqqFDhzqj\ndvhqv4XTEhIS9NRTT6lfv34KDQ1Vy5YtndEq6tSpow8++EBPP/206tSpox07dui6667zW4dAw+68\n++672rVrl6KionTnnXdq4sSJuummm3yuF+hz9unTR9KZW2ji4+PP6VhB+Sps/4Wv3r17S/LdToq+\nX7hwob777jtFRERo4sSJJX5WLM5fexk3bpzi4+PVqlUrtWrVSvHx8V7jhQdqZ0Xr2KxZM/Xv31+N\nGjVSRESE9u3bpy+++EItWrRQcHCwRo4cqffee0/VqlULvEN+Q3r06KEaNWo4r4kTJ5712urxeDRo\n0CANGTJEkZGRysvLc4Zsi46O1pIlSzR58mTnmjZt2jSf4fBs55Oi84cOHaquXbuqVatWatu2rW67\n7TZVqlTJ5x8lVapUcTqf6tatq0ceeUTvvPOOmjZt6rPcs9XLX90KzZs3T3l5ec6IMn369HE6EoYO\nHapbb71VrVu3Vnx8vHr37u237MTERG3YsEGhoaHq1atXwGWLK35NKuxJlc6M/x0bG6sHH3xQVatW\n1fz58zVu3Djt3LmzxGeZP3++rrrqKoWGhurNN9/UggUL/O6jwhFCgoODFRcXpyNHjngtf66/znjs\nfP6kRrnbtm2bBg8erPXr15fJ9tq3b+8MyQQAwG9BcnKyHnrooQrxP1KhbBBkAQDAZSk3N1erVq1S\n165ddeDAAfXu3VsdO3bUiy++eKmrhjJCkAUAAJelEydOqFOnTvrpp59UvXp19ezZU6+88opq1ap1\nqauGMkKQBQAAgCtVuIe9AAAAgNKoHGimxxMnKbVcKoLLWazMdpVribRdXLjyb7cSbRdlgXMu3Orc\n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\n", | |
"text": "<matplotlib.figure.Figure at 0x4cc2e90>" | |
} | |
], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": "## The aim is to extract the skeleton edges defined as the skeleton deprived of the branched points \n### Let's label the edges obtained from medial axis computed with scikit-image:\n### 1.with mahotas using a neighborhood defined on 4 pixels. \n### 2.with skimage using a neighborhood defined on 8 pixels." | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "edgesA_lab_mh4, _ = mh.label(ma_edgesA)\nedgesA_lab_sk8 = mo.label(ma_edgesA, neighbors=8)", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 17 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": "## C4 or C8 labelling of C4 skeleton fails to isolate edges:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "figsize(7,7)\nsubplot(121, xticks=[],yticks=[])\nimshow(edgesA_lab_mh4, interpolation='nearest')\nsubplot(122, xticks=[],yticks=[])\nimshow(edgesA_lab_sk8, interpolation='nearest')", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 19, | |
"text": "<matplotlib.image.AxesImage at 0x5810bd0>" | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "display_data", | |
"png": "iVBORw0KGgoAAAANSUhEUgAAAZQAAADeCAYAAAAacfYeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABUVJREFUeJzt3b+KXGUcgOFzNBegYKFYKNimsNNu0on3ECy1ErZLubOl\n3YKVlrLXoNhlu9ilsBW0EC0svAE5dsbAzpkk+87MzpnnaT+W/WDmx8s3nD/jNE3TAAC39NqhNwDA\nMggKAAlBASAhKAAkBAWAxL25xXF8fxiG3/ayEdid94Zp+vXQmxiGwUyxFDfP1Dh32fA4jsMwnO9w\nU7APF8NduTreTLEMN8+Un7wASAgKAAlBASAhKAAkBAWAhKAAkBAUABKCAkBCUABICAoACUEBICEo\nACQEBYDE7OPr2ZWPZtZ+2tsuYDnM1F3ghAJAQlAASAgKAAlBASAhKAAkBAWAhMuGd+LLLetfb156\nYz3/p39vWYdFMlPHwAkFgISgAJAQFAASggJAQlAASAgKAAlBASDhPpRX8WA9v/54y/qcbdfEn21Z\nv7zF/4ZDMVOL4IQCQEJQAEgICgAJQQEgISgAJAQFgISgAJBwH8pNrtbz6w+3rAPPu1rPr5upRXBC\nASAhKAAkBAWAhKAAkBAUABKCAkBCUABICAoACUEBICEoACQEBYCEoACQEBQAEoICQMLj64/N5Xp+\n/ect6/e3rMOpMVMZJxQAEoICQEJQAEgICgAJQQEgISgAJAQFgMRJ3ofy9vTZ7Pqf43o/G4GFMFMM\ngxMKABFBASAhKAAkBAWAhKAAkBAUABKCAkBCUABICAoACUEBICEoACQEBYCEoACQEBQAEoICQOIk\n34eyaPfXs8ur6ePZ9evxSbgZWAAz9cKcUABICAoACUEBICEoACQEBYCEoACQEBQAEou9D+Xz6c2N\na9+O3+1xJ7AMZoptnFAASAgKAAlBASAhKAAkBAWAhKAAkBAUABKCAkBCUABICAoACUEBICEoACQE\nBYCEoACQONrH119Of8yun4172siRuR6fzK7/MD3euPbp+KDdDHeKmXo1ZuoZJxQAEoICQEJQAEgI\nCgAJQQEgISgAJAQFgISgAJAQFAASggJAQlAASAgKAAlBASAhKAAkBAWAxNG+D4XdmHs/wy/TN7N/\n+8H4RbwbOH6nNFNOKAAkBAWAhKAAkBAUABKCAkBCUABICAoACUEBICEoACQEBYCEoACQEBQAEoIC\nQEJQAEgc7ePrz8Z3Zten3y/2tJPTMY7nh94CO2Sm9m9pM+WEAkBCUABICAoACUEBICEoACQEBYCE\noACQuLP3oUw/zl/zPn4yf/32+O6yru8+BtNXWz6zRz6TQzJTx+fYZsoJBYCEoACQEBQAEoICQEJQ\nAEgICgAJQQEgcbD7UKaHt7smHniemeLQnFAASAgKAAlBASAhKAAkBAWAhKAAkBAUABKCAkBCUABI\nCAoACUEBICEoACQEBYCEoACQONjj61me8dH849GnD7c8Xv2px6vD/x3bTDmhAJAQFAASggJAQlAA\nSAgKAAlBASAhKAAkdnofyl+vb75GerxyzwG8LDPFXeaEAkBCUABICAoACUEBICEoACQEBYCEoACQ\nEBQAEoICQEJQAEgICgAJQQEgISgAJAQFgISgAJC41ftQvh82v5thGIbhrX+8n4Fnxqfz34fzme/T\nxXAa3yUzxcu4azPlhAJAQlAASAgKAAlBASAhKAAkBAWAxDhN07RxcRyH4UQu12TJLoaZr/lemSmW\n4eaZckIBICEoACQEBYCEoACQEBQAEoICQEJQAEgICgAJQQEgISgAJAQFgISgAJAQFAASggJAQlAA\nSNybW1ytVsP19cW+9gI7sVqtDr2F/5gplmDTTM2+YAsAXpSfvABICAoACUEBICEoACQEBYDEv2Zx\nqNcpuUlGAAAAAElFTkSuQmCC\n", | |
"text": "<matplotlib.figure.Figure at 0x58459d0>" | |
} | |
], | |
"prompt_number": 19 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": "## Let's generate a skelton of the letter \"A\" by morphological thinning implemented in mahotas. Contrary to scikit-image, the skeleton is computed with a neighborhood of 8 pixels.\n###The resulting skeleton is compared to the skeletonization algo implemented in scikit-image." | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "skelC8 = mh.thin(imA)\nskel_sk = mo.skeletonize(imA)\nth_bpA = branchedPoints(skelC8, showSE = False) > 0\nth_epA = endPoints(skelC8) > 0\nth_edgesA = np.logical_not(th_bpA)*skelC8\n ", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 21 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "figsize(16,12)\nsubplot(151, xticks=[],yticks=[])\ntitle('mahotas: skeleton by thining')\nimshow(skelC8, interpolation='nearest')\nsubplot(152, xticks=[],yticks=[])\ntitle('Branched Points')\nimshow(th_bpA, interpolation='nearest')\nsubplot(153, xticks=[],yticks=[])\ntitle('End-Points')\nimshow(th_epA, interpolation='nearest')\nsubplot(154, xticks=[],yticks=[])\ntitle('Binary Edges : thin-BP')\nimshow(th_edgesA, interpolation='nearest')\nsubplot(155, xticks=[],yticks=[])\ntitle('skimage skeletonization')\nimshow(skel_sk, interpolation='nearest')", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 24, | |
"text": "<matplotlib.image.AxesImage at 0x682d650>" | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "display_data", | |
"png": "iVBORw0KGgoAAAANSUhEUgAAA5UAAADSCAYAAADaHeSaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt0VOW5x/HfkAASyGWScEtCkqMpgsdSWaUgilx0iRSB\nIlQuCoR6imKRg1atgCBgPVorKEex4gUBQS7VqiBYREQE2wL2oAJCQDgQDoRLuCdcAkme8wcruzNh\nZpJskpCE72etrMWwb+/e+9nv+z6z97zbY2YmAAAAAABcqHW5CwAAAAAAqL5IKgEAAAAArpFUAgAA\nAABcI6kEAAAAALhGUgkAAAAAcI2kEgAAAADgWqUmlUOHDtX48eMrc5PlKjU1VZ9//nmlLVfeKvL4\nr1q1Ss2aNQs6/cEHH9QzzzxTqnWVZV5Unlq1aul///d/y2VdnTt31owZM8plXUWee+45DRs2rFzX\niSvHxIkTNXjw4HJfb/fu3TVnzpxyXy8ur+raTs2aNUu33HLL5S5GSLt371atWrVUWFgYcDp1ffkI\nVedV92Pstr97ufKUNWvWqEWLFuW+3nfffVd33HFHua83mEpNKj0ejzwej6tlK6ITWlZuy1/a5Uqq\nSC/VpRz/4sqaYLz22msaN25cuc9b06WmpioiIkKRkZGKjY1Vjx49tHfv3stdrEsWKhYnTpyo2rVr\nKzIyUl6vVzfffLPWrl1b4jrHjBmjN998s1Tbr6gEApXP9xop+vvP//zPMq+npLqxc+fOqlevniIj\nI9WwYUP17dtXBw4cKHG9n3zySaljrSq0c7igpLq3qrRTRf0G3/iPjIzUe++9d7mLVmqpqalauXJl\nqecvS11fnG/7EhkZqeuuu04ffPCBM33VqlXO8YyKilKLFi00a9YsV9uq6kLVeZdyjKuCiu6vS2WP\n21BuueUWZWRkXNI6AuUQ9957rz799NNLLV6pVZvHX8srGaoOzKxarLsiy4kLPB6PlixZopycHO3f\nv1+NGzfWyJEjg85fUV9IVCaPx6OBAwcqJydH2dnZ6tChg/r06XO5i4UqyvcaKfp7+eWXK2Q7r776\nqnJycrR9+3YdP35cjzzySLlvA1VDWeve8pKfn+9quRMnTvhdA3fffXc5l6zieDyeSutP+LYvOTk5\nmjp1qgYNGqTs7GxnnsTEROXk5OjkyZN6/vnnNWzYMG3durVSyleZanofzu3+lXa5yozbsricZSox\nqUxNTdXkyZPVqlUrRUZG6j/+4z908OBB/fznP1d0dLRuv/12HT9+3Jn/7rvvVtOmTRUTE6NOnTpp\ny5Ytfus7evSoevTooaioKN14441+d7v+/ve/62c/+5liYmLUtm1b/eMf/5AkPfnkk1qzZo0eeugh\nv2+hR40apeTkZEVHR6tNmzb66quvnHWtX79ebdq0UXR0tJo0aaJHH320VAfk8OHD6tGjh7xer+Li\n4tSxY8eA823dulVXX321Fi5cKElasmSJbrjhBufOyqZNmwIuZ2b6wx/+oLS0NMXHx6t///46duyY\nJDnbiomJUWRkpNatWycz0zPPPKPU1FQ1btxY6enpOnnypKR/fSvxzjvvKCUlRQ0bNtSzzz5b4v51\n7dpVUVFR6ty5s/bs2SNJGjFihB577DG/eXv16qWpU6detI6icv7kJz+56BvRF198UY0bN1ZCQoLf\nt3u+jxSsWrVKSUlJ5TLvkSNH1LNnT0VHR6tt27YaN25clX+0x626deuqb9++ftfU0KFD9eCDD6p7\n9+5q0KCBVq1apaVLl6p169aKjo5WcnKyJk2a5MxfUswUFhbq2WefVVpamqKiotSmTRvt27fPmf7Z\nZ5+pefPm8nq9euihh/zK9/bbb+u6665TbGysunXr5sRW0XItWrRQTEyMRo4cKTMLWvH5TgsPD9eQ\nIUN04MABHT16VFlZWerVq5fi4uL0ox/9SG+99ZaznO/dx1D7uWzZMj333HNauHChIiMj1bp1a0kX\nHgu75pprFBUVpauvvlrz5s0r2wlClTJr1ix16NBBjz/+uGJjY3X11Vdr2bJlzvRdu3apU6dOioqK\nUteuXXX48OFSr9vr9apPnz7avHmzpOBtl+R/9zFUmYK1c4888ogaN26s6OhotWrVSt9///0lHxuU\nTbC6t7TtVGnq5LffflspKSm67bbb1KNHD02bNs2vDK1atdKiRYvKXPYjR46oV69eio6OVrt27bRz\n506/6cuXL9e1116rmJgYjRgxQp06dfK7Wx6qXi+P2Bw8eLD27Nmjnj17KjIyUpMnT3amzZ07N2A7\nVdq6PpDibU/Xrl0VGRl50XEp8otf/EJer7daJ5XPP/+8kpKSnDuvge6unT9/XgMHDtTdd9+t8+fP\nBzzGs2bNUnJysuLi4jR9+nR9/fXXatWqlbxer98XLjt37tStt96q+Ph4NWzYUIMGDdKJEyec6Rs2\nbFDr1q0VFRWlfv36qX///n6PnJa2Py1dHIPFcw5JysnJUZcuXfTwww9LkjIyMnT77bcrLi5OLVq0\nCHlXP1hZgsXt4sWL9e///u/yer3q0qWL393H1NRUTZkyRT/5yU8UExOjAQMGKC8vT5L/T8iK+iZF\nf3Xr1lWXLl0kha5LfHOIqKgorV279qLH3Utqq5566il16NBBUVFRuuOOO3TkyJGgxyYgK0Fqaqq1\nb9/eDh06ZPv27bNGjRpZ69at7dtvv7WzZ8/arbfeapMmTXLmnzlzpuXm5tq5c+fs4YcfthtuuMGZ\nlp6ebnFxcfb1119bfn6+3XvvvTZgwAAzMzty5IjFxMTY3LlzraCgwObPn29er9eOHj1qZmadO3e2\nGTNm+JVt7ty5dvToUSsoKLApU6ZYkyZNLC8vz8zMbrzxRps7d66ZmZ06dcrWrl3rLNeqVSubP39+\nwP0dPXq0DR8+3PLz8y0/P9+++uorv2Px+eef2//8z/9YcnKyLV261MzMNmzYYI0aNbL169dbYWGh\nzZ4921JTU+3cuXN+y5mZTZ061dq3b2/79u2zc+fO2QMPPGADBw40M7Pdu3ebx+OxgoICZ5szZsyw\ntLQ027Vrl+Xm5lqfPn1s8ODBZma2a9cu83g8dv/999vZs2ftu+++s7p169rWrVsD7lt6erpFRkba\nmjVrLC8vz0aNGmUdOnQwM7P169dbQkKCFRYWmplZdna2RURE2KFDhwKuy+Px2M6dO53PX3zxhYWH\nh9uECRMsPz/fPvnkE4uIiLDjx4+bmdnQoUNt/Pjx5T5v//79beDAgXbmzBnbsmWLNWvWzG655ZaA\nZa6OUlNTbcWKFWZ2IY6HDBli6enpzvT09HSLjo62v//972ZmdvbsWVu1apVt3rzZzMw2btxojRs3\nto8++sjMgsdMRkaGmZn98Y9/tB//+Me2fft2MzP77rvv7MiRI2Z24Zz37NnTTpw4YXv27LGGDRva\nsmXLzMzso48+srS0NMvIyLCCggJ75pln7KabbjKzC7EUGRlpf/nLXyw/P99eeuklCw8Pv+h6LjJh\nwgQbNGiQsz+PPfaYpaSkmJnZLbfcYiNGjLC8vDz79ttvrWHDhrZy5UozM5s4caKzXEn7OXHiROc6\nMjPLzc21qKgoZ78PHDhg33//fdlPGCqd7zXia+bMmVa7dm176623rLCw0F577TVLSEhwpt944432\n6KOP2rlz52z16tUWGRnpFxPFde7c2d566y0zuxDTXbp0sSFDhpSp7SqpTMXbuWXLltlPf/pTO3Hi\nhJmZZWRk2P79+y/haKG0Sqp7y9JOlaZOTk9Pt9OnT9uZM2fsz3/+s7Vr187Z1rfffmtxcXF2/vz5\ni8pZtHx+fn7A/ejfv7/179/fTp8+bZs3b7bExESnjczOzraoqCj78MMPraCgwP77v//bateu7cRg\nqHq9LLH53HPPWY8ePUIe66I+ku8+haq/S6rrg/WDfNuXwsJC+/jjj83r9Tr78cUXX1hSUpKZmRUU\nFNgHH3xgtWvXdtqG6iYjI8OaNWvmnJvMzEyn71Z0LM6cOWPdu3e3X/3qV04fMNAxfvDBBy0vL8+W\nL19uderUsd69e1t2draTG3z55ZdmZrZjxw5bsWKFnTt3zrKzs61jx4728MMPm5lZXl6eJScn28sv\nv2z5+fn2wQcfWJ06dZxrKVh/uqhv7ytUDBZdn4cPH7af/exnzvpzc3MtKSnJZs2aZQUFBfbNN99Y\nfHy8bdmyxVlu3LhxIcsSqG9vZrZt2zarX7++rVixwvLz8+2Pf/yjpaWlOddtamqqtWvXzvbv329H\njx61li1b2vTp083MP+58nTx50lq2bGlvvPGGmYWuSwLlEDNnznT6+SW1VZ06dbK0tDT74Ycf7MyZ\nM9a5c2cbPXp08OAKoFRJ5bx585zPffv2td/85jfO51deecV69+4dcNljx46Zx+OxkydPmtmFkzVs\n2DBn+ieffGItWrQwM7N33nnHrxI1M2vfvr3NmjXLzPwb9GC8Xq9t3LjRzMw6duxoEyZMsOzs7JJ2\n0c9TTz1lv/jFL2zHjh0XTUtNTbWnnnrKkpKSnIvHzGz48OFOwBa59tprbfXq1c5yRYHXsmVLvyDM\nysqy2rVrW0FBgXPh+gbErbfeaq+99przedu2bRfNv2/fPmd627ZtbcGCBQH3LT093UlgzS5cXGFh\nYbZ3716nbJ999pmZXTivd955Z9DjFCiprFevnl/ZGzVqZOvWrTMz/wu1vObNz8+/qLIfN26ccwHV\nBCkpKdagQQOLiYmx2rVrW2Jiom3atMmZPnToUL+OTiCjRo2yRx55xMwsaMwsXLjQzMyaN29uixcv\nDrgej8djf/vb35zP/fr1s+eff97MzLp16+bXGS4oKLCIiAjLzMy02bNnW/v27f3WlZSUFDKprFOn\njsXExFijRo3stttusw0bNtiePXssLCzMcnNznXnHjBljQ4cOdZYr3ggG20/fec0uXAsxMTH2l7/8\nxU6fPh2wXKiafK+Ror8333zTZs6caWlpac58p06dMo/HYwcPHrTMzEwLDw/3O9f33HOPX0wU16lT\nJ4uIiLCYmBhLTEy0QYMG2eHDh0vVdvkmlcHKVDSvbzu3cuVKa968ua1du9avDkTFK03dW9o2rbhA\ndfKuXbuc6WfOnDGv1+v0Qx599FEbMWJEwHUVLe8b/zExMZaRkeG0kdu2bXPmHzt2rNNGzp4920kS\nizRr1syJ11D1ennGZrCksjT1d1n7Qb7tS/369S0sLMxeeOEFZ/oXX3xhtWrVspiYGIuNjbXWrVs7\n262OfvjhB2vUqJGT5PmaOHGi9erVyzp27GijRo3ymxboGGdlZTnT4+Li7M9//rPzuW/fvjZ16tSA\nZfjwww+tdevWZmb25ZdfWmJiot/0Dh06OH3oYP1p3z53kVAxOHToULvvvvvs+uuvt8mTJzv/v2DB\ngotuPNx///3OzTHfL4vK0rc3M3v66aetf//+zufCwkJLTEx0yp6ammrvvvuuM/13v/udDR8+3MwC\nJ5UFBQV25513+uVcxQWqS4IllaVpq/7rv/7LmfanP/3JunXrFnTbgZTqN5WNGzd2/l2vXj2/z1dd\ndZVyc3MlSQUFBRo9erTS0tIUHR2tf/u3f5Mkv8eKiq+raNmsrCwlJyf7bTclJUVZWVnO5+K/N5k8\nebKuu+46xcTEyOv16sSJE862ZsyYoe3bt6tly5Zq27atli5dWppd1eOPP660tDR17dpV11xzjZ5/\n/nlnmpnp9ddf18033+z3WGxmZqamTJkir9fr/O3du9ev7EV2796tu+66y5nvuuuuU3h4uA4ePBiw\nPPv371dKSorzOTk5Wfn5+X7zN2nSxPl3RESETp06FXBdHo9HSUlJzuf69esrNjbWKeeQIUM0d+5c\nSRceOynrQCZxcXGqVetfIRUREeGc34qYNzs7W/n5+X6jzvruX03g8Xi0aNEiHTt2THl5eXrllVfU\nqVMnHTp0yJmn+Ki769atU5cuXdSoUSPFxMTo9ddfv+gRhuIxU3Ts9+7dq2uuuSZoeYItl5mZqVGj\nRjlxHRcXJ0nat2+f9u/ff9F5CTVSsCTnsfCDBw9qxYoVat26tbKyshQbG6v69es78yUnJ/s9nlva\n8hZXv359LVy4UNOnT1dCQoJ69Oihbdu2hSwjqgbfa6To79e//rWki8+/JOXm5iorK0ter1f16tVz\npvvWs8OHD3cePfrDH/7gbOeVV17RsWPHtHfvXs2ZM0dxcXGlart8BSuT7/4U6dKlix566CGNGDFC\njRs31gMPPKCcnJyyHSC4Upq611eoNq00dbJvnXjVVVepX79+mjNnjsxMCxYsKLE9PnLkiN81cO21\n1wZsI31jNSsr66K62fdzsHo9KyurUmKztPV3oHmL+kENGjRwBt35v//7P0n/al9yc3O1c+dOzZ49\nW2+88YazfEJCgo4dO6YjR45ow4YN6tevX7nuV2VKS0vT1KlTNXHiRDVu3FgDBw7U/v37JV3o065d\nu1abN2/WE088UeK6QuUCvv35gwcPasCAAUpKSlJ0dLQGDx7sxHtWVpYSExP91usbn8H600Vl9hUq\nBs1MS5cu1dmzZ/XAAw/4rX/dunV+6583b17APnhZ+vbShf667/Xl8XjUrFkzvz6Kb5z6HrNAnnzy\nSZ06dcpvjIDS1CXBlKatKkv5AnE1UI8F+S3UvHnztHjxYn3++ec6ceKEdu3aFXJ+X4mJicrMzPT7\nv8zMTCf4iieUa9as0QsvvKD33ntPx48f17FjxxQdHe1sKy0tTfPmzVN2draeeOIJ/fKXv9SZM2dK\nLEeDBg00efJk7dy5U4sXL9aLL76oL774winD66+/rszMTP32t791lklOTtaTTz7pV6Hn5uaqf//+\nF60/OTlZy5Yt85v39OnTatq0acBBGhISErR7927n8549exQeHu53MZdFUaUqXejIHD16VAkJCZKk\nQYMGadGiRfruu++UkZGh3r17u9pGMGUZhKI08zZs2FDh4eF+++T775rG4/HorrvuUlhYmN/vh4u7\n55571Lt3b+3du1fHjx/X8OHDSz2AT7NmzbRjx44yly05OVlvvPGGX1yfOnVK7du3V9OmTf3Oi5mF\nPE/BfvyekJCgo0eP+lVye/bscfVFQqD46tq1q5YvX64DBw6oRYsW1Xo4dYTWtGlTp+4tkpmZ6cTF\n9OnTnYE8Ro8eHXJdJbVdZREoLkeOHKl//vOf2rJli7Zv364XXnihzOvFpQlW95a2TStNnVx8Xenp\n6Xr33Xe1YsUKRUREqF27dmUud1Eb6fs7SN9/JyQk+I1oa2Z+n4PV6zfeeKOk8ovNihygKjc31xl0\np1mzZhe1LykpKerWrZs+/vjjCivD5TZw4ECtWbPGqeN8E8iuXbtq9OjRuu222/y+MHE7cqokjR07\nVmFhYdq8ebNOnDihOXPmOPHetGnTi74I9o3JsvSnpeAx6PF4NGzYMN1xxx3q3r27U9cnJyerU6dO\nfuvPycn |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment