Вы не указали, как вы получили свои начальные сегменты. Несмотря на это, я думаю, что улучшение линий водоразделов может решить вашу проблему, и это можно сделать в структуре иерархии водоразделов с помощью пакета Higra .
Я указываю начальное упорядочение водоразделов по изображение дополняет и пересчитывает линии водоразделов с другим атрибутом (объемом).
Падение интенсивности и площадь, которые вы описываете, являются атрибутом объема, и вы можете управлять сегментацией по его пороговому значению в иерархии.
Вот рабочий пример:
import cv2
import numpy as np
import higra as hg
from skimage.morphology import remove_small_objects, label
import matplotlib.pyplot as plt
def main():
img_path = "fig.png"
img = cv2.imread(img_path)
img = img[:,:,0].copy()
img = img.max() - img
size = img.shape[:2]
graph = hg.get_4_adjacency_graph(size)
edge_weights = hg.weight_graph(graph, img, hg.WeightFunction.mean)
tree, altitudes = hg.quasi_flat_zone_hierarchy(graph, edge_weights)
attr = hg.attribute_volume(tree, altitudes)
saliency = hg.saliency(tree, attr)
# Take a look at this :)
# grid = hg.graph_4_adjacency_2_khalimsky(graph, saliency)
# plt.imshow(grid)
# plt.show()
attr_thold = np.mean(saliency) / 4 # arbitrary
area_thold = 500 # arbitrary
segments = hg.labelisation_horizontal_cut_from_threshold(tree, attr, attr_thold)
segments = label(remove_small_objects(segments, area_thold))
plt.imshow(segments)
plt.show()
if __name__ == "__main__":
main()
Вот результат.
Результат