Я думаю, что проблема проста, если граница объекта выпуклая и нет трех вершин на линии (т.е. ни одна вершина не может быть удалена без изменения многоугольника): тогда вы можете просто выбрать две точки случайным образом и использовать простой поиск типа градиентного спуска, чтобы найти самую длинную строку:
Start with random vertices A, B
See if the line A' - B is longer than A - B where A' is the point left of A; if so, replace A with A'
See if the line A' - B is longer than A - B where A' is the point right of A; if so, replace A with A'
Do the same for B
repeat until convergence
Так что я бы предложил найти выпуклую оболочку для каждого начального объекта, удалив все вершины «излишков» (чтобы обеспечить сходимость) и запустив алгоритм, описанный выше.
Построение выпуклой оболочки - это операция O (n log n) IIRC, где n - количество граничных пикселей. Должно быть довольно эффективным для небольших объектов, подобных этим. РЕДАКТИРОВАТЬ : Я только что вспомнил, что O (n log n) для алгоритма выпуклой оболочки была необходима для сортировки точек. Если граничные точки являются результатом анализа подключенных компонентов, они уже отсортированы. Таким образом, весь алгоритм должен выполняться за O (n) время, где n - количество граничных точек. (Тем не менее, это большая работа, потому что вам, возможно, придется написать собственный алгоритм выпуклой оболочки или изменить его, чтобы пропустить сортировку.)
Добавить: Ответ на комментарий
Если вам не нужна точность 100%, вы можете просто подогнать эллипс к каждому шарику и рассчитать длину большой оси: это можно вычислить из центральных моментов (IIRC это просто квадрат корень, если наибольшее собственное значение ковариационной матрицы), поэтому это операция O (n), которая может быть эффективно рассчитана за один проход по изображению. У него есть дополнительное преимущество, заключающееся в том, что он учитывает все пиксели большого двоичного объекта, а не только две экстремальные точки, т. Е. На него гораздо меньше влияет шум.