Weak boundaries extraction

Hi all,
Below is a typical melt-pool image of a metallic material.
I’d like to extract the weak boundary in the lower part of the image, just as what the red arrows point to.

I have tried some traditional segmentation methods, even the machine-learning based ones, which are still not good enough.
Can anyone shed some lights on this task?
Thanks in advance!

Below is the raw image for your information.

1 Like

It is not a pure segment question, normal segmentation algorithms are based on region, but this question has a prior rule, the line is smooth, So I think we can treat it as a route programming question.

we need some prework to make the goal line darker. it is thin, so we can use a dog filter to enhance it. (adjust dog filter’s two sigma, we can enhance object in specific scale)

  1. force threshold the min value (suppress the too dark region)

  2. dog filter to enhance the line

  3. make a line roi from the start to the end, then find shortest route

we get a very perfect result:

the last question is how to find the start and end point. just for this image, there is a simple and safe method.

  1. binarize the image, and do some morph repair.

  2. get the boundary

  3. find the start and end point

    here we need a imagery point (not exist really, may be below the image’s center), then the start point is the nearest point in the left broundary, and the end point is the nearest point in the right broundary. It is easy to implemented with numpy.

idx = np.argmin(np.linalg.norm(left_broundary - imgpoint, axis=1))
the left_broundary[idx] is the start point. (the right is similar)


another way to find the start and end point:
we also use the shortest route to find the start point.

@jni I think the skimage’s shortest_route should add a parameter: the geometry cost.
the image upon if I did not do image += 1, the result is below:

I add a step cost befor find route, but I think it is a better way that, skimage add this parameter k, and treat diagonal step as sqrt(2).

That’s a nice idea! Then you have to find some weighting between the image cost and the path cost (they are unlikely to be on the same scale, eg if the image is in [0, 255]). I guess I would say distance_weight=0, then it is exactly the same case as before, but when you say distance_weight=1, then you sum the distance traveled to the image cost, and distance_weight=2, you sum twice the distance traveled, etc. Does that make sense? Either way, could you raise an issue so we can track this feature request?

yes, So the total cost = pixel cost + length * geometry cost.

and another parameter may be useful. This function is brightness mattered, eg if we add a const in the image, the result may be different. an extreme eg, if we add an very big value, the result would be a line (the geometry cost is more important than the pixel cost).

we should add a base_level, it could be 0 by default, and tell user in the document they could pass img.min() If it is a low contrast image.

the value small than base_level, treat as 0, else value - base_level.