ReferenceLoosePartFeeder или компьютерное зрение для утилизации рассыпухи

Приветствую всех. Продолжаю знакомить вас с возможностями OpenPNP.
Сегодня мы поговорим об автоматическом распознавании элементов в ячейке.
До того, как я обзавелся станком и начал собирать приборы в более-менее большом объеме, я делаю резисторы и конденсаторы небольшими партиями и заливаю их в ручной "комбайн".

Но сохранять элементы в катушках намного удобнее, если вы планируете использовать их позже в органайзере. А когда покупаешь не 100-200, а 2000-4000 компонентов одного номинала, очень глупо их куда-то сливать.
Но все же я успел раскидать некоторые номиналы по "коробочкам" и их надо как-то выбросить. Загрузка в пустые ленты возможна, но очень утомительна. Особенно, если в каждой плате их используется более 10 штук.
На помощь приходит «корм для рассыпного пороха». Сегодня я расскажу как я настроил его для распознавания SMD резисторов и конденсаторов с "фильтрующими" резисторами лежащими "пузом" вверх.

Первым шагом является печать фона. Я использовал квадратные коробки, сделанные на 3D-принтере. "Зеленка" - это еще и пластина, напечатанная на принтере с включенным "сглаживанием" верхнего слоя и затем обработанная наждачной бумагой для придания ему матовости. Это важно. Вы можете использовать любую цветную бумагу. Но Зеленка — это классический хромакей и стандартные пайплайны (о них позже) для компьютерного зрения в OpenPNP рассчитаны на него.

Любое распознавание в OpenPNP, будь то элементы, как в нашем случае ленты с компонентами, опорные точки для центрирования платы и так далее, настраиваются в так называемых Pipelines (Конвейерах), где путем объединения стандартных шагов и установки их параметров , сможете ли вы добиться нужного вам результата. Нажмите Редактировать пайплайн и перейдите к редактированию. (Потом объясню по картинкам, чтобы меньше писать и больше показывать).

Первым делом захватываем изображение и применяем размытие по Гауссу (BlurGaussian) для фильтрации невидимых нашему глазу артефактов (как видите, у нас 2 резистора перевернуты):

Затем делаем изображение серым (ConvertColor), а после черно-белого (Threshold) устанавливаем порог яркости (шаг серого и выделения). Получаем белые контакты (отражающие свет) и «пузыри» резисторов.
После «ищем все контуры» (FindContours). Каждый замкнутый контур на изображении помечен как «в процессе"
Но теперь нам нужно найти неуместные резисторы, поэтому мы фильтруем контуры (FilterContours) по размеру, устанавливая минимальный размер больше, чем контактные площадки, но ограничивая максимальный, чтобы при необходимости отфильтровать свет.

Затем для поста я включил элемент DrawContours, чтобы вы могли видеть, какие из них все еще «в процессе".

Большой.

Обратите внимание: Портит ли зрение комьютер или телефон?.

У нас есть цепи сопротивления, которые нам не нужны. Теперь перейдем к тем, которыми было бы неплохо пользоваться. Мы вызываем ImageRecall. Преобразовываем цвета из RGB в HSVFull (это важно) и вырезаем все резисторы на зеленом (MaskHSV).

Здесь вы можете увидеть всех наших противников. Теперь немного магии, вызываем MaskModels и в качестве параметра modelStageName указываем имя (!) этапа, на котором мы отфильтровывали неправильные резисторы (counturingResistors). Вуаля:

Элегантный? Уже видно, что резисторы, которые ошиблись, очень разные. Теперь нам нужно обрезать изображение (MaskRectangle), чтобы убрать лишнее. И после применения большего размытия (BlurMedian сильнее самого начала Gaussian). И это все. Наших схем с ненужными резисторами почти не осталось.

Осталось определить контуры (FindContours + FilterContours), используя несколько шагов из стандартного Pipeline:
Поиск прямоугольников + их ориентация. Ну и нарисуй все это:

Собственно, это все. Надеюсь, это было интересно. ;)

PS спасибо @Pas.Ratunkow за мотивацию :)

Больше интересных статей здесь: Гаджеты.

Источник статьи: ReferenceLoosePartFeeder или компьютерное зрение для утилизации рассыпухи.