In [3]:
%pylab inline


Populating the interactive namespace from numpy and matplotlib

In [57]:
import skimage, skimage.io, skimage.morphology


img = skimage.io.imread("/home/raphael/ensl/2a/images/assignments/ShapeIndexing/database/butterfly-10.pgm")


img = np.pad(img, (10, 10), 'constant')
# Preprocessing : il faudrait agrandir un peu le cadre de l'image, trouver le bord, et ensuite couper ? En fait notre papillon a un trou :()
plt.imshow(img, cmap = plt.cm.gray)
show()
# need to change every 255 in 1.
img = img / 255
img = skimage.morphology.binary_dilation(img)
img = skimage.morphology.binary_opening(img)
img = skimage.morphology.binary_dilation(img)
img = skimage.morphology.binary_opening(img)
plt.imshow(img, cmap = plt.cm.gray)
show()



In [5]:
#plt.imshow(img, cmap='Greys')
contours = skimage.measure.find_contours(img, 0.8, 'high')

c = np.zeros(img.shape)
count = 0
#plt.imshow(img, interpolation='nearest', cmap=plt.cm.gray)
for n, contour in enumerate(contours):
    plt.plot(contour[:, 1], contour[:, 0], linewidth=1)
    show()
    for x in contour:
        c[x[0]][x[1]] = 1
        count += 1
    #display(contour.shape)
    #for x in contour[:,1]:
    #    for y in contour[:,0]:
    #        count += 1
    #        c[y][x] = 1
            # faire un truc plus efficace
    break
    
display(count)
plt.imshow(c, cmap = plt.cm.gray)


/home/raphael/anaconda3/lib/python3.5/site-packages/ipykernel/__main__.py:11: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
1861
Out[5]:
<matplotlib.image.AxesImage at 0x7f1835b586a0>

In [6]:
from skimage.morphology import skeletonize
sk = skeletonize(c)

In [7]:
plt.imshow(sk, cmap = plt.cm.gray)


Out[7]:
<matplotlib.image.AxesImage at 0x7f1835a40908>

In [43]:
def fill_shape(sp, border):
    # sp : starting point
    # image with the border only
    image = 255*np.copy(border)#.astype(int)
    q = [sp]
    image[sp] = 255
    while(q != []):
        #display(q)
        curr = q.pop()
        #display("curr " + str(curr))
        t = curr[0]-1, curr[1]
        b = curr[0]+1, curr[1]
        r = curr[0], curr[1]+1
        l = curr[0], curr[1]-1
        
        image[curr] = 255
        #display("changed " + str(curr))
        #display(image[t])
        if (image[t] != 255):
            image[t] = 1
            q.append(t)
        if (image[b] != 255):
            image[b] = 1
            q.append(b)
        if (image[r] != 255):
            image[r] = 1
            q.append(r)
        if (image[l] != 255):
            image[l] = 1
            q.append(l)
    
    return image

from random import randint

def find_point_in(borders):
    # pick at random a line. If it crosses the shape 2 times or more, take a point between the first two non-connected points
    # assume borders is a matrix in Z/2Z
    p = (-1,-1)
    n_lines = borders.shape[0]
    while(p == (-1, -1)):
        line = random.randint(0, n_lines-1)
        n = np.nonzero(borders[line])[0]
        if(n.size == 0):
            continue
        else:
            i = -1
            for i in range(n.size-2):
                if(n[i]+1 != n[i+1]):
                    p = (line, (n[i]+n[i+1])//2)
                    break
    return p

In [46]:
p = find_point_in(c)
display(p)
del(i)
i = fill_shape(p, c)
display(i)
i[i > 0] = 1
plt.imshow(i, cmap = plt.cm.gray)


(158, 191)
array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       ..., 
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.]])
Out[46]:
<matplotlib.image.AxesImage at 0x7f18355cd198>

In [48]:
# perform skeletonization
image = i
skeleton = skeletonize(image)

# display results
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4.5),
                               sharex=True, sharey=True,
                               subplot_kw={'adjustable': 'box-forced'})

ax1.imshow(image, cmap=plt.cm.gray)
ax1.axis('off')
ax1.set_title('original', fontsize=20)

ax2.imshow(skeleton, cmap=plt.cm.gray)
ax2.axis('off')
ax2.set_title('skeleton', fontsize=20)

fig.tight_layout()

plt.show()



In [54]:
from skimage.morphology import medial_axis

skel, dist = medial_axis(i, return_distance = True)

plt.imshow(skel * dist, cmap=plt.cm.spectral, interpolation='nearest')
plt.contour(i, [0.5], colors='w')


Out[54]:
<matplotlib.contour.QuadContourSet at 0x7f183531b358>

In [ ]: