Русский
Русский
English
Статистика
Реклама

Метаданные

Американский суд признал массовую слежку за гражданами незаконной с опозданием на 7 лет

07.09.2020 22:10:18 | Автор: admin


Спустя семь лет после того, как бывший сотрудник Агентства национальной безопасности США Эдвард Сноуден сообщил о массовой слежке за телефонными записями американцев, Апелляционный суд девятого округа США признал эту программу незаконной, а также признал факты публичной лжи со стороны руководителей американской разведки.

В 59-страничном постановлении суд заявил, что массовый сбор и анализ метаданных о телефонных переговорах граждан нарушает Акт о негласном наблюдении за иностранными разведками (Foreign Intelligence Surveillance Act, FISA) и вполне может быть нарушать Конституцию.

Тем временем Эдвард Сноуден вынужден семь лет скрываться в России, а американские власти до сих пор не сняли с него обвинение в шпионаже.

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


В 2013 году Сноуден передал в СМИ сверхсекретные документы о глобальных программах слежки, осуществляемых американскими и британскими разведывательными агентствами. За эти статьи издания The Guardian и The Washington Post получили Пулитцеровскую премию.

Среди всех разоблачений, возможно, самым сенсационным стали доказательства, что АНБ тайно создавало обширную базу с метаданными телефонных записей США кто, когда, где и с кем говорил по мобильному телефону.

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

Американские официальные лица настаивали, что эти четверо были осуждены в 2013 году благодаря программе массовой слежки АНБ за телефонными разговорами. Но Апелляционный суд девятого округа США постановил в среду, что эти утверждения несовместимы с содержанием секретных документов. То есть они противоречат документам и по сути тоже являются ложью.



Наблюдательные группы, включая Американский союз гражданских свобод (ACLU), который помог подать апелляцию по делу экстремистов, приветствовали вердикт судей о шпионской программе АНБ: Сегодняшнее решение является победой наших прав на неприкосновенность частной жизни, говорится в заявлении ACLU, Очевидно, что массовый сбор АНБ телефонных записей американцев нарушает Конституцию.

Программа по отслеживанию звонков началась без разрешения суда при президенте Джордже Буше-младшем после терактов 11 сентября 2001 года. Аналогичная программа была одобрена секретным судом FISA в начале 2006 года и неоднократно возобновлялась, но суд 9-го округа заявил, что эти решения были юридически ошибочными.

Апелляционный суд воздержался от того, чтобы прямо заявить о нарушении Конституции, но отверг доводы министерства юстиции о том, что сбор метаданных не является обыском, поскольку клиенты добровольно делятся такой информацией с телефонными провайдерами, в соответствии с 40-летним юридическим прецедентом.

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

Суд 9-го округа по сути одобрил постановление Нью-Йоркского суда 2-го округа от 2015 года, что массовая слежка недостаточно тесно связана с каким-либо конкретным расследованием, то есть судебное постановление в рамках конкретного расследования не может легализовать массовую обработку данных.

В России тоже действуют программы массовой слежки за населением, как у АНБ.



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

ФСБ настаивает на дешифровке TLS/SSL-трафика в режиме реального времени перед записью в хранилище. Для этого планируется развернуть российский УЦ для выдачи правильных SSL-сертификатов.

Поправки Яровой вступили в силу 1 июля 2018 года, но де-факто закон ещё не работает. В данный момент российские операторы завершают модернизацию технической инфраструктуры для массового хранения данных.
Подробнее..

Будут ли провайдеры и дальше торговать метаданными опыт США

22.07.2020 12:20:51 | Автор: admin
Рассказываем о законе, который частично возродил правила сетевого нейтралитета.


/ Unsplash / Markus Spiske

Что сказали в штате Мэн


Власти штата Мэн, США, приняли закон, обязывающий интернет-провайдеров получать явное согласие пользователей на передачу метаданных и персональных данных третьим лицам. В первую очередь речь идет об истории просмотров и геолокации. Также провайдерам запретили рекламировать услуги, не связанные с коммуникациями, и использовать данные, по определению не являющиеся ПД.

Дополнительно закон штата Мэн возродил несколько правил сетевого нейтралитета, которые действовали на территории страны до 2018 года пока их не отменила FCC. В частности, он запретил интернет-провайдерам предлагать скидки на свои услуги и другие формы вознаграждения в обмен на согласие клиента предоставить личную информацию.

Почему речь только о провайдерах


Закон штата Мэн не регулирует деятельность телекоммуникационных или ИТ-компаний. Такое положение вещей не устроило интернет-провайдеров, поэтому в июле этого года они обратились в суд. Отраслевые организации USTelecom, ACA Connects, NCTA и CTIA подали коллективный иск, в котором отметили, что постановление дискриминирует провайдеров и нарушает первую поправку к Конституции США, гарантирующую свободу слова применительно к ведению бизнеса.

Свежие материалы из нашего блога на Хабре:


Лоббисты говорят, что если Google, Apple, Facebook и брокерам данных разрешено продавать ПД клиентов без их согласия, то такая возможность должна быть и у интернет-провайдеров. Но здесь стоит отметить, что на федеральном уровне уже ведется обсуждение закона, который запретит передачу геолокации третьим лицам. Хотя его будущее пока остается неизвестным.

Кто за новое регулирование


В первую очередь в поддержку закона в штате Мэн выступили представители Фонда электронных рубежей (EFF). Они давно продвигают инициативы, ограничивающие возможности интернет-провайдеров. По их словам, такие шаги необходимы для защиты приватности пользователей.

Как сообщает Vice, около 100 млн американцев являются клиентами поставщика, который в прошлом нарушал требования net neutrality. Но перейти к другому оператору они не могут, так как их регион обслуживает всего одна организация.


/ Unsplash / Markus Spiske

В пользу нового закона также высказался судья, рассматривающий дело интернет-провайдеров. Во время предварительных слушаний он признал закон штата Мэн конституционным и заметил, что первая поправка не распространяется на рекламу (commercial speech) в полном объеме. Постановление может стать важным прецедентом, на который будут опираться другие штаты, желающие возродить у себя сетевой нейтралитет.

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

Что почитать о протоколах в нашем корпоративном блоге:

Подробнее..

Перевод Как считывать и удалять метаданные из ваших фотографий с помощью Python

12.04.2021 16:18:43 | Автор: admin

Те, кто знает Python, могут делать поистине удивительные вещи, например, создавать арт-объекты и игры и красивые карты, полнотекстовую поисковую машину и систему распознавания лиц. Применим Python и для вполне бытовых задач. Сегодня, специально к старту новых потоков курсов Python для веб-разработки и Fullstack-разработчик на Python поделимся с вами туториалом, как считывать, добавлять и удалять EXIF метаданные из фотографий с помощью Python.


Немного очевидного для тех кто не в теме метаданные в фото

Массовое распространение смартфонов (по сути, портативных, оснащённых датчиками, всегда подключённых к сети компьютеров) привело к двум важным последствиям влиянию на конфиденциальность и влиянию на безопасность, и это ещё не до конца изучено:

  1. У большого количества людей есть камера, которая обычно находится в пределах досягаемости.

  2. По умолчанию фотографии, сделанные на камеру, могут выдавать конфиденциальную информацию, и многие пользователи не подозревают об этом.

Помимо данных изображения фотографии, сделанные с помощью смартфонов и современных цифровых камер, содержат метаданные, которые являются дополнительной информацией о фотографии. Эти метаданные хранятся в формате EXIF (сокращение от EXchangeable Image File format), который является постоянно развивающимся стандартом для информации, добавляемой к цифровым изображениям и звукозаписям.

На фотографиях EXIF может включать такую информацию, как:

  • Размеры и плотность пикселей фото.

  • Марка и модель устройства, на котором был сделан снимок.

  • Масштабирование, диафрагма, вспышка и другие настройки камеры при съёмке фотографии.

  • Ориентация устройства при фотографировании.

  • Когда было сделано фото.

  • Где было сделано фото.

  • В каком направлении была обращена камера.

  • Высота, на которой был сделан снимок.

Эти метаданные полезны для сортировки, каталогизации и поиска фотографий, поэтому был определён стандарт EXIF. Однако при этом возникают проблемы с конфиденциальностью и безопасностью, которые многие пользователи не принимают во внимание.

Одним из первых предостережений об EXIF является инцидент с конфиденциальностью в 2012 году, связанный с основателем антивирусной компании Джоном Макафи. Это было захватывающее время в жизни Макафи, поскольку он уклонялся от действий правоохранительных органов, но при этом давал журналистам эксклюзивные, пользующиеся большим спросом интервью. Один журналист, которому посчастливилось взять интервью, решил похвастаться своей удачей, опубликовав фотографию Макафи, но предварительно не удалив EXIF-данные. Они и раскрыли местонахождение Макафи и привели к его аресту.

Вы, вероятно, знаете о недавних историях, когда правоохранительные органы арестовывали подозреваемых, используя фотографии, размещённые в социальных сетях, потому что подозреваемые не принимали меры предосторожности и не очищали свои данные EXIF в процессе загрузки.

Я подозреваю, что вы как разработчики, заботящиеся о безопасности, вероятно, задаёте себе следующие вопросы:

  • Как я могу программно обнаружить и прочитать EXIF-метаданные с фотографии?

  • Как я могу программно изменять, добавлять или удалять EXIF-метаданные?

Если на вашем компьютере установлен Python 3.6 или более поздней версии, вы можете узнать это, выполнив приведённые ниже инструкции. Они охватывают пару пакетов Python, которые вы можете включить в свои приложения для извлечения, добавления, изменения или удаления EXIF-данных с фотографий. Попутно вы не только будете использовать свои навыки программирования, но и поработаете детективом!

Модуль exif

Существует ряд модулей Python, которые могут получить доступ к данным EXIF в цифровых фотографиях. В этой статье мы сосредоточимся на exif. Его API настолько питонический, что кажется, будто он является частью языка, а не модулем.

Чтобы установить exif, используйте pip, введя в командной строке следующее:

pip install exif

Если при вводе этой команды выдаётся сообщение об ошибке, попробуйте вместо этого использовать команду pip3 install exif. pip3 это версия pip, менеджера пакетов Python, специально предназначенная для Python 3.

Если вы не поддерживаете какой-либо код на Python 2, но вам нужно использовать pip3 для установки пакетов Python, то вам следует подумать об обновлении Python.

Загрузка фотографий и проверка их на наличие данных EXIF

Давайте проверим exif в работе. Рассмотрим эти две фотографии, palmtree1.jpg и palmtree2.jpg:

Предположим, вам задали следующие вопросы:

  1. Были ли эти фотографии сделаны на одно устройство или на разные?

  2. Какое фото было сделано первым?

  3. Где были сделаны эти фотографии?

Чтобы ответить на эти вопросы, мы загрузим данные из этих фотографий в объекты exif-Image, а затем будем использовать эти объекты для проверки EXIF-метаданных:

from exif import Imagewith open("./images/palm tree 1.jpg", "rb") as palm_1_file:    palm_1_image = Image(palm_1_file)    with open("./images/palm tree 2.jpg", "rb") as palm_2_file:    palm_2_image = Image(palm_2_file)    images = [palm_1_image, palm_2_image]

Код открывает каждый файл только для чтения. Он считывает данные файла в двоичном формате в объект файла, который затем используется для создания экземпляра объекта exif-Image. Наконец, он помещает объекты Image в массив, чтобы мы могли перебирать их, выполняя одни и те же операции с EXIF-метаданными каждой фотографии.

Давайте выполним нашу первую операцию: убедимся, что фото действительно содержат EXIF-данные. Мы сделаем это, проверив свойство has_exif каждого объекта Image. Для каждого изображения, содержащего EXIF-данные, мы будем использовать свойство изображения exif_version, чтобы отобразить версию EXIF:

for index, image in enumerate(images):    if image.has_exif:        status = f"contains EXIF (version {image.exif_version}) information."    else:        status = "does not contain any EXIF information."    print(f"Image {index} {status}")

При запуске этот код даёт следующие результаты:

Image 0 contains EXIF (version 0220) information.Image 1 contains EXIF (version 0232) information.

Теперь мы знаем, что обе фотографии содержат информацию EXIF и используют разные версии EXIF. Скорее всего, эти фотографии были сделаны на разные камеры.

Какие метаданные EXIF доступны на каждой фотографии?

Думайте о EXIF как о структуре данных ключ-значение, подобной словарю Python. Пары ключ-значение EXIF называются тегами, и каждый тег может содержать строковое или числовое значение. В текущем стандарте EXIF (версия 2.32) есть десятки тегов, и каждый от производителей смартфонов и камер до фотографов может добавлять свои собственные теги.

Вот полный список тегов EXIF, которые вы, вероятно, найдёте на цифровых фотографиях. Кроме того, тут есть теги, не входящие в стандарт EXIF, но предоставляемые рядом устройств или программного обеспечения.

EXIF один из тех неформальных форматов, где производители сами выбирают, какие функции они будут реализовывать. Это означает, что фотографии, снятые разными камерами и смартфонами, будут иметь разные наборы тегов EXIF.

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

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

Объекты Image, предоставляемые модулем exif, представляют теги EXIF как свойства этого объекта. Это означает, что вы можете использовать встроенную функцию Python dir() для объекта Image, чтобы увидеть, какие теги EXIF у него есть.

Следующий код отображает список тегов каждого объекта Image в нашем списке изображений:

image_members = []for image in images:    image_members.append(dir(image))for index, image_member_list in enumerate(image_members):    print(f"Image {index} contains {len(image_member_list)} members:")    print(f"{image_member_list}\n")

Вы увидите следующий результат:

Image 0 contains 53 members:['_exif_ifd_pointer', '_gps_ifd_pointer', '_segments', 'aperture_value', 'brightness_value', 'color_space', 'components_configuration', 'datetime', 'datetime_digitized', 'datetime_original', 'delete', 'delete_all', 'digital_zoom_ratio', 'exif_version', 'exposure_bias_value', 'exposure_mode', 'exposure_program', 'exposure_time', 'f_number', 'flash', 'flashpix_version', 'focal_length', 'focal_length_in_35mm_film', 'get', 'get_file', 'get_thumbnail', 'gps_altitude', 'gps_altitude_ref', 'gps_datestamp', 'gps_latitude', 'gps_latitude_ref', 'gps_longitude', 'gps_longitude_ref', 'has_exif', 'light_source', 'make', 'max_aperture_value', 'metering_mode', 'model', 'orientation', 'photographic_sensitivity', 'pixel_x_dimension', 'pixel_y_dimension', 'resolution_unit', 'scene_capture_type', 'sensing_method', 'shutter_speed_value', 'subsec_time', 'subsec_time_digitized', 'subsec_time_original', 'white_balance', 'x_resolution', 'y_resolution']Image 1 contains 68 members:['<unknown EXIF tag 316>', '<unknown EXIF tag 322>', '<unknown EXIF tag 323>', '<unknown EXIF tag 42080>', '_exif_ifd_pointer', '_gps_ifd_pointer', '_segments', 'aperture_value', 'brightness_value', 'components_configuration', 'datetime', 'datetime_digitized', 'datetime_original', 'delete', 'delete_all', 'exif_version', 'exposure_bias_value', 'exposure_mode', 'exposure_program', 'exposure_time', 'f_number', 'flash', 'flashpix_version', 'focal_length', 'focal_length_in_35mm_film', 'get', 'get_file', 'get_thumbnail', 'gps_altitude', 'gps_altitude_ref', 'gps_dest_bearing', 'gps_dest_bearing_ref', 'gps_horizontal_positioning_error', 'gps_img_direction', 'gps_img_direction_ref', 'gps_latitude', 'gps_latitude_ref', 'gps_longitude', 'gps_longitude_ref', 'gps_speed', 'gps_speed_ref', 'has_exif', 'lens_make', 'lens_model', 'lens_specification', 'make', 'maker_note', 'metering_mode', 'model', 'offset_time', 'offset_time_digitized', 'offset_time_original', 'orientation', 'photographic_sensitivity', 'pixel_x_dimension', 'pixel_y_dimension', 'resolution_unit', 'scene_capture_type', 'scene_type', 'sensing_method', 'shutter_speed_value', 'software', 'subject_area', 'subsec_time_digitized', 'subsec_time_original', 'white_balance', 'x_resolution', 'y_resolution']

Как вы можете видеть, в то время как оба объекта Image имеют много общих тегов, изображение 1 содержит немного больше, чем изображение 0. Это означает, что изображение 1 имеет несколько больше тегов EXIF, чем изображение 0. Это сильный индикатор того, что изображение 0 и изображение изображение 1 было снято на разные устройства.

Вы можете использовать стандартный метод set() для определения общих элементов изображения 0 и изображения 1:

common_members = set(image_members[0]).intersection(set(image_members[1]))common_members_sorted = sorted(list(common_members))print("Image 0 and Image 1 have these members in common:")print(f"{common_members_sorted}")

Запуск этого кода даёт следующий результат:

Image 0 and Image 1 have these members in common:['_exif_ifd_pointer', '_gps_ifd_pointer', '_segments', 'aperture_value', 'brightness_value', 'components_configuration', 'datetime', 'datetime_digitized', 'datetime_original', 'delete', 'delete_all', 'exif_version', 'exposure_bias_value', 'exposure_mode', 'exposure_program', 'exposure_time', 'f_number', 'flash', 'flashpix_version', 'focal_length', 'focal_length_in_35mm_film', 'get', 'get_file', 'get_thumbnail', 'gps_altitude', 'gps_altitude_ref', 'gps_latitude', 'gps_latitude_ref', 'gps_longitude', 'gps_longitude_ref', 'has_exif', 'make', 'metering_mode', 'model', 'orientation', 'photographic_sensitivity', 'pixel_x_dimension', 'pixel_y_dimension', 'resolution_unit', 'scene_capture_type', 'sensing_method', 'shutter_speed_value', 'subsec_time_digitized', 'subsec_time_original', 'white_balance', 'x_resolution', 'y_resolution']

Если вы смотрели EXIF-теги в документации (либо список стандартных тегов EXIF, либо расширенный список), вы могли заметить, что имена тегов EXIF находятся в PascalCase, а свойства EXIF в объектах exif-Image в snake_case. Это связано с тем, что авторы модуля exif стремятся следовать руководству по стилю Python и разработали Image для преобразования имён тегов EXIF в имена свойств Python.

Члены класса Image exif, не являющиеся тегами EXIF

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


Члены класса

Описание

delete(attribute)

Удаляет из изображения тег EXIF, указанный в строковом атрибуте.

delete_all

Удаляет все теги EXIF из изображения.

get(attribute, default=None)

Возвращает значение тега EXIF, заданное строковым атрибутом. Если тег недоступен или содержит значение, он возвращает значение, указанное в аргументе ключевого слова по умолчанию.

get_file

Возвращает текущие данные изображения, отформатированные для записи в двоичный файл.

get_thumbnail

Возвращает двоичные данные для эскиза изображения.

has_exif

Логическое значение, которое возвращает True, если изображение в настоящее время содержит метаданные EXIF.

set(attribute, value)

Установить значение для тега EXIF, заданное строковым атрибутом. Если тег недоступен или содержит значение, он возвращает значение, указанное в аргументе ключевого слова по умолчанию.

В этой статье мы рассмотрим большинство из этих свойств и методов.

Получение основной информации о фотографиях

Ответим на первый вопрос об этих фотографиях. Были ли они сняты на одно устройство или на разные? У нас уже есть основания полагать, что ответ нет.

Марка и модель устройства, на котором было сделано фото.

У обоих изображений есть теги марки и модели, поэтому давайте с их помощью определим, какие устройства использовались для создания этих снимков:

for index, image in enumerate(images):    print(f"Device information - Image {index}")    print("----------------------------")    print(f"Make: {image.make}")    print(f"Model: {image.model}\n")

Вот результат кода выше:

Device information - Image 0----------------------------Make: motorolaModel: motorola one hyperDevice information - Image 1----------------------------Make: AppleModel: iPhone 12 Pro

Это подтверждает, что фотографии были сделаны на разных устройствах, и теперь мы знаем детали.

Дополнительная информация об устройствах

Давайте соберём дополнительную информацию об устройствах, которые используются для фотосъёмки, а именно об их объективах и версиях операционной системы.

Не все устройства сообщают тип линзы в своих EXIF-метаданных, поэтому мы будем использовать метод Image get(), который аналогичен методу get(), используемому в Python. Подобно методу get() в Python, метод get(), предоставляемый объектом exif Image, изящно обрабатывает случай, когда данный ключ не существует.

В приведённом ниже коде используется get(), чтобы попытаться получить доступ к версиям объектива и операционной системы, используемым при съёмке фотографий. Если определённого свойства не существует, его значение будет отображаться как Неизвестно:

for index, image in enumerate(images):    print(f"Lens and OS - Image {index}")    print("---------------------")    print(f"Lens make: {image.get('lens_make', 'Unknown')}")    print(f"Lens model: {image.get('lens_model', 'Unknown')}")    print(f"Lens specification: {image.get('lens_specification', 'Unknown')}")    print(f"OS version: {image.get('software', 'Unknown')}\n")

Вот его результат:

Lens and OS - Image 0---------------------Lens make: UnknownLens model: UnknownLens specification: UnknownOS version: UnknownLens and OS - Image 1---------------------Lens make: AppleLens model: iPhone 12 Pro back triple camera 4.2mm f/1.6Lens specification: (1.5399999618512084, 6.0, 1.6, 2.4)OS version: 14.3

Обратите внимание, что телефон, используемый для съёмки изображения 0 (Motorola One Hyper), не предоставляет свойства lens_make, lens_model, lens_specification или software. Если бы мы попытались получить к ним доступ напрямую (например, image.lens_make), результатом была бы ошибка. Метод get() позволил нам предоставить альтернативное значение для этих несуществующих свойств.

Дата и время, когда была сделана фотография

Следующий вопрос: какое фото было сделано первым?

Мы можем узнать это, просмотрев свойство datetime_original каждой фотографии, которое указывает на дату и время, когда фотография была сделана. Процессор смартфона достаточно быстр, чтобы записывать точную долю секунды, когда он делает фотографию, и это значение сохраняется в свойстве subsc_time_original.

Некоторые телефоны также записывают свойство offset_time, которое мы можем использовать для определения смещения datetime относительно UTC.

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

for index, image in enumerate(images):    print(f"Date/time taken - Image {index}")    print("-------------------------")    print(f"{image.datetime_original}.{image.subsec_time_original} {image.get('offset_time', '')}\n")

Вот результаты:

Date/time taken - Image 0-------------------------2021:01:22 15:08:46.327211 Date/time taken - Image 1-------------------------2021:01:22 15:08:59.383 -05:00

Как видно из вывода, изображение 0 было снято первым, а изображение 1 было снято через 13 секунд.

Определение места, где была сделана фотография

В этом разделе мы рассмотрим доступ к GPS-координатам в метаданных фотографии, форматирование этих координат и упрощение понимания этих координат путём их размещения на карте и преобразования их в названия страны, региона и города, где фото было сделано.

Получение GPS-координат фотографии

Формат EXIF определяет ряд тегов, начинающихся с gps, которые содержат полезную информацию о геолокации, включая широту и долготу, где была сделана фотография:

for index, image in enumerate(images):    print(f"Coordinates - Image {index}")    print("---------------------")    print(f"Latitude: {image.gps_latitude} {image.gps_latitude_ref}")    print(f"Longitude: {image.gps_longitude} {image.gps_longitude_ref}\n")

Вот результат кода выше:

Coordinates - Image 0---------------------Latitude: (28.0, 0.0, 1.56) NLongitude: (82.0, 26.0, 59.04) WCoordinates - Image 1---------------------Latitude: (28.0, 0.0, 1.54) NLongitude: (82.0, 26.0, 58.75) W

Обратите внимание, что свойства gps_latitude и gps_longitude возвращают широту и долготу в виде кортежа из трёх значений:

  1. Градусы.

  2. Минуты (1/60 градуса).

  3. Секунды (1/60 минуты или 1/3600 градуса).

Широта определяет угловое расстояние от экватора, которое может быть северным или южным. Свойство gps_latitude_ref указывает это направление, которое может быть N или S.

Долгота определяет угловое расстояние от меридиана, которое может быть восточным или западным. Свойство gps_longitude_ref указывает это направление: E или W.

Возможно, вы заметили небольшую разницу между координатами, указанными на фотографиях. Это ожидаемо: даже одно и то же устройство, расположенное в одном месте, в разное время будет сообщать немного разные координаты. Расхождение в координатах, сообщаемых телефонами, составляет порядка долей секунды, что соответствует примерно 25 футам или 7,6 метрам.

Форматирование широты и долготы

Давайте определим пару функций для форматирования информации о широте и долготе, возвращаемой Image, в стандартные форматы:

  • Градусы, минуты и секунды. В этом формате широта изображения 0 будет записана как 28.0 0.0 '1.56 "N.

  • Десятичные градусы. В этом формате широта изображения 0 будет записана как 28,000433333333334. Северные широты и восточные долготы представлены положительными значениями, в то время как южные широты и западные долготы представлены отрицательными значениями.

Вот определения этих функций, а также некоторый код, который их использует:

def format_dms_coordinates(coordinates):    return f"{coordinates[0]} {coordinates[1]}\' {coordinates[2]}\""def dms_coordinates_to_dd_coordinates(coordinates, coordinates_ref):    decimal_degrees = coordinates[0] + \                      coordinates[1] / 60 + \                      coordinates[2] / 3600        if coordinates_ref == "S" or coordinates_ref == "W":        decimal_degrees = -decimal_degrees        return decimal_degreesfor index, image in enumerate(images):    print(f"Coordinates - Image {index}")    print("---------------------")    print(f"Latitude (DMS): {format_dms_coordinates(image.gps_latitude)} {image.gps_latitude_ref}")    print(f"Longitude (DMS): {format_dms_coordinates(image.gps_longitude)} {image.gps_longitude_ref}\n")    print(f"Latitude (DD): {dms_coordinates_to_dd_coordinates(image.gps_latitude, image.gps_latitude_ref)}")    print(f"Longitude (DD): {dms_coordinates_to_dd_coordinates(image.gps_longitude, image.gps_longitude_ref)}\n")

Вот результат:

Coordinates - Image 0---------------------Latitude (DMS): 28.0 0.0' 1.56" NLongitude (DMS): 82.0 26.0' 59.04" WLatitude (DD): 28.000433333333334Longitude (DD): -82.44973333333334Coordinates - Image 1---------------------Latitude (DMS): 28.0 0.0' 1.54" NLongitude (DMS): 82.0 26.0' 58.75" WLatitude (DD): 28.000427777777777Longitude (DD): -82.44965277777779

Отображение местоположения фотографий на карте

Вы, вероятно, не знаете широту и долготу своего дома, даже если округлить до ближайшего градуса. Есть несколько простых способов преобразовать данные о местоположении EXIF во что-то более лёгкое для понимания.

Один из способов использовать встроенный в Python модуль webbrowser для открытия новой вкладки браузера для каждой фотографии, используя десятичную версию EXIF-координат каждой фотографии в качестве параметров URL-адреса Google Maps. Мы создадим служебную функцию с именем draw_map_for_location(), которая сделает следующее:

def draw_map_for_location(latitude, latitude_ref, longitude, longitude_ref):    import webbrowser        decimal_latitude = dms_coordinates_to_dd_coordinates(latitude, latitude_ref)    decimal_longitude = dms_coordinates_to_dd_coordinates(longitude, longitude_ref)    url = f"https://www.google.com/maps?q={decimal_latitude},{decimal_longitude}"    webbrowser.open_new_tab(url)for index, image in enumerate(images):    draw_map_for_location(image.gps_latitude,                           image.gps_latitude_ref,                           image.gps_longitude,                          image.gps_longitude_ref)

Когда вы запустите его, откроются две новые вкладки браузера, на каждой из которых будет отображаться карта Google, указывающая, где была сделана соответствующая фотография.

Отображение города, региона и страны, где был сделан снимок

Другой способ отобразить местоположение фотографии использовать обратное геокодирование, то есть процесс преобразования географических координат в адрес или название места. Для этого нам нужно установить два модуля Python:

  • reverse_geocoder простой автономный обратный геокодер, который использует внутренние таблицы для преобразования набора координат в набор названий городов и штатов/провинций и кодов стран. Установите его, введя pip install reverse_geocoder в командной строке.

  • pycountry утилита поиска стран, которую мы будем использовать для преобразования кодов стран в их соответствующие названия. Установите это, введя pip install pycountry в командной строке.

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

import reverse_geocoder as rgimport pycountryfor index, image in enumerate(images):    print(f"Location info - Image {index}")    print("-----------------------")    decimal_latitude = dms_coordinates_to_dd_coordinates(image.gps_latitude, image.gps_latitude_ref)    decimal_longitude = dms_coordinates_to_dd_coordinates(image.gps_longitude, image.gps_longitude_ref)    coordinates = (decimal_latitude, decimal_longitude)    location_info = rg.search(coordinates)[0]    location_info['country'] = pycountry.countries.get(alpha_2=location_info['cc'])    print(f"{location_info}\n")

В коде используется метод search() из reverse_geocoder для преобразования десятичных значений широты и долготы каждой фотографии в набор следующей информации:

  • Название города, посёлка или деревни.

  • Главный административный регион, который обычно представляет собой штат или провинцию.

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

  • Код страны.

Затем он использует метод get() из pycountry для преобразования кода страны, предоставленного reverse_geocoder, в кортеж, содержащий соответствующие общие и официальные названия стран.

Вот его результат:

Location info - Image 0-----------------------{'lat': '27.94752', 'lon': '-82.45843', 'name': 'Tampa', 'admin1': 'Florida', 'admin2': 'Hillsborough County', 'cc': 'US', 'country': Country(alpha_2='US', alpha_3='USA', name='United States', numeric='840', official_name='United States of America')}Location info - Image 1-----------------------{'lat': '27.94752', 'lon': '-82.45843', 'name': 'Tampa', 'admin1': 'Florida', 'admin2': 'Hillsborough County', 'cc': 'US', 'country': Country(alpha_2='US', alpha_3='USA', name='United States', numeric='840', official_name='United States of America')}

Другая полезная информация о датчиках

Как я уже упоминал в начале этой статьи, смартфоны снабжены датчиками. К ним относятся магнитометр, барометр и акселерометр. В сочетании с GPS эти датчики предоставляют дополнительную информацию, которая добавляется к метаданным EXIF каждой фотографии.

В каком направлении была обращена камера?

Магнитометр воспринимает магнитные поля, в том числе создаваемые Землёй. Его основная цель быть компасом телефона и определять направление, на которое он указывает. Эта информация записывается в EXIF в виде компасного курса каждый раз, когда вы делаете снимок.

Давайте определим, в каком направлении я смотрел, когда делал каждую из этих фотографий:


Мы будем использовать следующие свойства exif-Image, чтобы определить направление, в котором была направлена камера:

  • gps_img_direction: направление по компасу, то есть направление, в котором смотрела камера, когда был сделан снимок, выраженный в десятичных градусах. 0 север, 90 восток, 180 юг и 270 запад.

  • gps_img_direction_ref: контрольная точка для gps_img_direction. Это может быть либо T, что означает, что 0 относится к истинному или географическому северу, либо M, что означает, что 0 относится к магнитному северу. В большинстве случаев используется истинный север.

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

  • degrees_to_direction(): эта функция преобразует направления по компасу в основные направления (например, N, NE, NNE и т. д.);

  • format_direction_ref(): эта функция превращает значение в gps_img_direction_ref понятную для человека строку.

def degrees_to_direction(degrees):    COMPASS_DIRECTIONS = [        "N",        "NNE",        "NE",        "ENE",        "E",         "ESE",         "SE",         "SSE",        "S",         "SSW",         "SW",         "WSW",         "W",         "WNW",         "NW",         "NNW"    ]        compass_directions_count = len(COMPASS_DIRECTIONS)    compass_direction_arc = 360 / compass_directions_count    return COMPASS_DIRECTIONS[int(degrees / compass_direction_arc) % compass_directions_count]def format_direction_ref(direction_ref):    direction_ref_text = "(true or magnetic north not specified)"    if direction_ref == "T":        direction_ref_text = "True north"    elif direction_ref == "M":        direction_ref_text = "Magnetic north"    return direction_ref_text# Import imageslake_images = []for i in range(1, 5):    filename = f"lake {i}.jpg"    with open(f"./images/{filename}", "rb") as current_file:        lake_images.append(Image(current_file))# Display camera direction for each imagefor index, image in enumerate(lake_images):    print(f"Image direction - Image {index}")    print("-------------------------")    print(f"Image direction: {degrees_to_direction(image.gps_img_direction)} ({image.gps_img_direction})")    print(f"Image direction ref: {format_direction_ref(image.gps_img_direction_ref)}\n")

Когда вы запустите код, вы увидите следующий результат:

Image direction - Image 0-------------------------Image direction: ENE (78.416259765625)Image direction ref: True northImage direction - Image 1-------------------------Image direction: N (1.174224853515625)Image direction ref: True northImage direction - Image 2-------------------------Image direction: SSE (178.46739196870607)Image direction ref: True northImage direction - Image 3-------------------------Image direction: W (273.8248136315229)Image direction ref: True north

На какой высоте был сделан снимок?

В дополнение к предоставлению координат местоположения GPS также может использоваться для определения высоты. Некоторые смартфоны оснащены барометрами (которые определяют давление воздуха), которые они используют для повышения точности измерения высоты.

Давайте выясним, на каких высотах были сделаны эти фотографии:

Мы воспользуемся этими свойствами объекта Exif Image для определения высоты:

  • gps_altitude: высота в метрах;

  • gps_altitude_ref: контрольная точка для gps_altitude. Это значение равно 0, что означает, что значение в gps_altitude относится к метрам над уровнем моря, или 1, что означает, что значение в gps_altitude относится к метрам ниже уровня моря.

Следующий код отображает высоту, сообщённую телефоном в момент съёмки каждой из фотографий. Он использует одну служебную функцию, format_altitude(), которая определяет, находится ли заданная высота над или под уровнем моря:

def format_altitude(altitude, altitude_ref):    altitude_ref_text = "(above or below sea level not specified)"    if altitude_ref == 0:        altitude_ref_text = "above sea level"    elif altitude_ref == 1:        altitude_ref_text = "below sea level"    return f"{altitude} meters {altitude_ref_text}"# Import imagesaltitude_images = []for i in range(1, 3):    filename = f"altitude {i}.jpg"    with open(f"./images/{filename}", "rb") as current_file:        altitude_images.append(Image(current_file))        # Display camera altitude for each imagefor index, image in enumerate(altitude_images):    print(f"Altitude - Image {index}")    print( "------------------")    print(f"{format_altitude(image.gps_altitude, image.gps_altitude_ref)}\n")

Вот результат:

Altitude - Image 0------------------14.025835763206075 meters above sea levelAltitude - Image 1------------------359.13079847908745 meters above sea level

Я мог бы сказать вам, где я сделал эти фотографии, но вы уже знаете, как это выяснить.

Двигался ли фотограф?

Смартфоны используют комбинацию местоположений GPS с течением времени и акселерометра, чтобы определить скорость телефона и направление, в котором он движется. Некоторые телефоны предоставляют эту информацию как часть метаданных EXIF на фотографиях.

Мой Motorola One Hyper не записывает метаданные, связанные со скоростью, но мой iPhone это делает. Доступ к этим данным можно получить с помощью этих двух методов объекта exif Image:

  • gps_speed: скорость, выраженная в виде числа;

  • gps_speed_ref: единицы скорости, используемые для значения в gps_speed. Это значение может быть: K для километров в час; M для миль в час; N для морских миль в час, или узлов.

Рассмотрим следующие фото:

Вот код, который выводит записанную скорость во время съёмки каждой фотографии. Он включает функцию универсальности, format_speed_ref(), которая определяет единицы сообщаемой скорости:

def format_speed_ref(speed_ref):    speed_ref_text = "(speed units not specified)"    if speed_ref == "K":        speed_ref_text = "km/h"    elif speed_ref == "M":        speed_ref_text = "mph"    elif speed_ref == "N":        speed_ref_text = "knots"    return speed_ref_text# Import imagesspeed_images = []for i in range(1, 4):    filename = f"speed {i}.jpg"    with open(f"./images/speed {i}.jpg", "rb") as current_file:        speed_images.append(Image(current_file))    for index, image in enumerate(speed_images):    print(f"Speed - Image {index}")    print("---------------")    print(f"Speed: {image.gps_speed} {format_speed_ref(image.gps_speed_ref)}\n")

Вот результат:

Speed - Image 0---------------Speed: 0.0 km/hSpeed - Image 1---------------Speed: 20.19736291335287 km/hSpeed - Image 2---------------Speed: 5.520932607215793 km/h

Редактирование EXIF данных и их сохранение

Пока что мы ограничились простым чтением метаданных EXIF с фотографий. Следующим шагом является внесение изменений в эти данные, а затем сохранение результатов в виде нового файла фотографии.

Редактирование координат фотографии

Начнём с этой фотографии:

К настоящему времени вы должны знать, как читать координаты из EXIF и использовать эти координаты, чтобы открыть карту Google, чтобы показать местоположение, где фото снято.

Вот код, который это сделает. Он использует служебную функцию draw_map_for_location(), которую мы определили ранее:

with open(f"./images/hotel original.jpg", "rb") as hotel_file:    hotel_image = Image(hotel_file)    # Read the GPS dataprint("Original coordinates")print("--------------------")print(f"Latitude: {hotel_image.gps_latitude} {hotel_image.gps_latitude_ref}")print(f"Longitude: {hotel_image.gps_longitude} {hotel_image.gps_longitude_ref}\n")# Open a Google Map showing the location represented by these coordinatesdraw_map_for_location(hotel_image.gps_latitude,                      hotel_image.gps_latitude_ref,                      hotel_image.gps_longitude,                      hotel_image.gps_longitude_ref

Он выводит следующее:

Original coordinates--------------------Latitude: (28.0, 21.0, 58.44) NLongitude: (81.0, 33.0, 34.29) W

Кроме того, он открывает новую вкладку браузера, показывающую карту Google, которая отображает отели Swan и Dolphin, которые находятся в нескольких минутах ходьбы от Walt Disney World во Флориде.

Давайте сделаем вещи немного интереснее, изменив координаты, встроенные в данные EXIF фотографии, чтобы они сообщали, что она была сделана в Зоне 51. Если вы не слышали об этом месте, это военный объект в Неваде, в котором, как считают теоретики теории заговора, правительство США хранит тела пришельцев и космический корабль, захваченные в 1950-х годах. Его координаты: 37,0 14 '3,6 "северной широты, 115 48' 23,99" западной долготы.

Вы видели, что чтение значения тега EXIF с использованием объекта Exif Image это просто чтение значения в соответствующем свойстве. Точно так же редактирование его значения это просто вопрос присвоения нового значения этому свойству. В этом случае мы присвоим значения, определяющие координаты Зоны 51, свойствам изображения gps_latitude, gps_latitude_ref, gps_longitude и gps_longitude_ref:

# Boring. Let's change those coordinates to Area 51!hotel_image.gps_latitude = (37.0, 14, 3.6)hotel_image.gps_latitude_ref = 'N'hotel_image.gps_longitude = (115, 48, 23.99)hotel_image.gps_longitude_ref = 'W'# Read the revised GPS dataprint("Revised coordinates")print("-------------------")print(f"Latitude: {hotel_image.gps_latitude} {hotel_image.gps_latitude_ref}")print(f"Longitude: {hotel_image.gps_longitude} {hotel_image.gps_longitude_ref}\n")# Open a Google Map showing the location represented by the revised coordinatesdraw_map_for_location(hotel_image.gps_latitude,                      hotel_image.gps_latitude_ref,                      hotel_image.gps_longitude,                      hotel_image.gps_longitude_ref

Выполнение кода приведёт к следующему результату

Revised coordinates-------------------Latitude: (37.0, 14.0, 3.6) NLongitude: (115.0, 48.0, 23.99) W

... и он откроет новую вкладку с картой Google, в которой отображается Зона 51.

Заполнение неиспользуемых тегов EXIF

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

Примечание: модуль exif записывает только теги в спецификации EXIF, но не дополнительные теги, включённые поставщиками. Официальные теги в спецификации EXIF подчёркнуты.

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

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

  • ImageDescription: описание фотографии. В объектах Exif Image это отображается как свойство image_description.

  • Copyright: уведомление об авторских правах на фотографию. В объектах Exif Image это свойство copyright.

Вот код, который заполняет эти теги:

hotel_image.image_description = "The Dolphin Hotel in Orlando, viewed at sunset from the Swan Hotel"hotel_image.copyright = "Copyright 2021 (Your name here)"print(f"Description: {hotel_image.image_description}")print(f"Copyright: {hotel_image.copyright}")

Выполнение кода даёт следующий результат:

Description: The Dolphin Hotel in Orlando, viewed at sunset from the Swan HotelCopyright: Copyright 2021 (Your name here)

Сохранение фото с обновленными данными

Теперь, когда мы отредактировали данные EXIF на картинке, давайте сохраним их как новый файл с названием hotel_updated.jpg.

with open('./images/hotel updated.jpg', 'wb') as updated_hotel_file:    updated_hotel_file.write(hotel_image.get_file())

Этот код создаёт файловый объект updated_hotel_file для записи двоичных данных в файл с именем hotel_updated.jpg. Затем он использует метод Image get_file() для получения данных об изображении отеля в сериализуемой форме и записывает эти данные в файл.

Теперь у вас должен быть новый файл: hotel_updated.jpg. Загрузим его и убедимся, что изменённые и добавленные данные сохранены:

with open(f"./images/hotel updated.jpg", "rb") as hotel_file:    hotel_image = Image(hotel_file)    print("Coordinates")print("-----------")print(f"Latitude: {hotel_image.gps_latitude} {hotel_image.gps_latitude_ref}")print(f"Longitude: {hotel_image.gps_longitude} {hotel_image.gps_longitude_ref}\n")print("Other info")print("----------")print(f"Description: {hotel_image.image_description}")print(f"Copyright: {hotel_image.copyright}")# Open a Google Map showing the location represented by these coordinatesdraw_map_for_location(hotel_image.gps_latitude,                      hotel_image.gps_latitude_ref,                      hotel_image.gps_longitude,                      hotel_image.gps_longitude_ref

Код выдаст вам этот результат

Coordinates-----------Latitude: (37.0, 14.0, 3.6) NLongitude: (115.0, 48.0, 23.99) WOther info----------Description: The Dolphin Hotel in Orlando, viewed at sunset from the Swan HotelCopyright: Copyright 2021 (Your name here)

... и откроется ещё одна вкладка браузера, отображающая Зону 51 на карте.

Удаление данных EXIF и сохранение очищенной фотографии

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

Первый способ использовать метод delete(), предоставляемый объектом Exif-Image. Давайте используем его, чтобы удалить данные о широте:

hotel_image.delete('gps_latitude')hotel_image.delete('gps_latitude_ref')print("Latitude data")print("-------------")print(f"gps_latitude: {hotel_image.get('gps_latitude', 'Not found')}")print(f"gps_latitude_ref: {hotel_image.get('gps_latitude_ref', 'Not found')}")

Вот результат кода выше:

Latitude data-------------gps_latitude: Not foundgps_latitude_ref: Not found

Второй способ использовать оператор Python del, который удаляет объекты из памяти. В этом случае мы будем использовать его для удаления атрибутов hotel_image, в которых хранятся данные о долготе:

del hotel_image.gps_longitudedel hotel_image.gps_longitude_refprint("Longitude data")print("--------------")print(f"gps_longitude: {hotel_image.get('gps_longitude', 'Not found')}")print(f"gps_longitude_ref: {hotel_image.get('gps_longitude_ref', 'Not found')}")

Вот результат кода выше:

Longitude data--------------gps_longitude: Not foundgps_longitude_ref: Not found

Теперь, когда мы удалили данные о местоположении с фотографии, давайте сохраним её под новым именем, hotel_without_location_data.jpg:

with open('./images/hotel without location data.jpg', 'wb') as updated_hotel_file:    updated_hotel_file.write(hotel_image.get_file())

Наконец, если вы хотите просто удалить все данные EXIF с фотографии, вы можете использовать метод delete_all() объекта exif Image:

hotel_image.delete_all()dir(hotel_image)
['<unknown EXIF tag 322>', '<unknown EXIF tag 323>', '_segments', 'delete', 'delete_all', 'get', 'get_file', 'get_thumbnail', 'has_exif']

Опять же, как только вы использовали delete_all() для удаления всех тегов EXIF, вам нужно сохранить эти изменения. Приведённый ниже код сохраняет наше изображение со всеми удалёнными тегами как hotel_without_tags.jpg:

with open('./images/hotel without tags.jpg', 'wb') as updated_hotel_file:    updated_hotel_file.write(hotel_image.get_file())

Практические и технические соображения

Причины удаления метаданных EXIF

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

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

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

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

Причины редактирования или добавления метаданных EXIF

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

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

Метаданные EXIF особенно полезны в мобильных приложениях, которые записывают одновременные комбинации визуальной информации, информации о дате/времени и местоположении. Например, от техника может потребоваться сделать фотографии выполненных ремонтных работ до и после с указанием того, где, когда и как были выполнены эти работы.

Другие вещи, которые следует учитывать

Как мы видели в различных тегах, записанных устройствами iPhone и Android, используемыми для фотосъёмки в этой статье, разные камеры записывают разные наборы тегов EXIF. Программное обеспечение для редактирования фотографий часто записывает информацию в разные теги или добавляет свои собственные теги. Эти дополнительные метаданные часто могут указывать на то, что фотография была отредактирована.

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

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

Знание Python это полезный hard skill не только для программиста, но и для аналитика и даже маркетолога. С ним вы можете сами написать простой парсер, написать небольшое приложение под свои задачи и даже увеличить свой доход, выполняя заказы на фрилансе. Если вы хотите дополнительно прокачать себя и освоить этот язык под чутким руководством наших опытных менторов обратите внимание на курс Fullstack-разработчик на Python и Python для веб-разработки.

Узнайте, как прокачаться в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

Перевод Как предотвратить появление неверных данных в ваших идеальных конвейерах

27.01.2021 14:17:26 | Автор: admin
8 пряников-человечков с тремя драже сверху вниз на теле или тремя кусочками мармелада, нечётные и чётные соответственно. Все человечки целые и улыбаются, как смайлики, кроме второго человечка во втором ряду, у которого отломали правую ногу. Его лицо грустное

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

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



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

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

Как возникает проблема


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

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

К счастью, есть надежда. Некоторые самые дальновидные команды дата-сайентистов разработали лучшие практики, чтобы предотвращать простои данных, остановки конвейеров и неточные данные дашбордов до того, как CEO спросит: Что здесь произошло?!.

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

1. Тестируйте данные. И ещё немного тестируйте


Ноутбук MacBook Pro, на весь экран открыта среда разработки с двумя окнами кода слева и справа. Слева HTML, код справа размыт
Для большинства групп специалистов DS тестирование это первая линия защиты от неверных данных.

В 2021 году тестирование данных это необходимый минимум, который вы должны предложить клиенту, чтобы он рассмотрел ваше предложение. Точно так же, как инженеры-программисты тестируют свой код, команды дата-сайентистов должны проверять свои данные на каждом этапе конвейера путём сквозного тестирования. По сути, тестирование помогает определить, работают ли Ваши данные и код так, как предполагается.

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

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

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

2. Поймите, откуда данные происходят и как влияют на процесс


Панель отслеживания происхождения данных
Отслеживайте происхождение данных на уровне полей и таблиц это может помочь специалистам DS и аналитикам понять, какие команды используют активы данных, затронутые инцидентами с данными в восходящем направлении.

Зачастую простой данных это непреднамеренное следствие невинного изменения, далёкого от конечного потребителя, полагающегося на информационный актив, о котором ни один из членов команды DS даже не знал. Это прямой результат плохой передачи данных я назвала это проблемой Вы пользуетесь этой таблицей?!.

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

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

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

3. Метаданные должны стать приоритетом, относитесь к ним как к единому целому


Панель с деталями запроса: его метаданные и время, когда он был выполнен, в два столбца
Метаданные могут помочь разрешить инциденты с данными.

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

Однако до недавнего времени с метаданными обращались, как с пустыми ящиками посылок Amazon, которые вы хотели приспособить под что-то, но только копили их и вскоре забывали.

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

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

Будущее простоя данных


Происхождение данных таблицы web_events_tbl
Происхождение данных, которое можно проследить, позволяет группам специалистов Data Science видеть поток их данных от приёма, преобразования и тестирования до производства, включая преобразования, моделирование и другие этапы процесса.

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

Что ж, ошибки в данных неизбежны, как смерть и налоги. Но, когда метаданные в приоритете, когда происхождение данных понятно, когда данные и метаданные тестируются и наблюдаемы, негативное влияние на ваш бизнес (а это истинная стоимость простоя данных) часто можно предотвратить.

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



image



Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru