Как измерить расстояние по фотографии
Привет
Русскоязычный информационно-болтологический форум
Измерение растояний на jpeg-изображении
Измерение растояний на jpeg-изображении
Post by VI » Tue Mar 26, 2013 8:47 am
Помогите чайнику! Имеется туча изображений, на которых надо измерить расстояния между двумя точками. В поле зрения имеется метка длинной в 1 см. Надо знать расстояния между двумя парами точек на том же изображени. Для упрощения задачи картинка считается идеально плоской, хотя реально метка не всегда находится в одной плоскости с объектом.
Я знаю о существовании фотошопа, но на весь кампус он единственный, на другом конце кампуса и установлен на самый медленный компъютер. Под рукой есть программа для измерения расстояний на рентгеновских снимках, она идеально подходит, но сторонние изображения она не берёт .
Попробовал загрузить программу Fiji, но или она дурная, или я криворукий. Нормально переработать значительное количество файлов получится не очень. Проще картинки распечатать и мерять линейкой.
Есть какие-нибудь альтернативные решения или придётся переводить всё на бумагу и орудовать линейкой? Ведь люди засмеют.
Re: Измерение растояний на jpeg-изображении
Post by Snickers » Tue Mar 26, 2013 9:00 am
Use «Measure Tool» from the ToolBox.
Re: Измерение растояний на jpeg-изображении
Post by VI » Tue Mar 26, 2013 9:32 am
Use «Measure Tool» from the ToolBox.
Re: Измерение растояний на jpeg-изображении
Post by mitnlag » Tue Mar 26, 2013 10:18 am
Re: Измерение растояний на jpeg-изображении
Post by bulochka » Tue Mar 26, 2013 10:38 am
Чтобы задать шкалу, используете Analyze/Set scale. Измерить можно и расстояния, и площади, и многое другое. Да и для обработки изображений (если нет фотошопа) она годится, к тому же принимает картинки в разных форматах, включая 16-битовые и прочие извращения.
Re: Измерение растояний на jpeg-изображении
Post by VI » Tue Mar 26, 2013 11:11 am
Я пробовал ImageJ, но как-то у меня она не очень пошла. Она меряет, но результат измерения не фиксировался после клика на вторую точку измеряемого отрезка. GIMP так себя не ведёт. Результат измерения остаётся и мышей после второго клика можно безболезненно кликать и двигать.
Re: Измерение растояний на jpeg-изображении
Post by VI » Tue Mar 26, 2013 11:12 am
Re: Измерение растояний на jpeg-изображении
Post by Leonid_V » Tue Mar 26, 2013 11:32 am
Re: Измерение растояний на jpeg-изображении
Post by Leonid_V » Tue Mar 26, 2013 11:52 am
ImageJ делает это поленивее.
Дает оптическую плотность в любом ROI (region of interest)
Позволяет автоматический перевод пикселей в микроны (километры, локти, аршины итд)
Позволяет нарисовать тьму линий (тьма = много) и узнать длинну каждой в фарлонгах если такова единица измерения.
Активируем меню Analyze >> Mesure
видим виндашку Results, в ней площадь картинки и средняя температура по больнице, т.е. средняя оптическая плотность
ловкой мышкой кликаем на меню “линия“
проводим оную на изображении
жмем Ctrl-M (одновременное нажатие на клавиши Ctrl и литеру М)
в виндашке Results, в качестве бесплатного сыра появляется длинна в фарлонгах
проводим следующую линию, жмем Ctrl-M,
в виндашке появляется следующая длинна в фарлонгах
повторяем операцию требуемое количество раз
сохраняем результат, который видим в виндашечке в виде файла с циферками. Файл открываем в Excel, например.
Аналогично с плотностью, только вместо меню линия выбираем меню квадрат (ROI) или круг, или произвольная фигура.
Дисклаймер:
неограниченное поедание бесплатного сыра поднимает холестерин в крови ловкой мышки
Re: Измерение растояний на jpeg-изображении
Post by bulochka » Tue Mar 26, 2013 11:55 am
Я пробовал ImageJ, но как-то у меня она не очень пошла. Она меряет, но результат измерения не фиксировался после клика на вторую точку измеряемого отрезка. GIMP так себя не ведёт. Результат измерения остаётся и мышей после второго клика можно безболезненно кликать и двигать.
Интенсивность (или оптическая плотность) тоже меряется в этой же программе. Например, многие люди таким образом обмеряют интенсивность полос на гелях.
Насколько я понимаю, Вам нужна будет величина «Integrated Density»— The sum of the values of the pixels in the image or
selection. This is equavalent to the product of *Area* and *Mean Gray Value*. Величины, которые хотите измерить, задаются в меню Analyze/Set measurements.
Измерение расстояния до объекта и его скорости
Технологию, которую я собираюсь Вам представить, я не встречал в найденных мной методах определения расстояния до объекта на изображении. Она не является ни универсальной, ни сложной, суть её заключается в том, что видимое поле (будем считать, что мы используем видеокамеру) калибруется линейкой и затем сопоставляется координата объекта на изображении с отметкой на линейке. То есть измерение ведётся по одной линии или оси. Но нам не нужно хранить отметку на линейке для каждого пикселя, алгоритму для калибровки нужно только знать размер линейки в пикселях и в метрах, а также координату пикселя, который является фактической серединой линейки. Очевидное ограничение — работает только на плоских поверхностях.
Кроме самого метода в статье рассмотрена его реализация на языке Python с использованием библиотеки OpenCV, а также рассмотрены особенности получения изображений с вебкамер в Linux, используя video4linux2 API.
На практике нужно было измерить расстояние до автомобиля и его скорость на каком-нибудь прямом участке дороги. Я использовал длинную рулетку, растягивал её в доль дороги, по середине полотна, затем настраивал камеру так, чтобы вся рулетка как раз входила в поле зрение камеры и была выравнена с осью X изображения. Следующим шагом было положить что-нибудь яркое на середину рулетки, закрепить камеру так, чтобы она никуда не съехала, и записать координаты пикселя этой середины.
Все расчёты сводятся к одной единственной формуле:
l = L*K / ( W/x — 1 + K ), где
l – искомое расстояние до объекта, м;
L – длина «линейки», м;
W – длина «линейки» в пикселях, обычно совпадает с шириной изображения;
x – координата объекта на изображении;
K = (W — M) / M – коэффициент, отражающий наклон камеры, здесь M – координата середины «линейки».
В выводе этой формулы мне очень пригодились школьные знания тригонометрии.
График зависимости этой функции приведён на рисунке:
Чем больше наклон камеры, тем круче идёт график. В граничном случае, когда ось камеры направлена перпендикулярно плоскости «линейки» ( M = W / 2), график становится прямой линией.
Но статья была бы слишком короткой, если бы на этом и остановиться. Поэтому я решил сделать демонстрационную программу, которая бы подключалась к вебкамере компьютера и следила бы за каким-нибудь объектом, вычисляя расстояние до него и его скорость. В качестве языка программирования я выбрал Python, язык с очень большим количеством достоинств, для построения графического интерфейса был выбрал фреймворк Tkinter, идущий вместе с Python, так что его не нужно устанавливать отдельно. Для слежения за объектом хорошо подходит OpenCV, я использую версию 2.2, но в репозитории текущей версии ubuntu (10.10) имеется только версия 2.1, а у них API немного изменилось в лучшую сторону и программа под версией 2.1 не заработает. В принципе можно было бы построить всю программу на OpenCV, возложив на неё функции графического интерфейса и захвата изображения, но я хотел отделить её от основной части программы, чтобы можно было если что заменить эту библиотеку на что-нибудь другое или просто убрать, выключив слежение. Я начал перерабатывать старую программу, удаляя всё ненужное, и на моё удивление от программы осталось всего несколько строк с непосредственным расчётом расстояния и скорости, что в принципе было логично, так как в оригинале программа не использует графический интерфейс, следит за автомобилем по другому алгоритму да и вместо вебкамеры используется мегапиксельная сетевая камера с подключением по RTSP.
Что касается получения изображений с вебкамеры, то тут не всё так просто. Под Windows программа использует DirectX для подключения к камере через библиотеку VideoCapture, здесь всё достаточно просто. Но под Linux внятных статей об использовании вебкамер из Python очень мало, а те примеры что есть как правило оказываются неработоспособными из-за какой-нибудь очередной смены API. В прошлом я использовал ffmpeg для этих целей и программа была на C, но ffmpeg это немного «по воробьям из пушки», да и дополнительными зависимостями не хотелось отягощать конечную программу. Можно было воспользоваться OpenCV, которая так же использует ffmpeg, но был выбран путь написания собственной обёртки video4linux2 API для Python.
Также подразумевается, что вебкамера отдаёт изображение в YUYV формате (YUV422), от RGB он отличается тем, что цветовой информации в нём в 2 раза меньше. В YUYV два пикселя кодируются 4 байтами, а в RGB шестью, отсюда экономия в полтора раза. Y — компонента яркости, для каждого пикселя она своя. U и V — цветоразностные компоненты, которые определяют цвет пикселя, так вот каждые два пикселя используют одни и те же значения U и V. Если представить поток байт от вебкамеры в этих обозначениях, то он будет выглядеть как YUYV YUYV YUYV YUYV YUYV YUYV — это 12 пикселей. Выяснить в каком формате у Вас работает вебкамера можно с помощью VLC плеера, открываете захватывающее устройство с его помощью и затем запрашиваете информацию о кодеке, должно быть как на рисунке:
Вот так выглядит исходный код библиотеки для доступа к вебкамере:
main_v4l2.cpp
Алгоритм вполне понятен — сначала открываем устройство, имя которого задаётся вначале («/dev/video0»), а затем на каждый запрос getFrame считываем кадр с вебкамеры, конвертируем его в RGB формат и отдаём ссылку на кадр тому, кто его просил. Я предоставляю также Makefile для быстрой компиляции данной библиотеки, если вам это понадобится.
А вот так выглядит обёртка этой библиотеки для Python:
v4l2.py
Как видите абсолютно ничего сложного. Библиотека подключается с помощью модуля ctypes. В написании обёртки не было никаких проблем, за исключением строчки:
Осталось только показать исходный код основного скрипта, который формирует графический интерфейс и загружает все остальные модули.
main.py
bootsector
Ретротехника, самоделки и борьба с идиотизмом
В связи с известным событием по всему интернету развернулись бурные дискуссии, участники которых обвиняют своих оппонентов то в незнании программы средней школы, то в непонимании того очевидного факта, что в военное время косинус угла может достигать четырёх.
Не желая в эти дискуссии ввязываться, я лучше на наглядном примере покажу вам, как, имея на руках фотографию какого-либо известного объекта и немного вспомогательной информации, можно с большой точностью по совсем не сложным формулам рассчитать, на каком расстоянии этот объект находился от фотографа в момент съёмки. По возможности я постараюсь каждый шаг сопровождать иллюстрацией, расчётом или ссылкой на источник. Итак, приступим.
Как известно, простейший объектив для фотоаппарата можно сделать из одной двояковыпуклой линзы. Конечно, существуют фотоаппараты вообще без объектива (так называемые пинхол-камеры, предок которых — камера-обскура), но в данном случае они нам не слишком интересны. Для начала мы рассмотрим, как строится изображение в простейшем однолинзовом объективе, а затем я покажу, что те же методы хорошо подходят и для сложных объективов, сочетающих в себе более десятка последовательно расположенных линз.
Напомню вам схему хода лучей в тонкой линзе из школьного курса геометрической оптики:
На этой схеме d — расстояние от линзы до объекта, D — расстояние от линзы до изображения объекта (на матрице или плёнке), а f — фокусное расстояние линзы.
Формула тонкой линзы из того же курса связывает эти три расстояния:
Теперь ещё раз посмотрим на оптическую схему: h — это линейный размер объекта съёмки, а H — размер его уменьшенного изображения. Нетрудно заметить, что h = d tan α, а H = D tan α (это следует из свойств прямоугольного треугольника). Подставив эти величины в формулу тонкой линзы, увидим, что tan α сокращается, и в результате получим следующее уравнение:
«Неудобная» величина D ушла, а остальные мы знаем или можем легко вычислить. На основе этого уравнения получаем вот такую формулу расстояния до объекта:
Ну а теперь давайте проверим её на практике.
Вот фотография, которую я сделал из своего окна:
На ней запечатлён дом 1 по 3-му Дорожному проезду, что в Москве. Это 22-этажная башня серии И-700А.
Какую полезную информацию можно извлечь из данной фотографии? Напомню, для расчёта нам нужны неизвестные пока величины h, H и f. h — это реальная высота дома (в метрах). Сходу я её не нагуглил, зато выяснил вот что: высота потолков в этом доме — 2,64 м, а толщина перекрытий — 0,22 м. Наверняка при измерении высоты потолков не учитывалась толщина напольного покрытия. Точно она мне не известна, так что, немного округлив, примем высоту одного этажа равной 2,9 м. Хорошо видны 23 панели, таким образом, высота видимого участка составляет примерно 66,7 м. Запомним эту величину и приступим к анализу фотографии.
H — это размер изображения дома на матрице фотоаппарата. По фотографии мы можем подсчитать его в пикселях, но, как известно, размер пикселя — это всё равно что размер ангела: точных данных ни у кого нет. Но здесь нужно вспомнить, что конкретные физические размеры имеет матрица фотоаппарата. Лезем в поисковик и узнаём, что для камеры Nikon D90 размер матрицы составляет 2,36 × 1,58 см, а разрешение — 4288 × 2848 пикс. Наша фотография не была кадрирована или повёрнута, поэтому мы можем узнать точный линейный размер изображения дома на матрице, составив пропорцию. Но чтобы делать это не вручную, воспользуемся программой Adobe Photoshop, где есть масса полезных инструментов.
По умолчанию Photoshop, конечно, не знает, какого размера должна быть наша фотография, и указывает ей разрешение 300 пикс./дюйм, или 118,11 пикс./см:
Но мы, зная физический размер матрицы и количество пикселей по длинной стороне снимка, делаем такой расчёт: 4288 / 2,36 (размер матрицы в сантиметрах), и получаем правильное разрешение — 1817 пикс./см. Вписываем его в соответствующее окошко и, чтобы не изменились реальные размеры фотографии, а лишь были пересчитаны её длина и ширина в см, указываем в верхних полях «100 проц»:
Как видите, при этом в поле «Размер печатного оттиска» появились уже известные нам размеры матрицы: 2,36 × 1,57 см. Точнее, в спецификации было указано 1,58 см, но это несущественная погрешность.
Теперь при помощи инструмента «Линейка» измерим высоту видимого участка дома (23 панели) на фотографии (смотрите в правый верхний угол):
Получается, что высота изображения дома на матрице составляет 1,92 см, или 0,0192 м.
Осталось только выяснить фокусное расстояние, но для этого, к счастью, ничего считать не нужно: оно сразу прописывается при съёмке в метаданных фотографии (EXIF). Открываем их в фоторедакторе и видим:
Фокусное расстояние при съёмке составляло 105 мм, или 0,105 м, то есть я снимал дом с максимально возможным для этого объектива приближением.
Ну что ж, теперь у нас есть все данные для расчёта. Подставляем их в формулу
и получаем: d = (0,105(0,0192 + 66,7)) / 0,0192 = 364,9 м. Внимательный читатель наверняка заметил, сколь ничтожно мала величина H в сравнении с h, поэтому нашу формулу смело можно упростить до вида
Для любых фотографий относительно крупных объектов, сделанных с расстояния больше 10 м, она будет давать практически тот же результат.
Ну а теперь самое интересное — нужно проверить, верна ли была использованная нами формула? Ведь в начале я говорил, что мы рассматриваем упрощённую конструкцию объектива, а не реальную. Может быть, наши расчёты не имеют ничего общего с действительностью? К счастью, это легко выяснить. Заходим на Яндекс.Карты и переходим в точку с координатами 55.604364, 37.611455. Затем активируем инструмент «Линейка» и ставим на карте две точки: одну — возле окна, из которого было сделано фото, а другую — возле стены дома, на которой мы считали панели:
Получаем 365 м. Ну не красота, а? Величины совпали с точностью до 0,1 м! Конечно, такая точность в известной мере является результатом везения, потому что и при измерении размеров изображения, и при подсчёте высоты этажей, и при расстановке точек на карте я вполне мог допускать погрешности в 1–3%. Но, как бы то ни было, в конечном итоге расчётная и измеренная величины сошлись.
Скептически настроенный читатель может подумать, что я подгонял цифры, и что для другой фотографии всё будет по-другому. Что ж, у меня есть ещё одно фото того же дома, сделанное с аналогичной точки, но совсем с другим фокусным расстоянием:
Проделаем для него те же измерения и расчёты. У меня получилось, что размер изображения дома составляет 0,39 см, а фокусное расстояние — 21 мм. Подставляем эти числа в упрощённую формулу и получаем d = (0,021 × 66,7) / 0,0039 = 359,2 м. Результат немного отличается, но всё равно в рамках погрешности совпадает с измеренным по карте. Расхождение несложно объяснить: камера указывает фокусное расстояние как целое число, то есть и 20,51, и 21,49 мм она покажет как 21 мм. А это уже даёт погрешность 2,4%.
Впрочем, самых въедливых скептиков наверняка не убедил и этот пример. Ведь в обоих случаях я использовал один и тот же объектив — а что, если формула работает для него чисто по совпадению? Справедливое замечание. Чтобы проверить, так ли это, я возьму кадр, сделанный не только другим объективом, но и другим фотоаппаратом, причём не цифровым, а плёночным.
Вот фотография, которую мы будем анализировать:
Её много лет назад сделал мой отец на свой «Зенит-Е» с объективом Гелиос-44-2. Фокусное расстояние этого объектива составляет 58 мм. Определить физический размер изображения дома очень просто: у меня есть слайд, который я оцифровал с определённым разрешением, и сканер прописал его в свойствах файла. Тут даже пересчитывать ничего не нужно, достаточно воспользоваться линейкой.
Участок из тех же 23-х панелей имеет на слайде высоту 1,06 см. Подставляем значения в формулу: d = (0,058 × 66,7) / 0,0106 = 365 м. Полное совпадение!
Что ж, мы получили интересные результаты: выходит, простая формула для тонкой линзы позволяет получать весьма точные (и легко проверяемые) результаты при анализе реальных фотографий, а не «сферических коней в вакууме». Почему же так происходит, если реальный объектив представляет собой не одну линзу, а целый бутерброд из линз? Ответ на этот вопрос поможет дать статья Википедии. Для сложного объектива при расчёте вводят не одну, а две главные плоскости. Фактически, расстояния d и D, которые вы видели на схеме в самом начале этого поста, в этом случае отсчитываются от разных (хотя и не слишком удалённых друг от друга) точек. Но расстояние D, даже небольшое изменение которого могло бы существенно повлиять на результат просто в силу небольших размеров этого плеча оптической системы, нам, к счастью, знать не нужно, потому что производитель объектива уже рассчитал и нанёс на его корпус фокусное расстояние, через которое величину D, как было показано выше, легко выразить. А что касается изменения расстояния от передней главной плоскости до объекта, то какими бы толстыми ни были линзы и каким бы длинным ни был объектив (мы, конечно, говорим о реальных конструкциях, а не воображаемых объективах размером с дом), при расстоянии до объекта съёмки в несколько сотен метров, как в нашем случае, величиной в десяток-другой сантиметров можно смело пренебречь.
На основании вышеизложенного легко вывести формулу для соотношения расстояний до объектов, запечатлённых на одной и той же фотографии. Причём знать фокусное расстояние объектива и размер матрицы в этом случае уже будет не нужно, поскольку они сократятся при составлении пропорции.
Как видите, даже знаний из программы средней школы достаточно, чтобы убедиться в полной некомпетентности отдельных «экспертов». Любите математику и не давайте себя обмануть!
Как измерить расстояние в фотошопе
Photoshop — отличный инструмент для редактирования фотографий. Лучшее в Photoshop то, что вы можете использовать его для творчества с фотографиями, но вы также можете использовать его для простые модификации изображения и задачи.
Например, вы можете использовать это программное обеспечение для измерения расстояний, объектов и даже углов. В Photoshop есть специальный инструмент «Линейка», который позволяет не только измерять расстояние, но также выравнивать и улучшать изображения. Вот как использовать линейку для измерения расстояния в Photoshop.
Как измерить расстояние в фотошопе
Если вы хотите создать идеальное изображение в Photoshop, вам необходимо точно отметить расстояния на фотографии и создать или вырезать объекты рассчитанных размеров. В Photoshop есть удобный инструмент «Линейка», который позволяет это делать.
С помощью инструмента «Линейка» вы можете создавать линии измерения между любыми двумя точками изображения в любом направлении. Линии могут сказать вам размер объекта, который вы измеряете, расстояние между объектами, а также углы и точные координаты объекта на вашей фотографии. Эти линии не печатаются и служат только для того, чтобы помочь вам правильно расположить изображение или его элементы.
Как использовать линейку в Photoshop
Прежде чем вы сможете начать измерение расстояния в Photoshop, вам нужно узнать, где найти инструмент «Линейка» и как считывать атрибуты измерения.
Если вы не видите инструмент «Линейка» при открытии изображения в Photoshop, выберите «Просмотр» в меню, затем выберите «Линейки». Кроме того, вы можете использовать сочетание клавиш Ctrl + R (для Windows) или Cmd + R (для Mac), чтобы сделать то же самое. Вы увидите шкалу линейки и информационную панель вокруг вашего изображения.
По умолчанию инструмент «Линейка» отображает расстояние в пикселях, но вы можете изменить его на одно из следующих: дюймы, точки, сантиметры, миллиметры, пики и проценты. Чтобы изменить единицу измерения, щелкните линейку правой кнопкой мыши и выберите один из вариантов.
Как измерить расстояние между двумя точками
Чтобы измерить расстояние между любыми двумя точками в Photoshop, вам нужно провести измерительную линию с помощью инструмента «Линейка». Вы можете сделать это, выполнив следующие действия.
После этого на вашем изображении появится измерительная линия. Затем вы можете использовать панель «Информация», чтобы найти следующую информацию о вашем изображении или его элементах:
Помимо угла, все измерения на панели «Информация» отображаются в ранее установленных единицах измерения. Если вы не изменяли единицы измерения, по умолчанию они будут рассчитываться в пикселях. Если в вашем документе уже есть линия измерения, она будет отображаться на экране, когда вы выберете инструмент «Линейка».
Как изменить измерительную линию
Если по ошибке провести измерительную линию не в том месте, ее всегда можно отредактировать. Чтобы отредактировать линию измерения в Photoshop, выполните следующие действия.
Как измерить угол в фотошопе
Вы можете использовать инструмент «Линейка», чтобы измерить угол на вашем изображении, создав транспортир. Вам нужно будет создать две измерительные линии вместо одной, чтобы можно было определить угол между ними. Для этого выполните следующие действия.
На панели «Информация» вы найдете уже рассчитанный угол между двумя линиями. Он отмечен буквой A.
Научитесь делать больше в Photoshop
Инструмент «Линейка» в Photoshop может быть чрезвычайно полезен, если вам нужно измерить точное расстояние между объектами, узнать точный угол между линиями или получить точные координаты чего-либо на вашем изображении. Вы даже можете использовать этот инструмент для выпрямления изображения, если не хотите обрезать его в Photoshop.
Вы раньше использовали Photoshop для измерения расстояния? Вы использовали для этого инструмент «Линейка» или другой метод? Поделитесь своим опытом работы с Photoshop в разделе комментариев ниже.