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

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

Чтобы очистить свои фотографии, я использовал The Gimp, чтобы создать маску мест наихудших кусочков пыли:

самые пыльные места

затем использовал gmic, чтобы удалить их из командной строки:

gmic 08-34-51.jpg ../../../dustmask_20180606_sky_flat_neg.png +inpaint_patchmatch[0] [1],10,7,4,2,1,0 -o[2] 08-34-51-clean.jpg

Хотя это не оптимальное решение, поскольку оно по существу перерисовывает эти области с нуля (без использования фоновой информации), оно обеспечивает удовлетворительные результаты на голубом небе. Я подумал, что таким образом я смогу автоматизировать процесс над сотнями затронутых изображений. К сожалению, пыль не является стационарной , поэтому это не работает. Он смещается примерно на 20 пикселей, что соответствует примерно 80 мкм. Я не знаю, связано ли это с физическим перемещением пыли, или это может быть связано с обработкой изображения в камере, такой как стабилизация изображения или коррекция объектива. Я сделал несколько изображений как в необработанном виде, так и в формате JPEG, и на этих изображениях я визуально вижу небольшое изменение формы изображения.

Это очень тонко, но если вы сравните следующие два изображения, самая большая и самая заметная часть пыли переместилась из центра пикселя (1677, 619)в центр пикселя (1655, 603). С другой стороны, менее заметный пиксель справа переместился с (4919, 1485)на (4940, 1483). Возможно, вас не должно слишком удивлять, что частицы пыли могут перемещаться и перемещаются относительно сенсора?

Изображение 1 с пылью в небе

Изображение 2 с пылью в небе

Фотографии сделаны с разницей примерно в 90 минут. Изображения, которые я разместил, уменьшены в 2 раза.

Данные EXIF ​​включают данные Sony Makernote, которые могут включать информацию о стабилизации изображения, например файлы ImageStabilization = 1. Я не знаю, включает ли он дополнительную информацию о стабилизации изображения. Он включает в себя поле Sony_0x201f = 128 17 2 0, которое, по-видимому, различается между изображениями, но идентично для двух изображений, показанных выше, поэтому оно (уникально) не идентифицирует информацию для корректировки стабилизации изображения. Я не знаю, подходит ли какое-либо другое поле. Полные данные exif (как сообщает exiftool -v) для одного изображения показывают:

  ExifToolVersion = 10.10
  ИмяФайла = 08-35-11.jpg
  Каталог = .
  Размер файла = 9440161
  FileModifyDate = 1528067625
  FileAccessDate = 1529519016
  FileInodeChangeDate = 1528150970
  Разрешения на файл = 33204
  Тип файла = JPEG
  FileTypeExtension = JPG
  MIMEType = изображение/jpeg
JPEG APP1 (44908 байт):
  ExifByteOrder = II
  + [Каталог IFD0 с 13 записями]
  | 0) ProcessingSoftware = digiKam-5.6.0
  | 1) Описание изображения =                                
  | 2) Марка = СОНИ
  | 3) Модель = ILCE-6000
  | 4) Ориентация = 1
  | 5) XРазрешение = 350 (350/1)
  | 6) Разрешение Y = 350 (350/1)
  | 7) ResolutionUnit = 2
  | 8) Программное обеспечение = ILCE-6000 v3.20
  | 9) Дата изменения = 2018:05:11 08:35:11
  | 10) YCbCrPositioning = 2
  | 11) ExifOffset (Подкаталог) -->
  | + [Каталог ExifIFD с 38 записями]
  | | 0) Время экспозиции = 0,003125 (1/320)
  | | 1) FЧисло = 11 (110/10)
  | | 2) Программа экспозиции = 3
  | | 3) ИСО = 100
  | | 4) Тип чувствительности = 2
  | | 5) Рекомендуемый индекс экспозиции = 100
  | | 6) ExifVersion = 0230
  | | 7) DateTimeOriginal = 2018:05:11 08:35:11
  | | 8) Дата создания = 2018:05:11 08:35:11
  | | 9) Конфигурация компонентов = 1 2 3 0
  | | 10) CompressedBitsPerPixel = 3 (3/1)
  | | 11) Значение яркости = 10,76328125 (27554/2560)
  | | 12) Компенсация экспозиции = 0 (0/10)
  | | 13) MaxApertureValue = 3,6171875 (926/256)
  | | 14) Режим измерения = 5
  | | 15) Источник света = 0
  | | 16) Вспышка = 16
  | | 17) Фокусная длина = 18 (180/10)
  | | 18) MakerNoteSony (Подкаталог) -->
  | | + [Каталог MakerNotes с 94 записями]
  | | | 0) Sony_0x1003 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  | | | 1) Сони_0х2000 = 0
  | | | 2) Изображение для предварительного просмотра =
  | | | 3) Рейтинг = 0
  | | | 4) Sony_0x2003 =
  | | | 5) Контрастность = 0
  | | | 6) Насыщенность = 0
  | | | 7) Резкость = 0
  | | | 8) Яркость = 0
  | | | 9) LongExposureNoiseReduction = 1
  | | | 10) HighISONoiseReduction = 2
  | | | 11) HDR = 0 0
  | | | 12) Sony_0x200c = 0 0 0
  | | | 13) Sony_0x200d = 1 (10/10)
  | | | 14) WBShiftAB_GM = 0 0
  | | | 15) ShotInfo (подкаталог) -->
  | | | + [Каталог BinaryData, 390 байт]
  | | | | FaceInfoOffset = 94
  | | | | SonyDateTime = 2018:05:11 08:35:11
  | | | | SonyImageHeight = 4000
  | | | | SonyImageWidth = 6000
  | | | | Обнаружены лица = 0
  | | | | FaceInfoLength = 37
  | | | | Метаверсия = DC7303320222000
  | | | 16) Креативный стиль = Стандартный
  | | | 17) Цветовая температура = 0
  | | | 18) Фильтр компенсации цвета = 0
  | | | 19) Режим сцены = 0
  | | | 20) Соответствие Зоны = 0
  | | | 21) Оптимизатор динамического диапазона = 3
  | | | 22) Стабилизация изображения = 1
  | | | 23) ColorMode = 0
  | | | 24) FullImageSize = 4000 6000
  | | | 25) PreviewImageSize = 1080 1616
  | | | 26) Формат файла = 3 3 1 0
  | | | 27) Качество = 2
  | | | 28) FlashExposureComp = 0 (0/10)
  | | | 29) WhiteBalanceFineTune = 0
  | | | 30) Баланс белого = 0
  | | | 31) СониМоделИД = 312
  | | | 32) Телеконвертер = 0
  | | | 33) MultiFrameNoiseReduction = 0
  | | | 34) PictureEffect = 0
  | | | 35) SoftSkinEffect = 0
  | | | 36) Коррекция виньетирования = 2
  | | | 37) Боковая хроматическая аберрация = 2
  | | | 38) Установка Коррекции Искажения = 0
  | | | 39) Sony_0x2015 = 65535
  | | | 40) Тип Объектива = 65535
  | | | 41) Спец.объектива = ...5c
  | | | 42) AutoPortraitFramed = 0
  | | | 43) FlashAction = 0
  | | | 44) Сони_0x2018 = 0
  | | | 45) Сони_0x2019 = 0
  | | | 46) Сони_0х201а = 1
  | | | 47) Режим фокусировки = 2
  | | | 48) AFAreaModeSetting = 1
  | | | 49) ГибкоеSpotPosition = 0 0
  | | | 50) AFZoneSelected = 0
  | | | 51) Сони_0x201f = 128 17 2 0
  | | | 52) AFPointsUsed = 0 0 0 0 0 0 0 0 0 0
  | | | 53) Сони_0x2021 = 0
  | | | 54) FocalPlaneAFPointsUsed = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  | | | 55) Сони_0x2023 = 0
  | | | 56) Sony_0x5001 = 0 (0/1000)
  | | | 57) Сони_0x5002 = 128
  | | | 58) Режим экспозиции = 7
  | | | 59) Сони_0xb045 = 0
  | | | 60) Сони_0xb046 = 0
  | | | 61) Качество JPEG = 65535
  | | | 62) Уровень вспышки = 0
  | | | 63) Режим Релиза = 0
  | | | 64) Порядковый номер = 0
  | | | 65) Анти-Размытие = 2
  | | | 66) Sony_0xb04c = 1 (10/10)
  | | | 67) Сони_0xb04d = 0
  | | | 68) Оптимизатор динамического диапазона = 1
  | | | 69) Сони_0xb050 = 65535
  | | | 70) Сони_0xb051 = 0
  | | | 71) Интеллектуальный Авто = 0
  | | | 72) Сони_0xb053 = 0
  | | | 73) Баланс белого = 0
  | | | 74) Tag9400c (Подкаталог) -->
  | | | + [Каталог BinaryData, 556 байт]
  | | | | Релизмоде2 = 0
  | | | | ShotNumberSincePowerUp = 2
  | | | | НомерПоследовательностиИзображения = 0
  | | | | Длина последовательности = 1
  | | | | НомерПорядковогоФайла = 0
  | | | | Длина последовательности = 1
  | | | | Ориентация камеры = 1
  | | | | Качество2 = 0
  | | | | SonyImageHeight = 500
  | | | | Модельрелизеар = 14
  | | | 75) Sony_0x9401 = ..f....pW..).6Q.\.(.GG..6\6.GG..6\6..$..........^. ..3..s.[отрывок]
  | | | 76) Tag9402 (Подкаталог) -->
  | | | + [Каталог BinaryData, 400 байт]
  | | | | Температура окружающей среды = 21
  | | | | Режим фокусировки = 2
  | | | | АФАраймоде = 1
  | | | | ФокусПозиция2 = 202
  | | | 77) Tag9403 (Подкаталог) -->
  | | | + [Каталог BinaryData, 1000 байт]
  | | | 78) Tag9404b (Подкаталог) -->
  | | | + [Каталог BinaryData, 556 байт]
  | | | | LensZoomPosition = 27
  | | | 79) Tag9405b (Подкаталог) -->
  | | | + [Каталог BinaryData, 1992 байта]
  | | | | СониISO = 4096
  | | | | Базовое ISO = 4096
  | | | | StopsAboveBaseISO = 4096
  | | | | SonyExposureTime2 = 6208
  | | | | Время экспозиции = 0,003125
  | | | | SonyFNumber = 5888
  | | | | SonyMaxApertureValue = 5054
  | | | | НомерПоследовательностиИзображения = 0
  | | | | Релизмоде2 = 0
  | | | | HighISONoiseReduction = 2
  | | | | LongExposureNoiseReduction = 1
  | | | | PictureEffect2 = 0
  | | | | Программа экспозиции = 1
  | | | | Креативный стиль = 0
  | | | | Резкость = 0
  | | | | Коррекция искажения = 0
  | | | | LensFormat = 1
  | | | | крепление объектива = 2
  | | | | LensType2 = 32787
  | | | | LensZoomPosition = 27
  | | | 80) Tag9406 (Подкаталог) -->
  | | | + [Каталог BinaryData, 64 байта]
  | | | | Температура батареи = 87
  | | | | Уровень батареи = 55
  | | | 81) Sony_0x9407 = .2WW.^....AT..W..>.WSi...lw...W.............T..i.... ...Т....Вл
  | | | 82) Sony_0x9408 = i....*......\...*..}......u}..C.=..@.[.8k.&...| ......C^..pp..[отрывок]
  | | | 83) Sony_0x9409 = . ...l.(....I........`...s..........i7.@.Sp......>... .....@.........z...%...>.[snip]
  | | | 86) Tag940c (Подкаталог) -->
  | | | + [Каталог BinaryData, 64 байта]
  | | | | LensMount2 = 4
  | | | | LensType3 = 32787
  | | | | CameraE-mountVersion = 336
  | | | | LensE-mountVersion = 263
  | | | | LensFirmwareVersion = 1
  | | | 87) Sony_0x940d = ......g......z...?..u.............GO.D.....qUx... ?...эл....8[отрывок]
  | | | 88) Tag940e (Подкаталог) -->
  | | | + [Каталог BinaryData, 12288 байт]
  | | | 89) Сони_0xa100 =
  | | | 90) Tag2010g (Подкаталог) -->
  | | | + [Каталог BinaryData, 6556 байт]
  | | | | Релизмоде2 = 0
  | | | | Оптимизатор динамического диапазона = 1
  | | | | Релизмоде3 = 0
  | | | | Релизмоде2 = 0
  | | | | Режим вспышки = 1
  | | | | StopsAboveBaseISO = 4096
  | | | | Значение яркости = 17245
  | | | | Оптимизатор динамического диапазона = 1
  | | | | HDRSetting = 0
  | | | | Компенсация экспозиции = 0
  | | | | Профиль изображения = 0
  | | | | Профиль изображения = 0
  | | | | PictureEffect2 = 0
  | | | | Качество2 = 0
  | | | | Режим измерения = 0
  | | | | Программа экспозиции = 1
  | | | | WB_RGBLevels = 690 256 427
  | | | | Фокусная длина = 180
  | | | | МинФокалленгс = 180
  | | | | MaxFocalLength = 2000
  | | | | СониISO = 4096
  | | | | LensFormat = 1
  | | | | крепление объектива = 2
  | | | | LensType2 = 32787
  | | | 91) Sony_0x940f = liVi.$........)....@..f.........&....@...Y@)..Y@. @.........[отрезать]
  | | | 92) Tag9050 (Подкаталог) -->
  | | | + [Каталог BinaryData, 944 байта]
  | | | | FlashStatus = 64
  | | | | Количество изображений = 3836
  | | | | SonyFNumber = 5888
  | | | | Релизмоде2 = 0
  | | | | ImageCount2 = 3836
  | | | | SonyDateTime2 = ....#.
  | | | | Релизмоде2 = 0
  | | | | Внутренний серийный номер = 162 254 226 13
  | | | | крепление объектива = 2
  | | | | LensFormat = 1
  | | | | LensType2 = 32787
  | | | | ОбъективSpecFeatures = .
  | | | | ImageCount3 = 44765
  | | | 93) Sony_0x9412 = ...@.V......................................... ...............[отрывок]
  | | 19) Комментарий пользователя =
  | | 20) FlashpixVersion = 0100
  | | 21) Цветовое пространство = 1
  | | 22) ExifImageWidth = 6000
  | | 23) ExifImageHeight = 4000
  | | 24) InteropOffset (подкаталог) -->
  | | + [Каталог InteropIFD с 2 записями]
  | | | 0) ИнтеропИндекс = R98
  | | | 1) InteropVersion = 0100
  | | 25) Источник файла = 3
  | | 26) Тип сцены = 1
  | | 27) CustomRendered = 0
  | | 28) Режим экспозиции = 0
  | | 29) Баланс белого = 0
  | | 30) DigitalZoomRatio = 1 (16/16)
  | | 31) FocalLengthIn35mmFormat = 27
  | | 32) Тип захвата сцены = 0
  | | 33) Контраст = 0
  | | 34) Насыщенность = 0
  | | 35) Резкость = 0
  | | 36) LensInfo = 18 200 3,5 6,3 (180/10 2000/10 35/10 63/10)
  | | 37) Модель объектива = E 18–200 мм F3,5–6,3 OSS
  | 12) PrintIM (подкаталог) -->
  | + [Каталог PrintIM с 3 записями]
  | | PrintIMVersion = 0300
  | | 0) ПечатьIM_0x0002 = 1
  | | 1) PrintIM_0x0003 = 34
  | | 2) ПечатьIM_0x0101 = 0
  + [Каталог IFD1 с 13 записями]
  | 0) Сжатие = 6
  | 1) Описание изображения =                                
  | 2) Марка = СОНИ
  | 3) Модель = ILCE-6000
  | 4) Ориентация = 1
  | 5) XРазрешение = 72 (72/1)
  | 6) YРазрешение = 72 (72/1)
  | 7) ResolutionUnit = 2
  | 8) Программное обеспечение = ILCE-6000 v3.20
  | 9) Дата изменения = 2018:05:11 08:35:11
  | 10) Миниатюрное смещение = 38476
  | 11) Длина эскиза = 6426
  | 12) YCbCrPositioning = 2
JPEG APP1 (2825 байт):
  + [Каталог XMP, 2796 байт]
  | XMPToolkit = XMP Core 4.4.0-Exiv2
  | Программное обеспечение = digiKam-5.6.0
  | CreatorTool = digiKam-5.6.0
  | Надпись = Национальный памятник Гранд-Каньон-Парашант, вдоль Глиняной дороги.
  | Название = Национальный памятник Гранд-Каньон-Парашант, вдоль Глиняной дороги.
JPEG APP13 (126 байт):
  + [каталог Photoshop, 112 байт]
  | IPTCData (подкаталог) -->
  | + [Каталог IPTC, 99 байт]
  | | CurrentIPTCDigest = ~.g..z....3P}R..
  | | -- Запись IPTCEnvelope --
  | | Набор кодированных символов = .%G
  | | -- Запись IPTCApplication --
  | | Исходная программа = digiKam
  | | Версия программы = 5.6.0
  | | ObjectName = Национальный памятник Гранд-Каньон-Парашант, вдоль Глиняной дыры Роа.
JPEG APP2 (156 байт):
  + [Каталог MPF0 с 3 записями]
  | 0) MPFVersion = 0100
  | 1) Количество изображений = 2
  | 2) MPImageList (Подкаталог) -->
  | + [Каталог BinaryData, 16 байт]
  | | MPImageFlags = 2684354560
  | | MPImageFormat = 0
  | | MPImageType = 196608
  | | MPImageLength = 8768466
  | | MPImageStart = 0
  | | ЗависимыйImage1EntryNumber = 2
  | | ЗависимыйImage2EntryNumber = 0
  | + [Каталог BinaryData, 16 байт]
  | | MPImageFlags = 1073741824
  | | MPImageFormat = 0
  | | MPImageType = 65538
  | | MPImageLength = 664145
  | | MPImageStart = 8724632
  | | ЗависимыйImage1EntryNumber = 0
  | | ЗависимыйImage2EntryNumber = 0
JPEG DQT (130 байт):
JPEG DHT (416 байт):
JPEG SOF0 (15 байт):
  Ширина изображения = 6000
  Высота изображения = 4000
  КодированиеПроцесс = 0
  Битсперсэмпл = 8
  КолорКомпонентс = 3
SOS в формате JPEG
  Предупреждение = [незначительное] Ошибка чтения PreviewImage
  Изображение предварительного просмотра = СКАЛЯР (0x19b5ab8)

Какие инструменты существуют для автоматического цифрового удаления сенсорной пыли с большой серии фотографий? У меня есть сотни затронутых фотографий (в основном все, что снято с F/8 или меньше). Это наиболее очевидно, когда пораженная область находится в небе, поэтому решение, которое работает только для неба, является удовлетворительным. Предполагая, что пыль не перемещается слишком далеко, должна быть возможность использовать какую-то технику сопоставления для расчета новой маски для каждой фотографии, прежде чем применять ее с помощью рисования или какого-либо другого метода. Несмотря на простоту в теории, реализовать это на практике может быть довольно трудоемко — и я даже не уверен, что рисование — хорошее решение.

Если не считать ручного восстановления каждой фотографии (только на моем старом компьютере это занимает 4 минуты расчетного времени), какие инструменты существуют для восстановления всей моей серии фотографий (или, по крайней мере, тех, которые были сделаны с F / 8 или меньше с небом в затронутых областях) ?

Я работаю в Linux, и мой обычный набор инструментов состоит из digikam, darktable, gimp и Python. Камера достаточно новая Sony A6000 (беззеркальная/компактная системная камера). Некоторые фотографии сделаны с объективом Sony 18–200 мм OSS, другие — с мануальным объективом Samyang 12 мм.

О боже — еще одна работа для ОД!
@mattdm ML = машинное обучение? Я полагаю, это так!
Ага. Я думаю, пришло время создать пул ставок на то, когда этот сайт сольется с ai.stackexchange.com :)
@xiota Я отредактировал вопрос: Sony A6000; Я почти уверен, что это сенсорная пыль, потому что она накопилась за время отпуска, была видна в лупу и исчезла после профессиональной чистки сенсора. Я предполагаю, что это пыль движется относительно датчика, но я никогда раньше не слышал об IBIS. Какая-то прозрачная пластина перед датчиком, которая может сместиться на 50–100 мкм?
@xiota Я новичок align_image_stack— посмотрю, может ли это мне помочь!
Включен ли сдвиг стабилизации изображения в метаданные? возможно, вы могли бы использовать это, чтобы отменить перевод пыли. В качестве альтернативы, как насчет сценария, который просит вас найти карту, щелкая в центре самого большого пятна пыли на каждом изображении? Вам все равно придется нажимать на каждое изображение, но это будет один клик вместо сотен. Я бы тоже предложил машинное обучение, но я думаю, что это запретная тема в этих краях.
@PhotoScientist Я не знаю, включены ли подробности о стабилизации изображения. Я не верю, но я добавил к вопросу полные заголовки exif. Сценарий может быть хорошей идеей — если это действительно связано со стабилизацией изображения или какой-то коррекцией, а не с перемещением пыли вокруг, тогда сдвиг для одного может однозначно идентифицировать сдвиг для других. Я не знаю, почему машинное обучение может быть табуированной темой, но я боюсь, что могу попасть в ловушку общей проблемы и что внесение исправлений вручную требует меньше усилий.
@gerrit Я считаю, что ты прав. Кажется вероятным, что вам потребуется меньше времени, чтобы найти наиболее конкретное решение ML, чем мне потребовалось, чтобы напечатать это. Тем не менее, вам, вероятно, потребуется больше времени на его реализацию, чем на ручное редактирование каждой фотографии, и поэтому это будет иметь смысл только в том случае, если это принесет вам деньги. Я предполагаю, что именно так создаются условно-бесплатные программы. Что касается запретных тем, то я просто стараюсь уважать волю народа. Кодирование решений проблем с фотографиями обычно не очень хорошо воспринимается здесь.

Ответы (1)

Что-то подобное в настоящее время не имеет технического решения - я думаю, вам нужно сделать это вручную или дождаться решения, поддерживаемого AI/ML.

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

http://www.batchcrop.com/dust-spot-removal.php

Стоит 49$.

В итоге я сделал это вручную (с darktable), это заняло много времени, но я хорошо и подробно рассмотрел много фотографий из отпуска!