Как расположить центры кругов в сетке в определенном порядке в opencv

У меня есть несколько приблизительных кругов примерной формы сетки, но есть искажения.

Как мне расположить центры слева направо, сверху вниз?

Я попробовал findCirclesGrid, но не думаю, что это сработает с искажениями.

Я не думаю, что обнаружение BLOB-объектов имеет порядок.

Я собирался поработать над каким-нибудь кодом, который надежно восстанавливает структуру сетки по набору точек... но это требует времени и мотивации.

Christoph Rackwitz 20.07.2024 12:26

Этот вопрос похож на: Python: сортировка элементов сверху слева вниз справа с помощью OpenCV. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

Tino D 22.07.2024 09:01

Вам следует проверить отличный ответ, который я предложил в качестве дубликата.

Tino D 22.07.2024 09:01

внешне похоже, но не совсем. ответ, который вы связали, объединяет точки в заданное пользователем количество строк, независимо от того, какая форма сетки лежит в основе точек. если бы сетку повернуть еще раз, она определенно просто перерезала бы строки и исказила бы структуру. связанный ответ довольно тривиален (get_rows), если удалить вторичный код (извлечение объектов для получения очков).

Christoph Rackwitz 22.07.2024 09:28

другой ответ на связанный вопрос на самом деле показывает более глубокое понимание. он предполагает кластеризацию, чувствительную к данным, вместо того, чтобы требовать количество кластеров, указанное пользователем. «кластеризация» описывает результат. это не конкретный подход. здесь «кластеризация» была бы нетривиальной, поскольку сетка искривлена ​​нелинейно: точки не лежат ни на одной прямой линии. и именно об этой проблеме я упомянул в своем первом комментарии. Я имею в виду подходы и играл с этой проблемой в прошлом. надежные решения далеко не тривиальны.

Christoph Rackwitz 22.07.2024 09:35

@VanushVee, возможно, вы захотите добавить к вопросу второе изображение, на котором показана более сильно искаженная сетка... если в вашем приложении есть такие экземпляры. нам не нужно усложнять проблему, чем она есть на самом деле, но полезно увидеть, насколько сложной может быть проблема.

Christoph Rackwitz 22.07.2024 09:39
findCirclesGrid, необходимый для калибровки камеры, должен иметь возможность восстанавливать деформированные сетки. ИДК, сможет ли он справиться с этим шаблоном. некоторые результаты поиска предполагают, что так и должно быть. CALIB_CB_SYMMETRIC_GRID | CALIB_CB_CLUSTERING помог кому-то в какой-то момент. ваше изображение может быть более сложным, потому что круги «комковатые».
Christoph Rackwitz 22.07.2024 09:44

небольшое расследование: детектору BLOB-объектов необходимо отключить всю фильтрацию. тогда я найду BLOB-объекты: i.sstatic.net/itvRGS0j.png и findCirclesGrid могу найти структуру: i.sstatic.net/Ddr0WXA4.png (для этого требуется отсутствие флага кластеризации; реализация кластеризации делает это неправильное присвоение баллов). все это требует от вас знания размера сетки и всех точек, которые будут видны. любые недостающие испортят это.

Christoph Rackwitz 22.07.2024 09:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

findCirclesGrid() предназначен для калибровки камеры. Ожидается, что такие шаблоны будут иметь искажения, как и ваши. Это определенно должно работать с вашими данными.

Ему просто нужна небольшая помощь. Внутри он использует BlobDetector, который инициализируется с некоторыми значениями по умолчанию, которые хорошо работают для обычных сеток кругов, которые показывают четко определенные круги.

Для вашей картинки вам понадобится BlobDetector с пользовательскими параметрами. Чтобы найти все эти комковатые капли, вам нужно отключить всю фильтрацию, которую он обычно выполняет.

params = cv.SimpleBlobDetector_Params()
params.filterByArea = False
params.filterByCircularity = False
params.filterByColor = False
params.filterByConvexity = False
params.filterByInertia = False

blobdet = cv.SimpleBlobDetector_create(params)

Результат keypoints = blobdet.detect(im) и cv.drawKeypoints():

Также нужно быть осторожным с флажками findCirclesGrid(). CALIB_CB_CLUSTERING потерпел неудачу в том, что он неправильно присвоил точки позициям сетки.

(rv, gridpts) = cv.findCirclesGrid(
    im, (10, 7),
    flags=cv.CALIB_CB_SYMMETRIC_GRID,
    blobDetector=blobdet)

И это придаст вам gridpts форму (70, 1, 2).

Немного визуализации:

im_with_grid = cv.cvtColor(cv.pyrUp(im >> 1), cv.COLOR_GRAY2BGR)

for k in range(1, len(gridpts)):
    [p1] = gridpts[k-1]
    [p2] = gridpts[k]
    cv.line(im_with_grid, (p1 * 2.0).astype(int), (p2 * 2.0).astype(int), (0, 0, 255), 2)

for i,[pt] in enumerate(gridpts):
    cv.circle(im_with_grid, (pt * 2.0).astype(int), 5, (0, 255, 0), -1)
    cv.putText(
        im_with_grid, f"{i}", (pt * 2.0).astype(int),
        cv.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2, cv.LINE_AA )

Или, если вы укажете размер сетки как (7, 10), она будет перевернута по диагонали и будет выглядеть так:

Предостережение

findCirclesGrid не получится, если в сетке есть дефекты, т. е. недостающие точки. Он не может обойти эти дефекты. Вам необходимо идеальное обнаружение всех точек сетки.

Другие вопросы по теме