Показаны сообщения с ярлыком графика. Показать все сообщения
Показаны сообщения с ярлыком графика. Показать все сообщения

20101126

unplot.py: извлекаем табличные данные из графиков

Недавно разгребал резервные копии, и обнаружил скрипт, который, пожалуй, может кому-нибудь пригодиться. Программа делает действие обратное построение графику: по изображению графика восстанавливает таблицу с числовыми данными. Поэтому она и называется unplot.

Скачать: unplot.py.

Исходники лежат на bitbucket. Исправляйте и улучшайте.

Перед запуском программы нужно вначале определить координаты (в пикселях) той части графика, которую надо обработать. Это можно сделать в Gimp или в Geeqie.

Если на графике несколько линий, то нужную из них нужно покрасить отдельным цветом, отличным от всех других. Это тоже можно сделать в Gimp. Нужно записать HTML-код её цвета.

В общем, исходный график должен выглядеть примерно так:

colourized plot

После этого можно запустить и сам скрипт:

./unplot.py "#00ff00" 0 151 0 475 5.0 824 0.09 85 /путь/к/plot.png > /путь/к/data.txt


Первый параметр — это код цвета линии. Вторые два числа это значение и координата X левого нижнего угла. Потом ещё два числа, значение и координата Y того же угла. Потом ещё четыре числа — соответственно для правого верхнего угла. И в конце имя файла с графиком. Результаты (текстовую таблицу с данными) перенаправляем в файл. Можно ещё задавать «чувствительность» к цвету (параметр -s).

После применения скрипта полезно построить ещё раз график по полученным точкам и убедиться, что выбран правильный участок графика, указан правильный цвет и разумные числовые значения точек. Например, в этом случае я захватил слишком много справа, и зелёные буквы тоже были учтены как точки графика.



Обновление 20101203: теперь скрипт умеет обрабатывать графики с линией толще 1 пикселя; также в репозитории появился и небольшой скрипт для тестирования unplot.py на вменяемость.


Flattr this


По-английски: Unplot.py: from plots to tabular data.

20091016

Микросоветы

Всё чаще в твиттер
одной строкой пост целый
пишу на память.

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

Приёмы работы
LaTeX и вёрстка
Программирование
Находки (всякие программки)

1. Приёмы работы:

  • Чтобы не закрывать Firefox, когда закрывается последняя вкладка по Ctrl-W: идём в about:config, находим browser.tabs.closeWindowWithLastTab, ставим false. Проверено на FF 3.5.
  • OpenOffice: чтобы запретить разрыв слова (т.е. запретить перенос), вставляем нечитаемый символ U+2060 (Zero-width WORD JOINER). Символ можно найти, запустив gucharmap. Надо в .XCompose добавить...
  • Чтобы использовать новый, сжимающий раза в два лучше, видео-кодировщик Theora 1.1, нужно взять саму новую библиотечку (уже есть в Debian unstable), и, главное, ffmpeg2theora версии не ниже 0.25. На сайте разработчиков есть и бинарные сборки.
  • Принудительное отключение подсветки ЖК-дисплея: xset dpms force off. Отсюда.
  • Банальность. Удаление пустых строк sed-ом: sed '/^\s*$/d'.
  • Редактируя диаграммы Graphviz в Vim, быстрый просмотр по :make можно сделать так: :set makeprg=dot\ -Tpng\ %\ \\\|display\ png:- errorformat='' autowrite. Подставить название используемой программы (dot, neato, fdp, ...).
  • Создание паролей (если нет KeePassX): cat /dev/urandom | tr -d -c 'a-zA-Z0-9' | fold -w 8 | head -1
  • Поиск и удаление дубликатов файлов: fdupes в командной строке, fslint — утилита с графическим интерфейсом.
  • В Debian можно заменить файл пакета, не пересобирая пакет. Поможет dpkg-divert.
  • sudo -i имитирует логин под рутом (даёт #). Бывает полезно (раньше sudo su - иногда пользовался).
  • Как создавать картинки предварительного просмотра видеофайлов:
    ffmpeg -itsoffset -1 -i видеофайл.avi -vcodec mjpeg -vframes 1 -an -y -f rawvideo -s 320x240 картинка.jpg ; done
    Как создавать картинки из PDF:
    convert -thumbnail 300x300 документ.pdf[0] -gravity center -extent 300x300 картинка.png


2. LaTeX и вёрстка:

  • Рекомендуемая минимальная ширина полей, чтобы документ можно было печатать и на A4, и на Letter — А4, слева и справа 20 мм, сверху и снизу 33 мм. RFC 2346.
  • Чтобы избежать разрыва страницы в LaTeX, можно поместить фрагмент текста в окружение samepage. Это частый вопрос.
  • Отступы элементов списка в LaTeX можно настроить, если использовать окружение list вместо itemize. Пример.
  • Чтобы добавить межабзацный пробел, \setlength{\parskip}{10pt plus 1pt minus 1pt}. Особенно полезно в наборе без абзацного отступа. Отсюда.
  • Чтобы выравнять картинку и текст справа от неё по вертикали, по середине, повозившись, сделал себе макрос \sidebyside{}{}:
    \newsavebox{\leftbox}\newlength{\leftboxheight}\newcommand{\sidebyside}[2]{\sbox{\leftbox}{#1}\settoheight{\leftboxheight}{\usebox{\leftbox}}\usebox{\leftbox}\raisebox{0.5\leftboxheight}{#2}}
    Смотрите пример использования.
  • Чтобы автоматически закрывать окружения LaTeX, пользователи Vim могут поставить плагин tex_autoclose. Использование: в режиме вставки Ctrl+\, затем c.
  • Разрезать на страницы и «склеивать» PDF-документы можно с помощью pdftk. Объединить два файла в один:
    pdftk первый.pdf второй.pdf cat output новый.pdf


3. Программирование:

  • В Python, примитивное транспонирование списка пар в пару списков:
    unzip = lambda pairs: zip(*pairs)
    @vlasovskikh подсказал, что для больших списков izip будет быстрее (проверили, так).
  • Занятное и доходчивое объяснение «что такое продолжения» на 11-й минуте видеопрезентации Swarm-dpl.
  • Быстро создавать графический интерфейс для научных программок позволяет библиотечка TraitsUI (Python). Пока не пробовал, но прочитал урок по TraitsUI.
  • Говорят, Intel готовит Concurrent Collections и для Хаскеля.
  • Я же пока проснулся и прочитал про со-процедуры на Си и устройство Даффа. Впечатлился.
  • Хотите полюбоваться, как можно добавлять побочные вычисления «наследованием» типов? Вот, пожалуйста, в этом примере (на Хаскеле). Хотя это, конечно не Java.
  • Учился использвать монадные трансформеры (бррр!) — оказалось несложно. В результате получился такой пример использования StateT поверх IO. Может кому пригодится.
  • Мелкое копирование словарей в Python — грабли.


4. Находки (всякие программки):

  • Atrack — анонимный открытый битторент трекер для Google App Engine. Всего 246 строк кода.
  • Sweet Home 3D — программа для планирования интерьера. Можно рисовать планы комнат, расставлять мебель, крутить по всякому. Сделана красиво.
  • fuse-zip — файловая система FUSE для монтирования zip-архивов. Быстрая, легко собирается по make, умеет писать в архив. Использование:
    fuse-zip архив.zip /точка/монтирования
    Есть также avfs, которая монтирует любые архивы, но не пишет и не такая удобная. Её использовать так:
    mountavfs ; ls ~/.avfs/полный/путь/к/архиву.zip#/файл/в/архиве
    В Debian нужно предварительно добавить пользователя в группу fuse.
  • Python(x,y) — дистрибутив Python для научных работников, для Windows и Ubuntu. Все инструменты и библиотечки «из коробки».
  • В дополнение к своему однострочнику antiodt нашёл ещё хороший конвертер ODT в Markdown odt2txt.py.
  • Дружественный к Гному вариант Xmonad — Bluetile. Раз попробовал, и две недели им пользовался.
  • Попробовал gitit. Самая простая вики для совместной работы над математическими текстами (вместе с jsMath из коробки). Хранилище — git или darcs.
  • TxtSushi — утилитки, позволяющие выполнять SQL-запросы по простому текстовому (CSV, TSV) файлу.


Ух-ты, а немало получилось.

20090922

Как нарисовать стрелку в Inkscape

Очень люблю Inkscape, и часто в нём рисую разные схемы. А для того, чтобы рисовать схемы, нужны стрелки. Готового инструмента «стрелка» в Инкскейпе нет*, поэтому творю из подручных материалов сообразно вкусу и потребностям. В общем-то, минутное дело, умеючи...

Я подумал, что кому-то, возможно, будет интересно увидеть, как можно самому нарисовать практически любую стрелку. Предлагаю небольшой видеоурок, где показываю как нарисовать стрелку попроще и стрелку позатейливей:



Это мой первый скринкаст. Прошу строго не судить. Кино немое, просто с титрами.

* В инкскейпе есть маркеры конца и начала линии. Красить их нельзя, они всегда чёрные. Впрочем, подсказывают из зала, можно — создав стрелку, надо «оконтурить обводку», получить два контура (древко и острие), вручную их подправить-подравнять, и получится полноценная контурная стрелка. Я пока остаюсь приверженцем своего способа создания контурных стрелок. Впрочем, смотрите на другой способ сами (подал идею и сделал видео freedomfidaj).

20090904

Как сделать видеофайл из GIF-а и добавить поля к видео

Для того, чтобы из анимированного GIFа сделать видеофайл, я недавно использовал gifsicle (чтобы разоптимизировать GIF и разбить на кадры) и ffmpeg (чтобы сделать из кадров видео):
gifsicle -U --explode "input.gif"
for f in *.gif.* ; do mv "$f" "$f.gif" ; done
ffmpeg -r 25 -i "input.gif.%03d.gif" -sameq -s 320x240 output.flv

Если нужно добавить чёрных полей (до нужного размера), действую примерно так (в данном случае, хочу получить 320×240):
ffmpeg -i input.file -s 320x180 -padtop 30 -padbottom 30 output.file

Дополнение: с новыми версиями ffmpeg (например, 0.6.90), поля к видео добавляются с помощью видеофильтра pad:
ffmpeg -i input.file -vf "scale=320:180,pad=320:240:0:30" output.file

Я не использую для разделения на кадры ImageMagick (convert), потому что мне кажется, что gifsicle работает быстрее и требует меньше памяти.

(in English)

20090827

Декоративная табличка в LaTeX

В TeXblog появилась заметка, как делать декоративные таблички в LaTeX. Вот такие:

Fancy tables with LateX and Tikz

Табличка набрана как обычно, но внутри «узла» окружения tikzpicture, а фон и раскрашенные шапки — средствами Tikz на фоне. Исходник примера — в TeX blog.

Кстати, давно хочу написать про PGF/Tikz. Что-нибудь интересно?

20090720

Как ускорить или замедлить видеоролик

Иногда нужно замедлить (растянуть) видеоролик, чтобы он игрался как будто в режиме замедленного воспроизведения, а иногда нужно наоборот, показать «на перемотке» слишком длинный ролик, выбросить часть кадров и ускорить воспроизведение. О том как это сделать — сия заметка.

Изменить частоту кадров в видеопотоке позволяет программа yuvfps из пакета mjpegtools. Как и большинство утилит пакета она принимает и отдаёт видеопоток в формате YUV4MPEG. И ffmpeg, и mencoder тоже умеют работать с YUV4MPEG (и умеют читать и писать всякие другие форматы). Я приведу пример использования ffmpeg.

Итак, чтобы ускорить видео, нужно взять исходный файл и посмотреть, какая в нём частота кадров
$ ffmpeg -i normal.ogg
FFmpeg version SVN-r13582, Copyright (c) 2000-2008 Fabrice Bellard, et al.
...
Input #0, ogg, from 'normal.ogg':
Duration: 00:00:10.49, start: 0.000000, bitrate: 150 kb/s
Stream #0.0: Video: theora, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 30.00 tb(r)
Must supply at least one output file

В данном случае исходный файл — 30 кадров в секунду. Затем нужно решить, во сколько раз уменьшить число кадров (исходя из желаемой длительности ролика). Потом берём исходный файл (normal.ogg в примере) и преобразовываем его в YUV4MPEG-поток (первый вызов ffmpeg), после нужно дважды вызвать yuvfps, первый раз, чтобы изменить число кадров в потоке (yuvfps -s 5:2 -r 1:1 сокращает исходные 2.5 кадра до одного), второй раз, чтобы перезаписать заголовок потока, указав скорость воспроизведения (yuvfps -r 30:1 -c устанавливает скорость 30 кадров в секунду). В конце опять вызываем ffmpeg и кодируем в нужный формат (я сохранил в формате Ogg/Theora, чтобы можно было вставлять в веб-странички тэгом <video>). Всё вместе:
$ ffmpeg -i normal.ogg -sameq -f yuv4mpegpipe - | \
yuvfps -s 5:2 -r 1:1 | yuvfps -r 30:1 -c | \
ffmpeg -f yuv4mpegpipe -i - -sameq -y fast.ogg


Аналогично можно увеличить число кадров. Дополнительные кадры интерполируются:
$ ffmpeg -i normal.ogg -sameq -f yuv4mpegpipe - | \
yuvfps -s 1:3 -r 1:1 | yuvfps -r 30:1 -c | \
ffmpeg -f yuv4mpegpipe -i - -sameq -y slow.ogg

В этот раз видео замедляется в 3 раза: на каждую «треть» исходного кадра (-s 1:3) создаётся целый кадр (-r 1:1). Вообще, как легко заметить, в качестве частоты кадров для yuvfps можно указывать любые дроби в виде числитель:знаменатель.

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

Теперь можно сравнить все три видео. Для просмотра нужен современный браузер с поддержкой тэга <video/>.

Исходное видео:



Ускоренное в 2.5 раза:



И замедленное в 3 раза:



P.S. В качестве иллюстрации использовал ролик Breitenlee-VESTAS-V-52.

20090504

Исправление дефектов кожи и ручное удаление шума в GIMP

Александр Прокудин описал очень интересное расширение для GIMP — вейвлетный разбор. За красивым названием — мощнейший инструмент. Можно использовать для:
  • ретуши дефектов кожи,
  • избирательного ручного удаления шума,
  • выделения или удаления деталей определённого размера,
  • смягчения границ...
Принцип действия: вейвлетным преобразованием изображение разделяется на несколько слоёв, каждый с деталями разного размера (разной «длиной волны»), от слоя с мелкими деталями наверху к слоям со всё более крупными деталями внизу. Благодаря такому разбору изображения на слои можно исправить, например, мелкие детали, не затрагивая крупных.

Для установки в Ubuntu Jaunty: скачиваем исходники, устанавливаем пакет libgimp2.0-dev, распаковываем исходники во временный каталог, make, make userinstall.

Расширение появляется в меню ФильтрыОбщиеWavelet decompose.

20090403

Русские буквы в matplotlib/pylab

Усилиями некого Алексея сегодня мы все наконец узнали как в Matplotlib/Pylab делать подписи по-русски. Вот работающий пример:
#!/usr/bin/env pytnon
# vim: set fileencoding=utf-8 ts=4 sw=4 expandtab:

# Cyrillic letters in Matplotlib,
# thanks to Alexey for solution, see http://koldunov.net/?p=290#comments
from matplotlib import rc
rc('font',**{'family':'serif'})
rc('text', usetex=True)
rc('text.latex',unicode=True)
rc('text.latex',preamble='\usepackage[utf8]{inputenc}')
rc('text.latex',preamble='\usepackage[russian]{babel}')

from pylab import *

def figsize(wcm,hcm): figure(figsize=(wcm/2.54,hcm/2.54))
figsize(13,9)

x = linspace(0,2*pi,100)
y = sin(x)
plot(x,y,'-')
xlabel(u"ось абсцисс")
ylabel(u"ось ординат")
title(u"Две беды в России — синусы и косинусы!")
savefig('rus-mpl.pdf')
И вот результат:



По теме:
Matplotlib. Простые вещи — 1
Matplotlib. Простые вещи — 2
Как построить график с изолиниями в gnuplot, gri и pylab
Короткие «рецепты» по применению Python в околонаучных целях

PS. Как, кстати, лучше PDF в растр конвертировать? Я делаю так:
$ pdftoppm -r 300 image.pdf | convert ppm:- image.png
Дополнение: ещё лучше вариант предложил Дмитрий Душкин:
from matplotlib import rc
font = {'family': 'Droid Sans',
        'weight': 'normal',
        'size': 14}
И всё отлично работает.

20090316

Wacom Bamboo Fun в Debian Lenny

Начну с приятного. Планшет Bamboo Fun* в Debian Lenny поддерживается, в смысле, что собирать самостоятельно драйвера Wacom не надо. Годятся дистрибутивные. У меня стоят соответственно пакеты wacom-tools и xserver-xorg-input-wacom версии 0.7.9.3-2.

* а вот владельцам Bamboo One, похоже, повезло меньше, судя по-всему им придётся установить драйвера самостоятельно, поддержка Bamboo One заявлена лишь начиная с wacom-tools 0.8.2.2


Однако для нормального использования, нужно внести настройки планшета в /etc/X11/xorg.conf. Во-первых, я добавил туда раздел ServerLayot, которого по-умолчанию там не было:

Section "ServerLayout"
Identifier "Default Layout"
Screen "Default Screen"
InputDevice "Configured Mouse"
InputDevice "Generic Keyboard"

InputDevice "stylus" "SendCoreEvents"
InputDevice "eraser" "SendCoreEvents"
InputDevice "cursor" "SendCoreEvents"
InputDevice "pad"
EndSection


Во-вторых, добавил описания для все четырёх устройств ввода планшета (оба конца пера, указатель курсора и кнопки планшета).

Section "InputDevice"
Identifier "stylus"
Driver "wacom"
Option "Type" "stylus"
Option "USB" "on"
Option "Threshold" "10"
Option "Device" "/dev/input/wacom"
EndSection

Section "InputDevice"
Identifier "eraser"
Driver "wacom"
Option "Type" "eraser"
Option "USB" "on"
Option "Threshold" "10"
Option "Device" "/dev/input/wacom"
EndSection

Section "InputDevice"
Identifier "cursor"
Driver "wacom"
Option "Type" "cursor"
Option "USB" "on"
Option "Threshold" "10"
Option "Device" "/dev/input/wacom"
EndSection

Section "InputDevice"
Identifier "pad"
Driver "wacom"
Option "Device" "/dev/input/wacom"
Option "Type" "pad"
Option "USB" "on"
EndSection


После этого нужно перезапустить графическую подсистему («иксы»). Т.е., если используется графический экран входа в систему, то подключить планшет нужно ещё до появления этого экрана. Если курсор там управляется планшетом нормально — входить и работать. Если же планшет там не подхватился, то, не входя в систему, нажать Ctrl + Alt + Backspace. Графическая система перезапустится. После этого планшет должен уж точно подхватиться.

Внимание! Если планшет отключить (выдернуть из USB-порта), то придётся выходить из системы, чтобы он заработал опять. Не очень удобно, но так вот пока сделано... Зато работает и стёрка, и перо, и кнопки. В Убунту по-умолчанию планшет подхватывается сам, но чтобы заработала и стёрка, и кнопки, придётся всё равно сделать как в Debian.

После этого в используемом приложении (Gimp, Inkscape) нужно указать, какие устройства планшета надо включить. Конкретно в Gimp 2.4 нужно пойти в Файл, Настроить, Устройства ввода, Настроить дополн. устройства ввода. Далее последовательно выбрать все устройства планшета (stylus, eraser, cursor, pad) и включить каждое из них, установив режим «Экран» или «Окно». Нажать Сохранить.

Включить планшет в Gimp

Дополнительные возможности регулировки нажима кисти есть в новом Gimp 2.6, но в Debian Lenny старый добрый 2.4. В нём всё минималистично:

Настройки чувствительности кисти в Gimp 2.4

Утилитки wacomctl в Debian Lenny нет. Впрочем, может и к лучшему. Настроить параметры планшета и запрограммировать его кнопки можно из коммандной строки с помощью xsetwacom. Есть также графические утилитки Gnome Tablet Apps, которых в Lenny тоже нет, но поставить несложно. Выглядят они вот так:

Gnome Tablet Apps: регулируем чувствительностью планшета к нажатию

Однако вернёмся к не такой яркой, но универсальной утилитке xsetwacom. Ниже я расскажу, как регулировать чувствительность к нажатию. Для себя я описываю его «гаммой» нажатия. Гамма равная 1 соответствует настройке по умолчанию, гамма равная 2 соответствует очень сильной чувствительности к слабым нажатиям, гамма равная 0 соответствует очень слабой чувствительности к слабым нажатиям.

Параметры кривой чувствительности планшета вычисляются для данной гаммы длинной командой, которую я его сделал алиасом (pressgamma ниже). В ~/.bashrc поместил следующее:
alias pressgamma="awk 'BEGIN{ b=3.14*ARGV[1]*0.25; x=int(50*1.41*cos(b)); y=int(50*1.41*sin(b)); print x, y, 100-y, 100-x; }'"
function setwacomgamma { xsetwacom set stylus PressCurve `pressgamma $1` ; }
Теперь, посмотреть параметры кривой чувствительности для произвольной гаммы,
$ pressgamma 0.7
60 36 64 40
А установить нужную чувствительность планшета можно командой
xsetwacom set stylus PressCurve `pressgamma 1.2`
или просто
setwacomgamma 1.2


Дополнение. На сайте Wacom можно зарегистрировать свой планшет указав операционную систему Linux.

20081209

Пример рисования в PyCairo

Пробуя библиотеку для рисования Cairo из Python, сделал такую вот табличку:



У кого браузер не поддерживает SVG, сморим PNG.

Идею нарисовать временную шкалу использования языков программирования дал мне вот этот опрос на StackOverflow («В каком возрасте вы начали программировать?»).

Кто хочет себе такую же табличку (в смысле, аналогичную), скрипт к вашим услугам (Public Domain). Требует PyCairo (python-cairo).

Оказалось, рисовать из Python в Cairo очень просто. При этом можно получать изображения в векторном формате (PDF, PostScript, SVG), не говоря уже о PNG. Можно будет использовать в будущем для автоматизированного создания схем и графиков, если готовых программ вдруг не хватит.

Есть самоучитель Cairo Tutorial (тоже на примере Python). Если очень кратко, то это делается так:

Шаг 1. Импортируем модуль:
import cairo

Шаг 2. Создаём «поверхность» и берём из неё «контекст» для рисования. Я рисовал сразу в SVG файл:
svg=cairo.SVGSurface("имяфайла.svg",ширина_в_пунктах,высота_в_пунктах)
ctx=cairo.Context(svg)

Шаг 3. Рисуем, используя контекст:
ctx.set_line_width(ширина_линии) # выбираем линию
ctx.set_source_rgba(красный,зелёный,синий,прозрачность) # выбираем цвет
ctx.move_to(x,y) # перемещаем «курсор»
ctx.line_to(x2,y2) # рисуем линию от позиции «курсора» до x2,y2
ctx.arc(x,y,радиус,угол1,угол2) # рисуем дугу с центром в (x,y)
ctx.close_path() # замыкаем контур
ctx.fill() # заливаем контур выбранным цветом
ctx.stroke() # обводим контур выбранной линией
ctx.set_font_size(размер_шрифта) # выбираем размер шрифта, можно дробный
ctx.show_text("буквы") # пишем слово «буквы»

Шаг 4. Нарисовавшись всласть, сохраняем результат (закрываем «поверхность»):
svg.finish()
В качестве справки используем документацию по Cairo для языка Си. Изменения для Python-скриптов вполне очевидны: вместо передачи параметров cairo_t *cr используем методы объекта-контекста. Аналогично для поверхностей.

20081025

Как сшивать панорамы

Давно хотел написать эту заметку. Расскажу о том, как можно сравнительно легко склеивать панорамы из отдельных фотоснимков. Хотя на всех иллюстрациях снимки экрана сделанны в линуксе, все описываемые программы доступны и пользователям других операционных систем (Windows, MacOS X). Так что аудитория этой заметки заметно шире моей обычной аудитории. В отличие от панорамного софта, который чаще всего упоминается в рунете, эти программы свободны и распространяются бесплатно. Итак, герои сегодняшнего дня:

Hugin. Графический интерфейс для склейки панорам. В примерах использовалась версия 0.7.0-beta5. Программа названа в честь одного из воронов Одина.

Autopanosift. Программа ищет «связующие точки» между отдельными кадрами. В большинстве случаев вызывается из Хугина.

Enblend. Бесшовно склеивает отдельные кадры в единое изображение. Она обычно тоже запускается автоматически из Хугина, хотя в сложных случаях её можно запускать и вручную.

Ещё потребуется какой-нибудь графический редактор. В примерах у меня будет показан nip2 (умеющий работать даже с очень большими изображениями) и Gimp. В общем, это дело вкуса.

В общих чертах, технологический процесс выглядит так:

  1. снимаем фото,
  2. загружаем отдельные кадры в Хугин,
  3. ищем «связующие точки» между отдельными кадрами, или автоматически (с помощью Autopanosift), или вручную,
  4. оптимизируем панораму (после этого отдельные кадры располагаются так, чтобы связующие точки по возможности совпадали), смотрим на предварительный результат,
  5. окончательно выбираем проекцию и склеиваем кадры в единую панораму (на этом этапе пригождается Enblend),
  6. обрезаем сшитую панораму, проверяем на наличие ошибок сшивки,
  7. окончательно ретушируем кадр, как в случае обычных фото.
Теперь подробнее о каждом этапе.

Как снимать панорамы


Нужно взять фотокамеру и последовательно снимать фрагменты будущей панорамы. Здесь есть несколько тонкостей:

  • кадры должны перекрываться примерно на треть, это необходимо для успешного поиска связующих точек между отдельными кадрами,
  • составлять горизонтальные панорамы удобнее из вертикальных кадров, таким образом вертикальный угол зрения однорядной панорамы будет шире, панорама будет восприниматься естественнее при просмотре целиком на экране компьютера, больше будет запас для окончательного кадрирования,
  • чаще всего удобно снимать с широким углом изображения (на минимальном «зуме»), в этом случае панорама будет состоять из минимального числа кадров (и наоборот, когда цель состоит в создании максимально детальной панорамы, стоит снимать длиннофокусным объективом, но в несколько «рядов»),
  • используйте бленду или прикрывайте объектив рукой, чтобы избежать бликов на объективе (при съёмке панорам часто приходится снимать почти против света),
  • не используйте поляризатор, хотя он и делает цвета сочнее на отдельных кадрах, из-за него небо на панораме в целом выглядит неестестсвенно,
  • снимайте все кадры панорамы с одними и теми же настройками экспозиции и баланса белого; хотя Хугин и Enblend и умеют выравнивать экспозицию и баланс белого в итоговой панораме, это не всегда получается достаточно хорошо, а разные цветовые тона сразу делают заметными отдельные кадры в панораме; тут очень может пригодится ручной режим экспозиции в фотокамере (если такой есть),
  • то же относится и к фокусному расстоянию, сшивать будет проще, если все кадры будут сняты с одним и тем же фокусным расстоянием,
  • старайтесь снимать с горизонтально выровненного штатива, если есть такая возможность; конечно, можно успешно снять панораму и с рук, но очень многие панорамы мне не удались именно из-за того, что я поленился достать штатив,
  • как в случае штатива, так и в случае съёмки с рук, важно обеспечить неподвижность оси вращения камеры, в идеале она должна проходить через оптическую ось объектива; особенно хорошо, если ось пройдёт через «точку без параллакса» (вот тут о её поиске по-английски),
  • последние два правила особенно важны, если объекты переднего плана расположены близко к камере,
  • лучше снимать все кадры последовательно в одном направлении, или слева направо, или справа налево, это минимизирует смещение подвижных объектов (например, облаков) в соседних кадрах; если в панораму попадает какой-то быстродвижущийся объект (например, машина, животное, человек), то потом бывает удобно иметь любой кадр панорамы в двух вариантах, с объектом и без него.
Многие из этих «хитростей» я почерпнул отсюда (текст по-итальянски). Это проект, который объединяет 380 круговых панорам, снятых с разных вершин в западных Альпах. Кстати, интересный пример того, что можно сделать со снятыми панорамами.

В результате получаем набор кадров будущей панорамы. Например, такой:



Как склеивать кадры в Hugin



Запускаем Хугин. В современных версиях Хугина все основные действия доступны прямо с его первой вкладки. По порядку, сверху вниз. Вначале загружаем фото:



После этого нужно создать контрольные точки. Жмём «Объединить…»:



После этого запустится Autopanosift:



Как правило, достаточно нажать кнопку «Compute» и дождаться, пока программа найдёт все контрольные точки.



Когда Autopanosift закончит, кнопка «Exit» в его окошке станет доступна:



Жмём и попадаем обратно в Хугин. Вначале откроется окно предварительного просмора



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



Однако закроем предварительный просмотр и вернёмся на первую вкладку Хугина. Там будут указаны параметры оптимизации. В данном случае предварительный результат оставляет желать лучшего:



Максимальная погрешность оптимизации составила 25 пикселей, т.е. одна из контрольных точек отстоит от своей пары на соседнем снимке на 25 пикселей. Это действительно плохо.

Перейдём на вкладку «Контрольные точки» и, попарно разглядывая кадры, посмотрим, как их расставил Autopanosift. Вот, например, и наша проблемная точка:



Проблемная точка оказалась где-то в облаках. И это хорошо, это легко исправить. Вообще, следует избегать размещения контрольных точек на изменчивых объектах: облаках, качающейся траве, волнах. Контрольные точки на таких объектах — почти гарантия проблем сшивки.

К сожалению, Autopanosift не умеет распознавать объекты на фото и предсказывать их поведение. Поэтому результаты его работы требуется корректировать вручную. В частности, точки на облаках можно просто убрать.

Другой нюанс. Autopanosift не умеет распознавать линию горизонта или гор, или стену здания, а для зрителя очень важно, чтобы они были ровными, неразрывными. Чтобы это обеспечить, проще всего просто добавить кое-где точки вдоль таких линий, тогда их положение будет учитываться при оптимизации панорамы.

На иллюстрации я добавляю такую точку:



Для этого я щёлкаю на выбранной точке на снимке слева, а затем примерно в том же месте на снимке справа. Чаще всего Хугин правильно размещает парную точку на втором снимке. Иногда же ему это не удаётся, и тогда можно увидеть такое сообщение:



Ничего страшного, парную точку можно уточнить вручную. Современные версии Хугин услужливо увеличивают окрестность точки, так что правильно поставить парную точку легко. Уточнив её положение, нажимаем «Добавить».

Ещё пара советов о расположении точек: избегайте «кучкования» всех контрольных точек в одном месте, особенно если это место находится на переднем плане, небольшие ошибки в положении этих точек будут соответствовать большим смещениям кадра при оптимизации. Старайтесь «выкладывать» контрольные точки вдоль важных для глаза контуров (и наоборот, не ставьте слишком много там, где глаз не чувствует линии).

Вот, например, сравните как расставила точки программа:



и как лучше их расположить:



Есть ещё один тип контрольных точек, пример которых я не буду приводить, потому что в данной панораме они не понадобились. Если обе точки пары поставить на один и тот же кадр, то зададут горизонталь или вертикаль в этом кадре. Это полезно, если в кадре есть архитектурные сооружения или деревья. Один известный дизайнер много писал о том, что здания на фотографиях должны стоять вертикально.

Поправив контрольные точки, попробуем ещё раз оптимизировать панораму. Кстати, если перейти на вкладку «Оптимизатор», то можно будет выбрать, какие именно параметры кадра оптимизировать. Мне кажется, что очень часто лучших результатов можно достичь, если оптимизировать не только положение кадра, но и его поворот вокруг оптической оси, «(y,p,r)». Особенно это верно для панорам, снятых с рук (снимая с рук, легко нечаянно немного наклонить камеру).



Заново оптимизировав, можно ещё раз посмотреть на результат в области предварительного просмотра:



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

Очень полезны функции «По центру» и «Уместить», а вот функцией «Выровнять» надо пользоваться осторожно. Если панорама была снята с горизонтально выровненного штатива, то выравнивание вообще не должно требоваться, если же сняли с рук, и кадры пошли «волной», то иногда выравнивание помогает убрать волну, но мне кажется, что при этом ухудшается результат сшивки. Функция «Выровнять» в Хугине довольно новая.

Теперь, если всё в порядке, делаем последний шаг. Переходим на вкладку «Сшиватель», выбираем проекцию, советую ещё раз рассчитать поле зрения и выбрать оптимальный размер (при котором не происходит уменьшения изображения).



Для просмотра на экране целиком, на мой взгляд, очень хорошо подходит цилиндрическая проекция. Если же планируется просматривать в тех или иных программах просмотра, например в апплете PTViewer, то лучше использовать эквидистантную проекцию (или ту, которую требует программа просмотра). А «рыбий глаз», по-моему, лучше всё равно снимать «рыбьим глазом».

Результат сшивки я всегда сохраняю в формате TIFF, потому что потом его ещё приходится редактировать. Жмём «Собрать», и ждём:



Ждём долго, это, пожалуй, самый долгий вычислительный процесс во всей технологической цепочке. Конец этого процесса выглядит примерно так:



Всё. У нас теперь есть большой файл со сшитой панорамой. Сохраняем проект Хугина и закрываем. Дальше нужно довести сшитую панораму до ума.

Обработка сшитой панорамы



Итак, у нас теперь есть TIFF-файл со сшитой панорамой. Он может быть довольно большим. В этом примере он получился 101 мегабайт. В действительно больших панорамах счёт может пойти на гигабайты. Поэтому я приведу пример, как можно обрезать панораму в редакторе nip2, который может работать даже с изображениями, размер которых превышает размер оперативной памяти.



Вообще, редактор nip2 довольно нетрадиционный. Советую для первого знакомства посмотреть заметку о нём Михаила Конника. Редактор по принципу работы больше похож на электронные таблицы, но работает действительно быстро.

Чтобы обрезать нашу панораму, дважды щёлкнем по ячейке с исходным файлом A1. Откроется новое окно с изображением:



Масштабируем с помощью Ctrl+колёсико мышки. Зажав Ctrl и перетягивая мышку от левого верхнего угла к правому нижнему выделяем прямоугольную область:



Да, выделять прямоугольную область в nip2 нужно именно так: от верхнего левого угла к правому нижнему и зажав Ctrl.

Теперь в главном окне nip2 появляется новая ячейка A2:



Именно содержимое этой ячейки (уже обрезанную панорамe) мы и сохраняем в файл.

В данном случае я обрезал с небольшим запасом, поэтому в одном месте на краю панорамы есть дырка:



По-моему, лучше оставить такую дырку в малозначительном месте, чем отрезать что-то важное в другом месте панорамы. А в малозначительном месте можно помахать клонирующей кистью:



Наконец, сохраняем окончательный вариант панорамы, добавляем геотаги, и любуемся:



Чтобы добавить геотаги потребуется скопировать EXIF-теги из исходных кадров в окончательный вариант панорамы. Я это делают так:
$ exiftool -tagsfromfile первый-кадр.jpg панорама.jpg
Это не совсем правильно, но быстро.

Что ещё можно сделать с панорамой?



Одно из самых интересных панорамных сообществ, на мой взгляд, группа Perfect Panoramas на фликере. Туда принимают только те панорамы, в которых модераторы не найдут дефектов.

Есть фотосообщество в ЖЖ, тоже посвященное панорамам. Не помню, как называется.

Панорамам с геотегами — самое место на Panoramio. Хорошие панорамы потом покажут в Google Earth :)

В интернете панорамы можно показывать с помощью апплета PTViewer.

Дополнение 2010-02: со времени написания заметки появился хороший панорамный хостинг pan0.net. На него можно выкладывать как круговые, так и частичные панорамы. Есть флэш-просмотрщик, который можно легко вставлять в блоги.



Перфекционисты и любители монументального искусства могут снимать гигапиксельные панорамы.

Ну и в общем ещё много разных применений этой техники. В том числе и вполне серьёзных.

Успехов!

PS. Я нашёл ещё два сходных руководства на русском языке: Клеим панораму Александра Прокудина и Склейка панорам в Hugin (© БэЖэ). Много учебных материалов доступно на сайте программы Hugin, но, увы, только на английском языке.

20080930

Ошибка сохранения файла в GIMP при нехватке памяти

При редактировании больших изображений в GIMP иногда можно столкнуться с ситуацией, когда нужные правки уже сделаны, но файл сохранить не удаётся. Ошибка, которую выдаёт GIMP в этом случае связана с тем, что вся доступная память уже израсходована под хранение данных изображения, и запустить дочерний процесс, который сохранит файл, GIMP уже не может. К счастью, это совсем не означает, что результаты редактирования сохранить нельзя и они будут потеряны. Файл можно сохранить, очистив предварительно историю изменений.

Увидеть, сколько занимает изображение в памяти GIMP можно в строке состояния окна изображения. Например, в данном случае изображение занимает в памяти 164 МБ:


Если это значение сопоставимо с размером оперативной памяти компьютера, то GIMP не только будет работать медленно (из-за обращения к диску), но и может испытывать сложности с сохранением изменённого файла. При редактировании изображения это значение растёт.

Однако при большом количестве изменений значительная часть памяти приходится не на хранение самого изображения, а на хранение промежуточных результатов (необходимых, чтобы работала функция «отмены»). Если удалить историю действий, то можно обычно освободить немало памяти. Выбираем в меню редактируемого узображения «Правка → История действий» и видим такой диалог:


На иллюстрации помечена кнопка, позволяющая принудительно очистить историю изменений. После этого перестанет работать функция «Отмены», но зато освободится память.

Вообще, настроить желаемое количество уровней отмены можно в разделе «Окружение» настроек GIMP.

PS: Кто-нибудь знает, каким свободным софтом можно обрабатывать действительно большие изображения (т.е. такие, которые не помещаются в оперативную память)? Желательно, чтобы программа умела подгружать изображение «по частям». Меня интересуют прежде всего операции кадрирования, поворота на произвольный угол, коррекция кривых и цветов. Спасибо читателям за подсказку, что действительно большие изображения можно редактировать в nip2 (обзор здесь). Разбираюсь.

Смотрю с большой надеждой на формат JPEG2000, в котором есть поддержка произвольного доступа к областям изображения, но пока он, похоже, поддерживается только в ImageMagick. При этом ковертация JPEG→JPEG2000 требует много больше памяти, чем размер несжатого TIFF-а с тем же изображением. В придачу большинство просмотрщиков работать с JPEG2000 не могут.

20080612

Garmin GPSmap 60Cx: подключение и использование в Linux

Вчера стали обладателями вот такого устройства, GPS-навигатора Garmin GPSmap 60Cx:Устройство позволяет пользоваться загружаемыми векторными картами и имеет карточку памяти. Впрочем, все возможности ещё только предстоит научиться использовать. Карты надо научиться делать самим (те, что в продаже, стоят безумно дорого, но, главное, нормальных топографических карт нет, всё больше дороги…) — но это отдельная тема (кое-какие инструкции (1) уже (2) нашёл (3)). Вчера же вечером прокатились на велосипедах, чтобы записать тестовый трек, а после я пытался «подружить» это чудо со своим GNU/Linux. Ниже краткий конспект.

Подключается GPSmap 60Cx по USB (кабеля для подключения по последовательному порту в комплекте нет). Причём может подключаться в двух режимах: USB Mass Storage (ну с этим всё понятно, как флэшка, при отключении — устройство перезапускается) и по своему собственному протоколу (по умолчанию). Дальше я буду писать в основном про второй режим подключения.

Похоже, что в дистрибутивном ядре Debian (2.6.24-1-686) нужные драйвера garmin-gps уже включены, потому что сразу после подключения устройства dmesg выдаёт следующее:
usb 4-1: new full speed USB device using uhci_hcd and address 9
usb 4-1: configuration #1 chosen from 1 choice
garmin_gps 4-1:1.0: Garmin GPS usb/tty converter detected
usb 4-1: Garmin GPS usb/tty converter now attached to ttyUSB0

Из чего следует, что устройство подключается как /dev/ttyUSB0.

Передача точек маршрута (Waypoints) и треков (Tracks)

Вначале пробую программу gpsman. Интерфейс не сверхудобный, куча не связанных между собой окошек, между которыми приходится переключаться, кнопки, которые распахиваются в меню, но зато всё это дело работает! :)

Настройки потребовались минимальные: в главном окошке в диалоге Options указать GPS Model «Garmin» и Serial port «/dev/ttyUSB0». Всё, после этого в окошке GPS Reciever
— там, где написано offline нажимаем и выбираем check — надпись сменится на зелёную online, а кнопки внизу станут активные. Именно эти кнопки и надо использовать чтобы скачивать с устройства (Get) или загружать на устройство (Put) разные типы объектов.

Я пробовал скачивать точки маршрута и записанный трек (кнопки WPoint и Track соответственно). После их нажатия программа получает с устройства список имеющихся в нём объектов, и уже в другом окошке можно выбрать нужный и сохранить/экспортировать. Треки можно сразу экспортировать в формате GPX. Ещё треки можно просматривать и редактировать на «карте» в gpsman. Слово «карта» написал в кавычках — потому что вначале это чистый лист, подложку с картой сделать вроде бы можно, но как — пока не разбирался.

Можно загрузить трек и точки маршрута с устройства при помощи программы gpsbabel, из коммандной строки. Если устройство подключено к /dev/ttyUSB0, а нужен трек с точками в формате GPX, то получить его можно так:
$ gpsbabel -t -w -i garmin -f /dev/ttyUSB0 -o gpx -F мойтрек.gpx
Другой способ получить эту информацию — скопировать с устройства GPX-файл в режиме USB Mass Storage, а потом уже его конверировать-преобразовывать… Этот файл с названием вида ГГГГММДД.gpx появляется на карточке памяти только если включена соответствующая функция в приборе. В него пишутся копии всех треков за день, сам прибор никак этой информацией не пользуется. gpsman же позволяет скачивать треки, находящиеся в памяти прибора. На мой взгляд, использовать gpsman проще, потому что треки и точки пути будут уже разделены и называться так же, как и на устройстве.

Лирическое отступление: Как вставить GPX-трек на Google Earth или Google Maps? Совет нашёл на Geofaq.ru (загрузка данных GPS на растровую карту). Если кратко, то трек нужно преобразовать в формат KML, а затем выложить куда-нибудь в веб, а в Google Maps указать URL этого файла. В Google Earth KML-файл можно открыть непосредственно. В случае использования свободного софта, преобразовать файл из GPX в KML может GPSBabel:
$ gpsbabel -i gpx -f 20080611.gpx -o kml -F 20080611.kml

Эта команда говорит: исходный формат GPX (-i gpx), исходные данные брать из файла 20080611.gpx (-f имяфала), конечный формат KML (-o kml), писать результат в файл 20060811.kml (-F имяфала). Всё, полученный файл можно просмотреть в Google Earth или Google Maps.

Загружать точки-треки-маршруты с компьютера на навигатор я ещё не пробовал, но в целом создалось впечатление, что работать с точками-треками-маршрутами можно без проблем.

Другие способы: у gpsman есть интерфейс коммандной строки (ещё не пробовал), есть программа gpstrans, умеющая делать примерно то же самое, тоже с интерфейсом коммандной строки (тоже ещё не пробовал).

Далее речь пойдёт о загрузке в прибор карт, прежде всего неофициальных (потому что покрытие официальных гарминовских топографических карт весьма неудовлетворительное).

Использование официальной MapSource4.0

С устройством поставляется программа MapSource4.0, необходимая для установки официльных карт, годная и для скачивания-закачивания треков, маршрутов и точек. Программа без проблем установилась под wine (версия 1.0-rc-1), даже на русском языке.

Народ на форумах подсказал, что нужно сделать вот так:
$ ln -s /dev/ttyUSB0 ~/.wine/dosdevices/com1

и после этого перезапустить MapSource. После этого программа стала находить подключенный по USB прибор и с ним работать. Проверил передачу треков и точек пути, загрузку карт на прибор. Вроде всё нормально.

Использование неофициальной QLandkarte

QLandkarte — свободная программка с неплохим интерфейсом предназначенная заменить собой несвободную MapSource, в том числе загружать на устройство карты. В данный момент мне удалось с её помощью просматривать карты в формате IMG, но вот соединяться с устройством QLandkarte никак не хочет. Выдаёт мистическую «Device link error», а в настройках прямо сказано, что имя порта для USB-устройств игнорируется… В общем, надо разбираться, копать список рассылки, потому что программа похоже стоит того.

Другие способы загружать на устройство карты

Копирование карт в режиме USB Mass Storage. Вот здесь предлагают такой способ:
Q: I copied the IMG files onto my GPS, but don't see anything.
A: Garmin GPS's have to use the gmapsupp.img file in the Garmin folder (USB Drive Letter:\Garmin\GMAPSUPP.IMG) and there can only be one of this file. Either rename the 1 file you want to gmapsupp.img or use sendmap20 to compile all the img's you want into one gmapsupp.img file.

Попробовал, создал на карточке устройства папку. Клал туда IMG-файлы. Устройство не видит. Переименовывал тот или иной файл в GMAPSUPP.IMG. Не находит. Пробовал называть строчными буквами (хотя там же всё равно FAT?). Не помогает. То ли карты не те, то ли надо что-то с устройством вначале сделать.

Есть программка sendmap20. Бесплатная её версия для Linux не работает: точнее не находит /dev/ttyUSB0. И что с ней можно сделать — я не придумал. Зато вот на этом польском форуме написали, что если в wine связать порт com1 c /dev/ttyUSB0 (см. выше про MapSource), то под wine будет работать бесплатная Windows-версия sendmap20.

И действительно, sendmap20 без проблем работает в wine после привязки порта, карты на устройство загружаются. Также в wine хорошо работает GPSMapEdit, которым можно создавать и редактировать карты. Бинарная бесплатная версия cgpsmapper, который конвертирует файлы из «польской нотации» в формат IMG, используемый Garmin, — тоже работает. Так что уже даже удалось создать и загрузить на устройство самодельную карту. При использовании sendmap20 нужно каждый раз стирать с устройства все карты и заливать весь нужный набор заново, это особенность программы.

Резюме: подключение GPS устройства Garmin GPSmap 60Cx в Linux проблем не вызвало, передача точек пути, треков и маршрутов похоже работает нормально (как минимум, в MapSource и в gpsman), конвертировать данные в другие форматы умеет gpsbabel, карты можно загружать на устройство с помощью sendmap20 или MapSource под wine; сами карты в формате IMG в Linux можно просмотреть в QLandkarte или официальном MapSource, полный цикл подготовки карт можно выполнить при помощи бесплатного (но несвободного) ПО, но замену некоторым программам можно найти. В этом плане я связываю надежды с QGIS и GRASS, но пока ничего с их помощью не произвёл.

Ссылки по теме:

20080228

Строим графики: графический интерфейс для gnuplot

Я уже не раз писал о построении графиков и визуализации данных, в том числе и об использовании gnuplot. В этот раз я хочу показать, как можно использовать gnuplot исключительно с помощью графического интерефейса. Такой интерфейс для gnuplot предоставляется программой qgfe.



Поскольку программа с графическим интерфейсом, то проще показывать, чем рассказывать. Учебный видеоролик на флэше можно посмотреть здесь. Размер ролика 1,9 мегабайт.

P.S. Видеоролик я сделал с помощью wink. Попробовал первый раз. Оказалось, что это довольно удобная программа для записи screencast-ов в формате флэш. К сожалению, мне не удалось в ней сделать комментарии на русском языке, поэтому весь ролик прокомментировал по-английски. Прошу прощения за это маленькое неудобство.

Читайте также другие статьи по теме:
Как построить график с изолиниями в gnuplot, gri и pylab
Цветные поверхности в gnuplot в режиме pm3d
Построение одномерных графиков в gnuplot
Создание графиков в gnuplot: деления на осях
Строим научные графики с помощью gnuplot (вводная статья)
Создание простейшей карты в GMT
Сравнение программ для построения графиков

20080215

Как построить график с изолиниями в gnuplot, gri и pylab

Я уже рассказывал о том, как отобразить двумерные данные с помощью поверхностей уровня в gnuplot. Сегодня я покажу другой способ отобразить двумерные данные на графике: с помощью изолиний, подобно тому, как обозначаются высоты на картах.

Я покажу как это делается на примере сразу трёх свободных инструментов: gnuplot, gri и matplotlib (он же pylab). Именно этими тремя программами я пользуюсь чаще всего. В тексте буду давать ссылки на полный скрипт, используемый для построения графика, пояснять же буду самое основное. Все графики я буду строить в чёрнобелом варианте, сохраняя в формате EPS. Иллюстрации к этой статье получены последующей конвертацией EPS в PNG.

Итак, дано: файл с данными sampledata.txt, значения x, y, z в три колонки, массив 80×80 точек, каждый следующий «столбец» сетки (следующее значение x) отделён от предыдущего пустой строкой. Файлы такого формата использует gnuplot (для gri и для pylab потребуется преобразовать формат). Задача: построить график с изолиниями постоянного значения z.

Итак, способ первый,

строим график с изолиниями в gnuplot

Здесь всё просто. Отключаем построение поверхности, включаем построение изолиний, включаем «вид сверху», велим выбирать уровни автоматически:
unset surface
set contour
set view map
set cntrparam levels auto 10
Можно задать уровни изолиний и вручную:
set cntrparam levels discrete уровень1, уровень2, уровень3, …
Теперь команда
splot 'sampledata.txt' w l
будет строить график с изолиниями. И вот какой результат получается по-умолчанию в gnuplot:
график с изолиниями, построенный в gnuplot
(Запускал gnuplot так: $ gnuplot plotiso_gnulot.txt)


Способ второй,

строим график с изолиниями в gri

Честно говоря, я считаю, что gri справляется с изолиниями лучше, чем gnuplot. Во всяком случае, здесь, в отличие от gnuplot, значения можно надписать прямо на изолиниях, и есть реальная возможность управлять цветами изолиний при сохранении EPS (пользователей gnuplot в этом месте ждёт сюрприз). При этом gri остаётся инструментом достаточно простым для понимания.

Небольшое препятствие состоит лишь в том, что необходимо преобразовать формат данных. Gri хочет, чтобы каждая строка данных отделялась была отдельной строкой в файле, а точки были разделены пробелами. Здесь я использую такую возможность gri, как чтение данных из юниксового «пайпа», и делаю все нужные преобразования на лету с помощью awk:
open "awk ' /[^s]/ { printf($3 \" \"); } /^\s*$/ { print ; }' sampledata.txt |"
read grid data 80 80 bycolumns
close
Построение же собственно изолиний уже совсем просто:
draw contour
Вот что получает в gri:
график с изолиниями, построенный в gri
(gri я запускал так: $ gri -b -output iso_gri.eps < plotiso_gri.txt)


Способ третий,

строим изолинии в matplotlib/pylab

matplotlib — это библиотека для python. Её можно использовать как интерактивно, запуская ipython -pylab, так и внутри обычного скрипта; синтаксис команд построения графиков приближен к синтаксису matlab, но при этом можно использовать на полную возможности Python. А возможности у matplotlib весьма приличные.

Изолинии строятся одной командой:
cset=contour(X,Y,Z)
Здесь X, Y, Z — должны быть двумерными массивами одной и той же размерности. Кроме того, в скрипте я отключил раскраску изолиний по умолчанию, чтобы нарисовать все изолинии чёрным цветом (параметр colors='black'). Другие варианты использования contour можно прочитать в help contour, если запустить ipython -pylab.
Ещё одна команда добавляет к изолиниям подписи:
clabel(cset,fmt="%1.1f",fontsize=9)
Сохранить результат в файл нужного формата тоже просто:
savefig('pylab.eps')
Остальные строчки в скрипте — это преобразование формата данных средствами Python.
Дополнение: в новых версиях SciPy этот скрипт можно значительно упростить, если воспользоваться функцией loadtxt(), загружающей данные из текстового файла. То, что нам надо.
Вот что получается в итоге:
график с изолиниями, построенный в matplotlib/pylab
(скрипт я запускал так: $ python plotiso_pylab.txt)

☙ ☙ ☙

Конечно, выбор конкретного инструмента — вопрос удобства (имеющегося формата данных, требований к тонкостям настройки графики, имеющегося времени, опыта использования). Я хотел показать, что выбирать есть из чего, и построить на графике изолинии с любой из трёх рассмотренных программ — дело двух–трёх строчек. Совершенствовать же результат и настраивать тонкости отображения можно долго. На мой взгляд, в случае построения изолиний, gri и matplotlib предоставляют больше возможностей.

Хочу также заметить, что этими тремя программами список инструментов пригодных для построения графиков с изолиниями не исчерпывается. Надо отметить ещё Tioga, plotmtv, GMT, Asymptote. Есть и пакеты, ориентированные на 3D-данные, но которые можно использовать и для 2D: OpenDX, VTK, MayaVi. Вроде бы можно построить изолинии и в R (приличных примеров я не видел). Судя по документации, есть такая возможность и в scilab (но примеров того, что получается — я тоже не видел). Octave, как я понимаю, предоставляет лишь альтернативный интерфейс для gnuplot. Возможно, эту статью я в будущем дополню ещё какими-то примерами. Если кто-то активно строит графики с изолиниями в чём-то другом — предлагаю поделиться ссылкой на подобные инструкции. Ссылки буду добавлять ниже.

См. также:

Сравнение 9 программ для построения графиков
Цветные поверхности в gnuplot в режиме pm3d

20080131

Плагин для GIMP Exposure Blend вместо HDR

Не секрет, что у цифровых камер довольно ограниченный динамический диапазон, то есть разница между самым яркими и самыми тёмными градациями в кадре. Говоря цифрами, динамический диапазон закатного пейзажа вполне может достигать 20 ступеней (соотношение яркостей 220), а большинство любительских камер обладают динамическим диапазоном максимум 8 ступеней. Это значит, что на фотоснимке такого пейзажа солнце и небо будут выбеленны, а детали в тенях неразличимо чёрными.

Чтобы обойти это ограничение в последнее время часто применяется техника известная как High dynamic range imaging (HDR). Идея её состоит в том, что берутся несколько кадров одной и той же сцены с разным уровнем экспозиции. Затем по совокупности кадров вычисляется сколько света должно было падать на каждый пиксель изображения. Эта информация позволяет построить новое изображение, как если бы динамический диапазон камеры был сколь угодно широк. При этом информация о тёмных градациях изображения берётся в основном со светлых кадров, а информация о светлых градациях — с тёмных. Полученные изображения часто очень красивы и приближены к нашему естественному восприятию сцен с высоким контрастом.

В GNU/Linux есть много программ, которые позволяют обрабатывать изображения, используя технику HDR. В частности, надо упомянуть Cinepaint (HDR in Cinepaint tutorial) и Qtpfsgui (Руководство по Qtpfsgui (на английском)). Qtpfsgui, пожалуй, обладает на сегодняшний день наиболее удобным интерфейсом. А для съёмки HDR необходимо иметь камеру с поддержкой автовилки экспозиции ну и штатив.

Однако надо учитывать, что большинство любительских камер могут делать в режиме автовилки максимум 3 кадра, и шаг экспозиции между ними обычно ограничен ±2 EV, а то и всего ±1 EV (как в моей камере). Это позволяет расширить динамический диапазон соответственно на 4 или лишь 2 ступени. Хорошо, но не очень много.

В этом случае часто может быть проще и быстрее использовать плагин Exposure Blend plugin для GIMP (сайт, похоже, часто не работает, но в Debian этот плагин можно найти в пакете gimp-plugin-registry). Результат работы этого плагина не является настоящим HDR. Вместо этого с помощью масок берутся тёмные детали с яркого снимка, а светлые детали с тёмного, и объединияются в одном изображении за счёт наложения слоёв. Однако результат бывает довольно хорош. И даже честный HDR по трём кадрам с любительской камеры и шагом экспозиции ±1 EV не даст результата лучше.

В GIMPе плагин запускается из меню Расш. / Photo / Exposure Blend. Нужно указать ему три файла (нормальный, тёмный, светлый). Большинство настроек хороши по-умолчанию. В результате будет создано изображение с тремя слоями (нормальный внизу, над ним слой с тёмными деталями и слой со светлыми деталями). При желании можно поиграться с прозрачностью слоёв.

Конечно, если камера поддерживает большой шаг автовилки — это хорошо. При съёмке лучше задавать максимально возможный. Результаты будут лучше. К сожалению мой фотоаппарат умеет делать максимум ±1EV, а этого не достаточно.

Поэтому для этого примера я избрал немного иной подход. Я снял одно изображение в формате RAW (12 бит на цветовой канал), а затем обработал его в UFRaw, сделав три изображения: одно нормальное и два с коррекцией экспозиции ±2EV.

Вот что получилось (ссылки ведут на более крупные изображения, лежащие на imageshack.us, желающим могу выложить RAW или полноразмерные версии):

нормальная экспозиция + -2EV + +2EV = композитное изображение


Сравните обычный кадр с композитным изображением, полученным с помощью Exposure Blend (внизу):

вверху обычный кадр, внизу композитное изображение


В изображении, созданном Exposure Blend, детали более отчётливы, чем в исходном изображении. И в тенях (фон, шары, поверхность), и в светлых областях (воск свечи). И это сделано компактной камерой и всего несколькими кликами мыши!

Я специально не исправлял гамму и не трогал цветовых кривых. Одно из ключевых преимущества использования Exposure Blend перед использованием HDR — это сохранение естественной цветопередачи. В случае HDR задача преобразования композитного изображения с расширенным динамическим диапазоном к обычному цветовом пространству совсем не тривиальная (попробуйте повторить результат в Qtpfsgui!). При использовании Exposure Blend никакой необходимости подгонять и настраивать особенности цветопередачи нет. Изображения всегда выглядят натурально.

Можете взглянуть также на некоторые другие изображения, полученные с помощью Exposure Blend (ссылки на Flickr):

Exposure Blend example 3 Exposure Blend example 4 Exposure Blend example 5 Exposure Blend example 6 Exposure Blend example 2
и другие фото с тэгом exposureblend

P.S. Эту заметку я написал также по-английски: Try Exposure Blend plugin for GIMP to fake HDR.

P.P.S. Как отметил в комментариях nagos, в будущих версиях пакета enblend появится также утилита enfuse, позволяющая совмещать кадры с разной экспозицией (в том числе более 3); в данный момент она доступна в версии enblend для разработчиков. Можете посмотреть также заметку про создание HDR в qtpfsgui, написанную nagos.