Как стать автором
Обновить

Комментарии 46

Класс! Решение буквально в 10 строк, демонстрирующее всю мощь данного математического пакета, на мой взгляд, незаменимого для науки инструмента.

P.S.: И спасибо, что напомнили недалекое прошлое, когда используя матлаб для расчётов и построения графиков, я написал нехилый диплом и поступил в аспирантуру. Прям руки зачесались поставить его вновь и применить его для решения одной старенькой, для меня, задачи.
Не за что! Если я правильно понимаю, вы давно не открывали MATLAB — в таком случае он может удивить вас новыми вкусными плюшками, которые добавляются с каждой новой версией — они сейчас выходят два раза в год.
Ну, не то, чтобы давно: где-то года 3 назад. Как раз поставил, сейчас буду удивляться.
вы видимо с IDL не знакомы, раз говорите о незаменимости матлаба в научных делах:)
Вот это уже TRUE. Я и рассчитывал увидеть алгоритмы цифры и прочее, а там были игры в фотошоп какие-то. Спасибо
Агррр.
Ну будет Вам, я же любя)
Решение прекрасное. Есть мелкий баг — иногда детектится внешний контур, иногда внутренний; т.е. всегда есть ошибка в радиусе либо +delta, либо -delta.
Но вообще — супер.

Про bwboundaries я не знал.
Хорошая задачка, вообще. Я бы (наверное) после нахождения контуров пробежался бы по всей картинке спец. фильтром для поиска окружностей, ну или более обще — эллипсов. Для него разрывы в контуре не проблемы.
А потом искал бы пары вложенных окружностей с примерно общим центром и небольшим зазором, и усреднял бы их радиусы и центры.

Другой вариант — искать не границы хребтов вокруг кратеров, а выделять сами хребты (т.е. трансформация IM -> (IM- Lowpass::Im).) И тогда можно искать самую высокую точку на хребте и т.п.

Понятно, что можно построить совершенно устойчивое решение. Но для этого надо все-таки неделю-две повозиться.
Примерно над этим я сейчас, честно говоря, и работаю. Есть уже определённые положительные результаты, и я скоро собираюсь ими поделиться на Хабрахабре. Заодно покажу пару картинок, к которым подобные преобразоания неприменимы, т.к. объекты либо имеют слегка неправильную форму, либо нечеткие границы.
Вот, к примеру, изображение, на котором выбранный алгоритм преобразования работает не совсем так, как хотелось бы.
(картинкой вставить не даёт, поэтому ссылки...)
Исходное изображение. Результат.
Как можно заметить, часть форм не обнаруживается. Большая часть мелких частиц обнаруживается, но большие — нет. Т.к. важно статистическое распределение, то это критично. Вот пытаюсь сейчас разрешить эту проблемку…
Мда… попробуйте создать базу данных из 100 наиболее типчных колечек разных диамтеров, и посчитайте корреляцию с каждым из них по всей картинке.
Получится 100 картинок, отражающих вероятность что именно это колечко здесь расположено, в данной точке (x,y).
Threshold уровни должны быть разные у больших и маленьких колечек.
Во время свертки учитывайте только пиксели на границе и внутри колец, т.е. ядро свертки должно быть круглым а не квадратным.
Перед этим, конечно, pre-processing:
1) convert to greyscale
2) убрать фоновый уровень
3) выровнять локальную контрастность (убрать градиент освещения и т.п.)
И это, как я понимаю, изначально полагалось вручную обрабатывать? Жесть!

Еще подход — без перехода к оттенкам серого. Как нетрудно заметить, изображение состоит по сути из трех цветов — белого (внутри объектов), черного (границы объектов) и фиолетового (фон). Переводим изображение в цветовое простанство HSV — тон, насыщенность, яркость. Яркость нам не нужна, используем только информацию о цвете. Кластеризуем точки изображения в координатах Тон-Насыщенность методом К-средних по метрике Евклида, вот что получается.

Видны косяки, связанные с градиентом освещения — внизу изображение слишком светлое, а сверху-слева слишком темное. Но освещение, я так понимаю, можно настроить… Белым — наши объекты, заметьте даже очень мелкие выделились.

Такой метод можно использовать наравне с остальными и затем объединить результаты.
Насчет того, что яркость нам не нужна — это Вы, я думаю, погорячились! :)
А белый цвет там результат overexposure, к сожалению. Так что никакой значимой информации он не добавляет.
Жалко, конечно. Признаюсь, я вначале тоже об этом думал…
На самом деле яркость я отбросил, чтобы избавиться от градиента освящения, но что-то не очень получилось.

Хм, засветка есть, и правда… Только почему белый цвет не несет информации? Это блики от объектов — фон ведь не бликует. Соответственно, кмк, по бликам их вполне можно определять.
НЛО прилетело и опубликовало эту надпись здесь
Расскажите пожалуйста о каком спец фильтре идет речь? для поиска окружностей? Решаю такую же задачу, только в круге есть текстура. Контура из за этого слегка рвутся. И таким образом задачка не решается. Дилатация конечно соединяет рваные контуры, но контур становится толстым, и его сложно трассировать. Сейчас есть алгоритм трассировки контура когда у каждой точки контура не более двух соседей, если контур толще — то не ясно как его трассировать. Говорят есть алгоритм Suzuki85 для этого однако описания нормального в научной литературе не нашел.
НЛО прилетело и опубликовало эту надпись здесь
Снаружи — есть текстура, все что угодно, у меня тестовые примеры на столе, а стол весь из дерева с характерным рисунком. Детектор Канни первым этапом предполагает применение фильтра гаусса, текстура внутри очень сложная, может на самом деле все что угодно. В общем буду допытываться до автора предыдущей статьи, там мне больше идея с заливкой понравилась.
НЛО прилетело и опубликовало эту надпись здесь
Толстые контуры можно скелетизировать алгоритмом Зонга-Суня (Zhang-Suen), или пустить по контуру «волну» и отслеживать её центр (где-то видел описание такого алгоритма, сейчас с ходу не вспомню, но могу найти).
НЛО прилетело и опубликовало эту надпись здесь
См. мою статью, указанную в начале этой :)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Да, к сожалению стоимость высока… Но есть опенсорсный аналог — SciLab, работал в нем не очень много, поэтому сравнивать по функционалу не могу.
Когда нужно было делать семестровки по численным методам, делал в octave, тоже опенсорсный аналог. Про функционал тоже не знаю — на семестровки хватало (и потом успешно запускалось в MATLAB), а более серьезных вещей не делал.
Лучшая реклама матлаба и антиреклама велосипедов.

>имперически
эмпирически, наверно.
Велосипеды тоже нужны. Все нужно.
Матлаб — сильное оружие, но если не понимать в точности, как каждая его функция работает, то далеко не уедешь. А если понимать, то по большому счету не важно в какой среде писать.
Хотя для разработки алгоритмов matlab супер удобный.
Спасибо, поправил.
Велосипед хорошо, катаюсь когда тепло.
> диляция
Вроде как «дилатация» будет правильней.

И, да, почему именно Канни? Тоже эмпирически?
Судя по английской вики, диляция и дилатация — одно и то же. Я привык к термину 'диляция'.

Канни — эмпирически, время на исследование эффективности различных методов не тратил.
В Гонсалесе-Вудсе перевели как «дилатация». Хотя, возможно, дело вкуса.
Хорошая демонстрация возможностей Матлаба.
Интересно, на каких-нибудь opensource аналогах, том же SciLab или Octave, например, можно добиться такого же быстрого решения?
В OpenCV можно сделать то же самое, примерно в то же количество строк.
НЛО прилетело и опубликовало эту надпись здесь
Спасибо! Почему то даже и не вспомнил об imopen. Внес исправление.
НЛО прилетело и опубликовало эту надпись здесь
Здорово! Спасибо, что не поленились написать! Я всерьез задумался об использовании MATLAB'a… Я действительно потратил на порядок больше времени, но в него входило изучение нового языка и т.п.
Ещё раз спасибо!
Вам спасибо за вдохновение! :)
Одна из актуальных и прикладных задач, которую я к сожалению лет 10 назад профакапил — определение «правильной круглости» колец Ньютона для тестирования зеркал лазерной сварки. Используются в автомобильной промышленности. Получалось что зеркала Российского производства выгодно дешевле, но немцев не убедило — главное для них было качество (что и надо было обеспечить) и высокая цена была заложена в стоимость мерседесов, бмв и прочих ауди.
Если знаешь как, то это можно сделать во многих математических пакетах. Например, в Mathematica:
SetDirectory[NotebookDirectory[]];
img = Import["kkk.jpg", "Graphics"];
grayimg = ImageAdjust[ColorConvert[img, "Grayscale"]] ;
bw = FillingTransform[EdgeDetect[grayimg, Method -> "Canny"]];
bw = Binarize[Blur[bw, 4]];
components = {#[[2, 2]], #[[2, 1]]} & /@ ComponentMeasurements[bw, {"EquivalentDiskRadius", "Centroid"}];
ImageDimensions[img]
Show[
    img,
    Graphics[{Red, Circle @@ #} & /@ components],
    Graphics[Text[Style[NumberForm[#2, 3], 15, Yellow], #1 - (#2/Sqrt[2] + 6)] & @@ # & /@ components]
]
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.