1

I want to be able to find the length of a path in a picture, this could be the length of a worm, a curly human hair, Amazon river, etc. Consider this Amazon river picture: enter image description here

I tried to make an skeleton of my picture after its binarization, but the problem is that the skeletons (obtained by two methods) have many small branches that causes their area to be much more than the approximate length of the path. I used scikit-image to do this. Here's the code and results:

from skimage.filter import threshold_otsu
from skimage import io
from skimage.filter.rank import median
from skimage.morphology import disk,skeletonize,medial_axis,remove_small_objects
import matplotlib.pyplot as plt


input_image = io.imread('Amazon-river2.jpg',
                    as_grey=True, plugin=None, flatten=None)
image = median(input_image, disk(15)) 

thresh = threshold_otsu(image)
image = image < thresh

skel1=skeletonize(image)
skel2=medial_axis(image)

min_size=sum(sum(skel1))/2

remove_small_objects(skel1,min_size=min_size,connectivity=5,in_place=True)

remove_small_objects(skel2,min_size=min_size,connectivity=5,in_place=True)


fig2, ax = plt.subplots(2, 2, figsize=(24, 12))

ax[0,0].imshow(input_image,cmap=plt.cm.gray)
ax[0,0].set_title('Input image')
ax[0,0].axis('image')
ax[0,1].imshow(image, cmap=plt.cm.gray)
ax[0,1].set_title('Binary image')
ax[0,1].axis('image')
ax[1,0].imshow(skel1, cmap=plt.cm.gray)
ax[1,0].set_title('Skeleton')
ax[1,0].axis('image')
ax[1,1].imshow(skel2,cmap=plt.cm.gray)
ax[1,1].set_title('Sleleton - Medial axis')
ax[1,1].axis('image')

plt.show()


print ("Length 1: {0}".format(sum(sum(skel1))))
print ("Length 2: {0}".format(sum(sum(skel2))))

enter image description here

Any suggestions to solve this problem? Any other idea to measure the length of an arc ?

Ehsan88
  • 3,569
  • 5
  • 29
  • 52

3 Answers3

3

As I see it, this is a graph were the nodes are end points and they are connected by path. so every point may (or not) connected to any other point, and you need need to find the longest path.

so, you need to find all end points, from each end point start to iterate until you get to another end point. after doing it for all points you can take the longest path!!!

hope that helps

  • I thought about that! but this is a very difficult thing to do because you should consider all the points you made a decision about going to one path or another and this is like a decision tree. Any idea how to create a code to do this ? – Ehsan88 Dec 25 '14 at 15:02
0

Try the following

  1. Perform color segmentation on R or B channel, instead of RGB->Grey
  2. Instead of greythresh Otsu, go for manually set threshold or use multithresh Otsu (should be there in python as well)
  3. Perform following morphology operations prior to skeletonize on binary image: Erosion -> Thinning -> Areaopen. This should eliminate islands.

Though skeletonize will always have such issues, you can go for canny edge detection on binary. Perform following on each edge Arc length

dbs
  • 126
  • 3
0

Totally agree with Yaron Kahanovitch's suggestion, and I think NetworkX should be able to do the job to calculate the longest trajectory/route, however how to automatically extract end point or cross point as nodes and calculate the distance for weighted edge still be struggling and challenging tasks to be done.

As a result, I just posted another question on stackoverflow, and hope some geek can give us valuable suggestions.

gongming wei
  • 83
  • 1
  • 9