Building on Image Analyst's answer, here's another thought about how to trim the ends of the worm.

The basic idea is to erode each end of the worm using a mask that is derived from the original image. This assumes that the curve in the image is reasonably smooth on a scale comparable to the worm thickness, but if it isn't, the process as a whole probably doesn't make a lot of sense.

The code below demonstrates the idea. I've taken the simple case of a straight line but it should be OK with a curve, as long as the curve is connected. The core operation is to extract a patch of the original image centred on a line end, rotate it through 180 degrees, and erode the same end of the worm with it, cutting it back so that the line meets the boundary.

I haven't tested this very thoroughly - it may need more work to make it robust for all reasonable cases. The factor of 1.2 times the dilation radius to get the region to erode at the end of the worm is empirical - it should be easy enough to work out a well-founded value geometrically, but I haven't got round to that.

Also, I have assumed that the worm does not get too close to the boundaries of the image. It would be easy to fix the code to deal with this problem by using exindex to cut out the patches.

x1 = 50;

y1 = 150;

x2 = 150;

y2 = 50;

im = false(200, 200);

im(sub2ind(size(im), y1:-1:y2, x1:x2)) = true;

imshow(im);

r = 30;

diskstruc = strel('disk', r, 0);

dil = imdilate(im, diskstruc);

disk = false(2*r+1);

disk(r+1, r+1) = true;

disk = imdilate(disk, diskstruc);

r2 = ceil(1.2*r);

mask = im(y1-r:y1+r, x1-r:x1+r) & disk;

reg = dil(y1-r2:y1+r2, x1-r2:x1+r2);

erod = imerode(reg, rot90(mask, 2));

dil(y1-r2:y1+r2, x1-r2:x1+r2) = erod;

mask = im(y2-r:y2+r, x2-r:x2+r) & disk;

reg = dil(y2-r2:y2+r2, x2-r2:x2+r2);

erod = imerode(reg, rot90(mask, 2));

dil(y2-r2:y2+r2, x2-r2:x2+r2) = erod;

splt = dil & ~im;

col = label2rgb(bwlabel(splt, 4));

figure; imshow(col);