In [3]:
%pylab inline
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)
Out[5]:
In [6]:
from skimage.morphology import skeletonize
sk = skeletonize(c)
In [7]:
plt.imshow(sk, cmap = plt.cm.gray)
Out[7]:
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)
Out[46]:
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]:
In [ ]: