Надеюсь, данный пост не станет причиной ночных кошмаров у особо чувствительных хабрачитателей. В этом посте я постараюсь рассказать о простом способе увеличения ГРИП. Это весьма актуальная проблема для тех, кто работает с микроскопом и занимается макрофотографией. Суть проблемы в том, что на больших увеличениях размытие удаленных от точки фокуса предметов становится большой проблемой. Это в традиционной портретной съемке размытие фона позволяет подчеркнуть объект. В научной микрофотографии это чаще всего негативный эффект. Радует, что есть методика focus-stacking, которая позволяет сшить в единую резкую картинку стопку фотографий с разной точкой фокусировки. Но хватит рассуждать об абстрактном. Внесите клеща в студию!
Если его не видно, это не значит, что он не ест тебя прямо сейчас
Все началось достаточно тривиально. Моя любимая фатсхедера начала стремительно чахнуть и всячески пытаться умереть несмотря на уход. Так как я работаю в
Надо было что-то придумывать для получения резкой картинки.
Z-stacking
Я обратился к традиционной методике сшивания серии фотографий, но был неприятно удивлен ценам на коммерческие продукты. Особенно, если это ПО от производителя микроскопа. Там вообще тихий ужас. Но так как мы не зря линуксоиды и иконку Столлмана регулярно протираем от пыли, то будем искать свободные программы. Сразу нашлись Hugin и Enfuse, которые позволяют делать все красиво и из консоли, что крайне удобно при массовой обработке фотографий.
Основных этапа у нас два:
- (Hugin) Выравнивание фотографий по контрольным общим точкам
- (Enfuse) Собственно сшивка всего этого воедино
Для Enfuse доступен GUI, но мы будем работать из консоли. Устанавливаем нужные пакеты под Ubuntu (они доступны и для Windows, будет отличаться синтаксис немного):
sudo apt-get update && sudo apt-get install enfuse hugin hugin-tools -y
На первом этапе складываем все наши изображения в отдельный каталог. При необходимости проводим доводку баланса белого и экспозиции с помощью того же RawTherapee. После это выравниваем, чтобы нивелировать дрожание камеры или в данном случае легкое шевеление пациента:
align_image_stack -v -m --gpu -a aligned -C *.jpg
Обратите внимание, что мы пробуем использовать GPU через OpenCL для расчетов, что значительно быстрее, но не всегда работает. Если будет падать — уберите опцию --gpu. Далее, -a aligned создает новые файлы с соответствующим префиксом. *.jpg — маска для выбора файлов, которые будут выравниваться.
В результате консоль дает нам такой вывод:
meklon@RegenLab-LinuxDesktop-1:~/ownCloud/Temp/2016.04 Клещ хабр/converted$ align_image_stack -v -m -a aligned -C *.jpg Creating control points between Image_299.jpg and Image_300.jpg
Trying to find 8 corners...
Number of good matches: 0, bad matches: 40
Number of good matches: 1, bad matches: 39
Number of good matches: 2, bad matches: 38
Number of good matches: 4, bad matches: 36
Number of good matches: 5, bad matches: 35
Number of good matches: 1, bad matches: 39
Number of good matches: 2, bad matches: 38
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 6, bad matches: 34
Number of good matches: 7, bad matches: 33
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 3, bad matches: 37
Creating control points between Image_300.jpg and Image_301.jpg
Trying to find 8 corners...
Number of good matches: 0, bad matches: 40
Number of good matches: 0, bad matches: 40
Number of good matches: 3, bad matches: 37
Number of good matches: 8, bad matches: 32
Number of good matches: 7, bad matches: 33
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 7, bad matches: 33
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 7, bad matches: 33
Number of good matches: 8, bad matches: 32
Number of good matches: 6, bad matches: 34
Creating control points between Image_301.jpg and Image_302.jpg
Trying to find 8 corners...
Number of good matches: 0, bad matches: 40
Number of good matches: 6, bad matches: 34
Number of good matches: 8, bad matches: 32
Number of good matches: 4, bad matches: 36
Number of good matches: 7, bad matches: 33
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 3, bad matches: 37
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Creating control points between Image_302.jpg and Image_303.jpg
Trying to find 8 corners...
Number of good matches: 3, bad matches: 37
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 5, bad matches: 35
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 2, bad matches: 38
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Creating control points between Image_303.jpg and Image_304.jpg
Trying to find 8 corners...
Number of good matches: 3, bad matches: 37
Number of good matches: 0, bad matches: 40
Number of good matches: 3, bad matches: 37
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 3, bad matches: 37
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Creating control points between Image_304.jpg and Image_305.jpg
Trying to find 8 corners...
Number of good matches: 0, bad matches: 40
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 2, bad matches: 38
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 4, bad matches: 36
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 6, bad matches: 34
Creating control points between Image_305.jpg and Image_306.jpg
Trying to find 8 corners...
Number of good matches: 2, bad matches: 38
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 2, bad matches: 38
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 2, bad matches: 38
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Creating control points between Image_306.jpg and Image_307.jpg
Trying to find 8 corners...
Number of good matches: 0, bad matches: 40
Number of good matches: 0, bad matches: 40
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 0, bad matches: 40
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 6, bad matches: 34
Number of good matches: 6, bad matches: 34
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 1, bad matches: 39
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 8, bad matches: 32
Number of good matches: 6, bad matches: 34
Optimizing Variables
Strategy 1
Average (rms) distance between Controlpoints
after 0 iteration(s): 13.1811221241261 units
Strategy 1
Average (rms) distance between Controlpoints
after 1 iteration(s): 13.1566720340408 units
Strategy 1
Average (rms) distance between Controlpoints
after 2 iteration(s): 13.0662076945298 units
Optimizing Variables
Strategy 2
Average (rms) distance between Controlpoints
after 0 iteration(s): 4.22711068896714 units
Strategy 2
Average (rms) distance between Controlpoints
after 1 iteration(s): 3.90465178857069 units
Strategy 2
Average (rms) distance between Controlpoints
after 2 iteration(s): 3.88979141960262 units
Strategy 2
Average (rms) distance between Controlpoints
after 3 iteration(s): 3.88741946042386 units
Strategy 2
Average (rms) distance between Controlpoints
after 4 iteration(s): 3.88714333274445 units
Strategy 2
Average (rms) distance between Controlpoints
after 5 iteration(s): 3.88711661173386 units
Strategy 2
Average (rms) distance between Controlpoints
after 6 iteration(s): 3.88711414454988 units
Strategy 2
Average (rms) distance between Controlpoints
after 7 iteration(s): 3.88711391437541 units
Ctrl points before pruning: 1274, after: 1051
Optimizing Variables
Strategy 1
Average (rms) distance between Controlpoints
after 0 iteration(s): 1.11869477363138 units
Strategy 1
Average (rms) distance between Controlpoints
after 1 iteration(s): 1.10458154981741 units
Strategy 1
Average (rms) distance between Controlpoints
after 2 iteration(s): 1.10324670986012 units
Strategy 1
Average (rms) distance between Controlpoints
after 3 iteration(s): 1.09274711349145 units
Strategy 1
Average (rms) distance between Controlpoints
after 4 iteration(s): 1.09274711349145 units
Optimizing Variables
Strategy 2
Average (rms) distance between Controlpoints
after 0 iteration(s): 1.08772087726722 units
Strategy 2
Average (rms) distance between Controlpoints
after 1 iteration(s): 1.07924785202492 units
Strategy 2
Average (rms) distance between Controlpoints
after 2 iteration(s): 1.07923206520615 units
Strategy 2
Average (rms) distance between Controlpoints
after 3 iteration(s): 1.07923200575396 units
Run called
Down to Algorithm
Original Image: 2080x1544
Inner 256 2349312: 128 1952 - 128 1416
Starting 256: 128 1952 - 128 1416
Starting 128: 128 1952 - 128 1416
Starting 64: 0 1952 - 0 1416
Starting 32: 0 2016 - 0 1480
Starting 16: 0 2048 - 0 1512
Starting 8: 0 2064 - 0 1528
Starting 4: 0 2072 - 0 1536
Starting 2: 0 2076 - 0 1540
Starting 1: 0 2078 - 0 1542
Found Solution: 0 0 2079 1543
Crop 0x0 - 2079x1543
Crop Size 2079x1543
Set crop size to 0,0,2079,1543
Multiple images output
loading Image_299.jpg
remapping Image_299.jpg
saving aligned0000.tif
loading Image_300.jpg
remapping Image_300.jpg
saving aligned0001.tif
loading Image_301.jpg
remapping Image_301.jpg
saving aligned0002.tif
loading Image_302.jpg
remapping Image_302.jpg
saving aligned0003.tif
loading Image_303.jpg
remapping Image_303.jpg
saving aligned0004.tif
loading Image_304.jpg
remapping Image_304.jpg
saving aligned0005.tif
loading Image_305.jpg
remapping Image_305.jpg
saving aligned0006.tif
loading Image_306.jpg
remapping Image_306.jpg
saving aligned0007.tif
loading Image_307.jpg
remapping Image_307.jpg
saving aligned0008.tif
Written aligned images to files with prefix "aligned"
Если вы фотографируете макро, что часто искажаются пропорции предметов на разной фокусировке. В таких случаях бывает, что вырванивание может занимать целую вечность. Попробуйте без него, хотя результат будет хуже.
Теперь сшиваем все воедино с помощью Enfuse. Основной принцип — выделение наиболее контрастных и резких деталей на каждой картинке для последующего сшивания. Небольшое гало все же остается.
Запускаем:
enfuse -o result.jpg -v --exposure-weight=0 --saturation-weight=0 --contrast-weight=1 --hard-mask *.tif
-o result.jpg — финальный файл для вывода, *.tif — маска для input. tif — результат вывода предыдущей утилиты, но если вы сшиваете исходники с другим расширением — замените соответственно.
Примеры сшивания
Я не буду приводить все фотографии серии, лишь несколько для примера.
Банка джема:
Специальная лабораторная салфетка под микроскопом:
Комментарии (55)
knagaev
13.05.2016 13:16+3Не могу назвать себя впечатлительным, но что-то поймал себя на ощущении, что хочется почесаться :)
Может на КДПВ лучше солдатика?
А милаху под спойлер?
И вообще лучше бы добавить фотографий симпатичной коллеги.
Сама статья отлична — кратко и по делу.
Спасибо!
themtrx
13.05.2016 13:29+5Ах, теги!
Meklon
13.05.2016 13:39+4Рад, что понравилось. У нас Диана, которая мелькала в публикации про кофе, уже готовит чемоданы практически и нервно озирается. Она целый месяц рядом с растением сидела, а клещей не видно, они всего 100 мкм, ужас!!!. Устроил им локальный геноцид. Вроде отпустило)
kraidiky
13.05.2016 13:44Так и напрашиваются послойные разрезы животинки на основе попадания деталек в фокус и улучшение картинки за счёт обратного анализа точек не в фокусе, есть такие алгоритмы. Позволяют прочитать текст от которго на фотке только серое пятно видно.
Может в профессиональном софте что-то такое и потому он столько стоит?Meklon
13.05.2016 13:46Нет, просто это завернуто в удобный GUI и чаще всего продается в нагрузку к дорогому оборудованию. А так я уже давно здесь работаю только со свободным софтом и все прекрасно. Алгоритмы базовые по сути.
Meklon
13.05.2016 14:37+2Вот, например, плагин Extended Depth of Field для ImageJ. Он по карте резкости строит трехмерную карту высот. Тоже свободный софт.
LoadRunner
13.05.2016 15:01Блин, по КДПВ я ожидал, что статья будет вокруг этого милого существа (со всеми подробностями), но всё равно крутая статья, мне нравится.
Zzzuhell
13.05.2016 15:21+1это животное вяло шевелилось даже будучи залитым спиртом
Не понял. Оно вяло шевелится благодаря или вопреки спирту?Meklon
13.05.2016 15:26Вопреки) Без спирта оно начало бодро махать своими лапами и сфотографировать было уже невозможно. На видео заметно. А микроскоп у меня странно реагирует на быстрые движения. Собственно, камера не предназначена для этого. Пришлось сделать ему наркоз.
Zzzuhell
13.05.2016 15:33А заформалинить до полного обездвиживания? Или заэфирить?
Meklon
13.05.2016 15:35Спирт как раз вариант заэфиривания)
Zzzuhell
13.05.2016 15:38Это понятно. Странно, что не вырубило полностью :)
Alexeyslav
13.05.2016 15:44Пост-эффекты, даже мертвые иногда шевелятся, а лягушек в своё время из-за этого эффекта использовали для обнаружения приближающейся грозы.
По хорошему-то надо было сутки выдержать, но как при этом справится с неуёмной тягой к интересному?
Alexeyslav
13.05.2016 15:33Хм… а почему не вид «с лица»? Чтобы уж совсем читателей не пугать?
Meklon
13.05.2016 15:35Лицо очень условное. Он навылет прозрачный. Желудок видно, какие-то органы выделения.
askbow
13.05.2016 19:39Прозрачные, значит? А я сначала подумал, что это рентген: уж очень похоже на фото из сканера в аэропорту по цветовой гамме и выделению границ элементов объекта
Meklon
13.05.2016 20:12Толщина примерно 15 микрометров. Они в длину всего 100. Свет тупо насквозь проходит. Очень тонкие.
Alexeyslav
15.05.2016 17:56+2На некоторых толщинах даже металлы становятся прозрачными. Нет в мире ни одной непрозрачной вещи. Кроме чёрных дыр.
Greendq
13.05.2016 15:54Уфф, я-то думал, оно действительно мозги естЪ. :) Но всё равно прикольно.
Meklon
13.05.2016 16:14+3
Вы это Диане расскажите. Не факт, что получится переубедить) У нее рабочее место рядом.Greendq
13.05.2016 17:06Диана, милочка, если бы они ели мозг — они бы тебя уже бы съели. Отсюда вывод — Иван тебя обманывает и на самом деле никаких клещиков в цветке не было, он подсунул картинки грязным хаком микроскопа. ;-) А цветочку просто удобрения нужны были.
З.Ы. Ну как, убедительно? ;-)nikitasius
14.05.2016 00:56+2Целостность мозга можно проверить фонариком в ухо, если глаза блестят… то все плохо.
LoadRunner
13.05.2016 17:28+3Зёрна кофе не в фокусе. Не работает Ваш метод :-р
Meklon
13.05.2016 18:14+2Диана дергалась. Она вообще чаще всего непрерывно шевелится)
Greendq
13.05.2016 19:09+8На неё спиртосодержащие растворы не действуют успокаивающе? ;-)
Meklon
13.05.2016 19:25+4У нас спирт только для протирки оптики микроскопов!))
LoadRunner
13.05.2016 22:27+1Подышать на ватку и протереть?
nikitasius
14.05.2016 00:57Скорее уж подышать на микроскоп после… и протереть.
Alexeyslav
15.05.2016 18:00+1Так только слюни по чувствительной оптике разотрёшь, разводы потом гарантированы.
ComodoHacker
14.05.2016 12:30Мало того, что это животное вяло шевелилось даже будучи залитым спиртом, так еще и было слишком объемным, чтобы влезть в резкую зону разом.
А такой хак, как придавить стеклом не прокатит?Meklon
14.05.2016 12:54Раздавит, вероятно. Но для простой фотографии хватило и спирта. У меня вообще есть специальная эпоксидная смола для фиксации препаратов. Просто смысла большого нет) и проблемы ГРИП это не решает.
ComodoHacker
15.05.2016 11:04Раздавит, вероятно
Да и бог с ним. :)
и проблемы ГРИП это не решает
Как не решает, раздавит же. :) Я с этой целью и предложил.
Psychosynthesis
17.05.2016 18:30Enfuse схоронил, полезный инструмент. Хотя, я так понимаю, примерно то же легко руками в фотошопе сделать, хоть и чуть дольше.
Тут на хабре мелькала ещё программулина, позволяющая смазанные изображения восстанавливать, но работала как-то не особо, отчего не прижилась. Вот интересно, допилил ли автор её до ума, жаль название не вспомню, не могу сам проверить.Meklon
17.05.2016 19:54Насчёт ручного режима, я выше картинку привел. Руками такое делать ужасно. А если изображений около 1000?
Meklon
Да, кстати, эти милахи восьминогие отлично истребляются препаратами на основе аверсектина. Если вдруг кому актуально. Они не насекомые и обычные инсектициды им безразличны.
agarus
А спрегаль? )
Meklon
Слабее) он заточен так, чтобы человеков не убивать при нанесении. Аверсектин — смесь жестких токсинов бактериальной природы. Хуже только фосфоорганика, но это гуано стойкое и потом есть нельзя нормально то, что опрыскал. А я перцы коллекционирую. Жалко. Trinidad Moruga Scorpion набирается сил понемногу)
Psychosynthesis
Что значит не насекомые? А что это тогда? Грибы?
Meklon
Клещи относятся к паукообразным. На количество ног посмотрите как минимум.