neděle 20. prosince 2020

Skládání fotografií pro redukci šumu, prodloužení expozice, i vyprázdnění náměstí

Jak skládáním řady expozic dosáhnout technicky lepší fotografie a jak to zautomatizovat. V případech, kdy je málo světla a vy nemáte stativ, chcete-li vyfotit rušné místo bez lidí, nebo jen zvýšit dynamický rozsah snímku, nejen k tomu vám může pomoci skript pro skládání snímků, který jsem si napsal. Takové funkce jsou dnes zabudovány i v nejednom fotoaparátu, či mobilním telefonu, já vám ale samozřejmě ukážu, jak na to v Ubuntu, či jiné linuxové distribuci. Protože nemám moc času, tak to asi malinko odfláknu, ale leží mi tu základ už pomalu pět let..

   

 

Více expozicemi k nižšímu šumu

První problém, který jsem řešil, byla možnost fotit za horších světelných podmínek bez stativu s co nejnižší úrovní šumu ve výsledném obraze. Snímač mého fotoaparátu není stabilizovaný, stejně jako mé objektivy, takže musím z ruky používat poměrně krátké časy, abych snímky neměl rozmazané, což mě s ubývajícím světlem postupně nutí snižovat clonu a následně zvyšovat ISO a tudíž i šum. Jedinou možností jak se pak dostat k výrazně lepšímu obrazu, je pořízení více expozic za sebou a jejich následné složení do jedné. Šum má náhodný charakter, každý snímek šumí jinak (i když se stejnou intenzitou) a tak se průměrováním pixelů všech použitých snímků dostáváte blíže k reálné hodnotě. Čím více snímků, tím čistší bude výsledek. Jen je dobré si uvědomit, že potřeba dalších snímků roste exponenciálně, takže abyste dosáhli vylepšení odpovídající 1 EV (např. snížili šum z úrovně ISO 1600 na ISO 800), stačí vám jeden další snímek, ale abyste to posunuli o 4 EV (pro zmíněný příklad na úroveň ISO 100), budete těch snímků potřebovat 2^4, tedy 16. Samozřejmě tuto techniku využijete jen pro statické scény.

Jednou jsem omylem podržel spoušť fotoaparátu v mém mobilu a ono to udělalo asi 30 snímků, cca 20/s. Za 3 sekundy nasekáte 60 snímků, na tyto účely je to ideální. Co se dá vyrobit složením různého počtu mazanic můžete vidět na následujícím obrázku, vlevo nahoře je originál, takhle vypadalo všech 59 snímků, spodní řada je zesvětlená:



V horní řadě snímky s jasem, jak vypadly z mobilu, v dolní zesvětlené.

Sérii expozic bez stativu je třeba vzájemně srovnat

Samotné pořízení více expozic neřeší nestabilitu fotografa, i když uděláte jen dvě expozice v sériovém snímání rychlostí 7 snímků za sekundu, jako má Canon 80D, budou s největší pravděpodobností vzájemně posunuté. Když jich uděláte v řadě dvacet, můžete zjistit, že se klátíte opravdu hodně. Díky krátkému času expozice se sice nemusí projevit neostrost na jednotlivých snímcích, ale všechny budou vzájemně trochu posunuté. A tak je snímky třeba nejprve vzájemně srovnat, případně vyřadit ty, které nejsou dostatečně ostré.

GIMP, oproti Photoshopu, automaticky zarovnat snímky ve vrstvách neumí a tak jsem hledal jinde. V Universe repozitáři Ubuntu jsem našel aplikaci s názvem Hugin, jenž je určena ke skládání panoramat. Jak je v linuxových systémech zvykem, Hugin je grafická nadstavba nad utilitami pro příkazový řádek. Základem aplikace je balík hugin-tools, jenž obsahuje nástroj align_image_stack, který umí zarovnávat překrývající se části snímků a poradí si i s drobnými deformacemi vzniklými třeba změnou úhlu záběru. Výhodou je i to, že podporuje akceleraci přes grafickou kartu, takže pokud používáte kompatibilní ovladač a kartu (např. Radeon HD7750 na Galliu), celá operace se velmi výrazně zrychlí.

Instalace (v mém případě na Ubuntu 16.04 LTS a 20.04 LTS):
sudo apt-get install hugin-tools

Použití align_image_stack:
align_image_stack --gpu -m --threads=3 -a "$prefix" -C xxx1.jpg xxx2.jpg ...

Programu se tedy dá seznam snímků (mohou to být i tiffy), které má srovnat a počká se na výsledek.

Přepínače mají následující významy:

--gpu  - pokud možno, využije k urychlení operace grafickou kartu, při běhu se zobrazí prázdné černé okénko.

-m     - podle prvního snímku optimalizuje pole záběru všech ostatních. To je v našem případě užitečné, když fotíte na krátkou vzdálenost a než nafotíte sekvenci, pohybujete se drobně i směrem k fotografované scéně a naopak. Ve výsledku máte na každém snímku jinak velké objekty a to je třeba srovnat. Jinak se to hodí i ze stativu, když skládáte snímky kvůli hloubce ostrosti, protože většina objektivů při přeostření drobně změní ohnisko a tím i úhlel záběru. Tento nástroj ale může mít problémy, pokud je na porovnávaných snímcích extrémní množství šumu.

-a     - prefix, tedy řetězec, kterým bude začínat jméno každého ze zarovnaných snímků, následovaný indexem ve formátu _xxxx.tif

Skládat se dá různými způsoby

Metod pro skládání snímků je mnoho, ale těmi nejzajímavějšími jsou statistické metody průměr a medián. Průměr je jasný asi každému, vezme se stejný pixel z každého snímku, hodnoty se sečtou a vydělí jejich počtem (pro každý z RGB kanálů zvlášť).

Medián zná mnoho lidí z televize, když se mluví o průměrných platech. Od klasického průměru se liší tím, že se hodnoty nesčítají, ale seřadí podle velikosti a hledaná hodnota je ta uprostřed řady. Výhodou je fakt, že pokud se do dat připlete zanedbatelné procento extrémně vychýlených hodnot, nemají na výsledek viditelný vliv, protože většina hodnot kolísá výrazně méně. Například když vám při snímání série snímků někdo projde před objektivem a objeví se sice třeba na polovině snímků, ale pokaždé v jiné části, po složení přes medián úplně zmizí. Zkrátka průměr hodnot 1,2,3,4,5,6,399 je 60, zatímco medián je 4.


Nevýhodou mediánu je větší výpočetní náročnost a tudíž trvá zpracování snímků výrazně déle, než klasický průměr - na mém C2D systému je to skoro čtyřnásobek času. Také je medián oproti průměru méně efektivní v eliminaci barevného šumu, takže je lepší mu předhazovat snímky už lehce odšuměné (jen barevně, ne jasově), na druhou stranu zase mívá lepší ostrost a kontrast, jelikož je metoda z výše zmíněného důvodu více rezistentní vůči náhodným nepřesnostem při rovnání. Posuďte sami (zdrojové snímky byly převedeny v dávce RawTherapee bez jakéhokoli odšumování, či doostřování, výstupní snímky jsou netknuté):


GIMP, narozdíl od Photoshopu, nemá ve výbavě mocné nástroje pro skládání snímků, ale v linuxovém světě máme pro manipulaci s obrazem mocný soubor nástrojů zvaný Imagemagick, který je dostupný z mocného příkazového řádku. Konkrétně utilita convert, umí od převodu pdf souborů do jpg, po vkládání textu do obrazu. A samozřejmě umí i složit libovolné množství obrázků přes průměr, i medián.

Instalace:
sudo apt-get install imagemagick

Příklad použití:
convert -quality 96 [seznam souborů] -evaluate-sequence [mean|median] [výstupní soubor]


Přepínač -quality určuje kompresní poměr výstupního jpegu, v příkladu 96%, tedy vysoká kvalita, seznam souborů obsahuje snímky, které chcete spojit, -evaluate-sequence v našem případě určuje, zda bude pro složení použita metoda průměru (mean), nebo mediánu a výstupní soubor, kam se výsledek uloží.

V Ubuntu 16.04 jsem neměl při použití convert žádné problémy, ale na 20.04 jsem narazil na to, že výchozí nastavení limitů paměti a disku nebyly dostatečně dimenzované na skládání většího množství snímků s vysokým rozlišením. Nastavení limitů můžete zkontrolovat takto, toto je výchozí nastavení:

$ convert -list resource
Resource limits:
  Width: 16KP
  Height: 16KP
  List length: 18.446744EP
  Area: 128MP
  Memory: 256MiB
  Map: 512MiB
  Disk: 1GiB
  File: 768
  Thread: 4
  Throttle: 0
  Time: unlimited

Limity si můžete zvýšit buď přímo v příkazu convert přidáním argumentu -limit a typu limitu (viz manuál), nebo editací souboru:

/etc/ImageMagick-6/policy.xml

Já jsem si nastavil Memory z 256MiB na 2GiB a zatím jsem neměl problém.

Skládání jako rozšíření pro správce souborů

Napsal jsem si tedy skript pro Nautila, správce souborů v Ubuntu, který mohu spouštět výběrem z kontextového menu po označení obrázků, které chci poskládat. Stačí nainstalovat

$ sudo apt install imagemagick hugin-tools exiftool

skript (viz dále) uložit do adresáře

~/.local/share/nautilus/scripts/

nazvat ho tak, jak chcete, aby se položka zobrazovala v menu, nastavit spustitelný příznak (chmod +x soubor) a pak už jen vybrat v nautilovi soubory pro skložení a z menu na pravém tlačítku myši vybrat Skripty > (v mém případě) Stack-images-mean.

#!/bin/bash
# align selected images and stack them to one by mean or median method
# apt-get install imagemagick hugin-tools exiftool

fname=${1%.*} # name of the first image without extension
prefix="aligned-"
quality=96 # output jpeg compression ratio
# possible to be called from script providing "method" variable
[[ "$method" ]] || method=mean # replace "mean" by "median" to use median method for stacking
            # median is much slower, little less effective in noise reduction
            # but able to eliminate random artefacacts like moving objects
output="$fname-STACKED-$method.jpg" # name of output file

(time  {
    echo "Trying to align selected images..."
    if ! nice align_image_stack --gpu -a "$prefix" -C "$@" 2>&1
    #f ! nice align_image_stack --gpu -m -a "$prefix" -C "$@" 2>&1 1 # gpu acceleration if available, -m for perspective correction (problem when too much noise)
        then echo -e "\n\nFailed to align images, result may be blured.\n"
        not_aligned=1
        images=$@
    echo "$images"
    else images="$prefix*"
    fi

    
    echo -e "\nStacking with $method method..."

    nice convert -verbose -quality $quality $images -evaluate-sequence $method "$output" 2>&1 &&  echo -e "\nCreated stacked image file:\n" `pwd`"/$output" || exit 1

    if [[ ! "$not_aligned" ]]
        then echo -e "\nCleaning..."
             rm -v "$prefix"* 2>&1
    fi
    echo -e "\nCopying EXIF metadata to output..."

    exiftool -tagsFromFile "$1" "$output" -overwrite_original 2>&1

    echo -e "\nComplete!"
    echo -e "\nOutput image file:"
    echo    `pwd`"/$output"
    echo -en "\nProcessing time:"

} ) 2>&1 | zenity --text-info --title "Stack Images - $method" || exit 1

exit 0

Skript jako argumenty bere seznam souborů, které má složit, ty mu dodá Nautilus, ale můžete ho spustit i samostatně. Při práci zobrazuje přes Zenity okno, ve kterém můžete sledovat co se děje a všechny výstupy z příkazů, včetně těch chybových. Tlačítkem Cancel celý skript ukončíte. Lícování a skládání snímků je výpočetně náročné, proto tyto nástroje spouštím s nižší prioritou, aby v případě potřeby neblokovaly celý výkon CPU.

Základní metodou pro skládání je mean, tedy průměr ale pokud mu předem nastavíte proměnou method na median, použije se tato. Proto mám nezi skripty ještě jeden pro spouštění median metody, ten vypadá následovně:

#!/bin/bash
method=median
. ~/.local/share/nautilus/scripts/Stack-selected-images-Mean

Ještě jsem se zapomněl zmínit o programu exiftool pro manipulaci s metadaty fotografií. Při složení snímků se totiž exif ztratí, proto jej zkopíruji z prvního snímku série do výsledné složeniny.

2 komentáře:

  1. Týjo, ani jsem nečekal, že někdy z tohohle RSS kanálu ještě někdy dostanu nějakou novinku a ona rovnou takováhle užitečná věc. To hned při nejbližší příležitosti zkusím taky, on i můj prastarý iPhone 5s rád při delším namáčknutí plní titěrnou interní paměť sekvencema, tak alespoň k něčemu budou. Dík!

    OdpovědětVymazat
    Odpovědi
    1. Ahoj, kdybych věděl, že tě to zajímá, dopsal bych to dřív ;)

      Vymazat

Zkuste prosím při komentováni používat místo volby Anonymní volbu Název/adresa URL, kde vyplníte nějakou přezdívku, adresu zadávat nemusíte. Vědět, které příspěvky jsou od jednoho člověka, je fajn. Díky.

Pokud by se vám náhodou odeslaný komentář na stránce nezobrazil, vytáhnu ho z koše hned jak si toho všimnu. I Google spam filter se občas sekne.