Zrekonstruuj brakujący kanał RGB

11

Spójrz na te zdjęcia scen naturalnych, z których usunięto jeden z kanałów RGB:

idylliczny las bez czerwieni

Źródło (z czerwonym): https://en.wikipedia.org/wiki/File:Altja_j%C3%B5gi_Lahemaal.jpg

brzeg Antarktydy bez zieleni

Źródło (z zielonym): https://commons.wikimedia.org/wiki/File:2007_mather-lake_hg.jpg

czerwony lis bez niebieskiego

Źródło (z niebieskim): https://commons.wikimedia.org/wiki/File:Fox_01.jpg

Nawet bez jednego z kanałów możesz prawdopodobnie dowiedzieć się, jakie kolory powinny mieć pewne rzeczy, lub przynajmniej mieć dobry pomysł, jeśli rekonstrukcja brakującego kanału jest dokładna.

Na przykład, oto pierwsze zdjęcie z czerwonym kanałem dodanym z powrotem, który jest po prostu przypadkowym szumem:

zdjęcie 1 z dodanym szumem

Ten obraz wyraźnie nie jest dokładną rekonstrukcją czerwonego kanału. Wynika to z faktu, że zdjęcia natury na ogół nie wykorzystują całego spektrum RGB, a jedynie podzbiór „naturalnie wyglądających kolorów”. Ponadto odcienie czerwieni będą podążać za pewnymi gradientami, które korelują z innymi.


Twoim zadaniem jest zbudowanie programu, który zrobi zdjęcie, z którego usunięto jeden kanał, i spróbuje jak najbardziej zbliżyć się do oryginalnego obrazu, odtwarzając to, co według niego jest brakującym kanałem.

Twój program zostanie oceniony na podstawie tego, jak ściśle brakujący kanał pasuje do kanału oryginalnego obrazu, poprzez zliczenie procentu pikseli, których wartości tego kanału mieszczą się w granicach ± ​​15 (włącznie) rzeczywistej wartości na oryginalnym obrazie (gdzie wartości zakres od 0 do 255 jak w standardowym 8-bitowym kanale kolorów).

Przypadki testowe, na których oceniany będzie Twój program, można znaleźć tutaj (plik zip 9,04 MB, 6 zdjęć). Obecnie zawiera tylko trzy przykładowe obrazy powyżej i ich oryginały, ale dodam jeszcze kilka później, aby zrobić pełny pakiet, gdy już je zrobię.

Każde zdjęcie jest zmniejszane i przycinane do 1024 x 768, dzięki czemu będzie miało taką samą wagę w wyniku. Wygrywa program, który potrafi przewidzieć najwięcej pikseli w ramach danej tolerancji.

Joe Z.
źródło
1
Czy mógłbyś napisać program oceniania, np. W Pythonie?
lub
Dojdę do tego jutro. Teraz muszę iść spać.
Joe Z.
Czy istnieje limit czasu działania programu?
Lause
@Lause Ograniczeniem jest twoja cierpliwość, aby program faktycznie generował dane wyjściowe.
Joe Z.

Odpowiedzi:

17

Python 3 + obraz scikit

Po prostu ustawia kolor brakującego kanału na średnią pozostałych dwóch.

import sys
from skimage import io, color

im = io.imread(sys.argv[1])
h, w, c = im.shape

removed_channel_options = {0, 1, 2}
for y in range(h):
    for x in range(w):
        if len(removed_channel_options) == 1: break
        removed_channel_options -= {i for i, c in enumerate(im[y][x]) if c > 0}
removed_channel = removed_channel_options.pop()

for y in range(h):
    for x in range(w):
        p = [float(c) / 255 for c in im[y][x][:3]]
        p = [sum(p)/2 if i == removed_channel else p[i]
             for i in range(3)]
        im[y][x] = [int(c*255) for c in p] + [255]*(c == 4)

io.imsave(sys.argv[2], im)

I przywrócone obrazy:

las lis lodowaty

orlp
źródło
3
średnia z pozostałych dwóch - najwyraźniej dużo dokładniejsza (subiektywnie) niż się spodziewałam. +1.
Cyfrowa trauma
2
Przypominają dawno zabarwione ręcznie dagerotypy. Bardzo dobrze. +1
6

Lua, Love2D

Ustawia tylko brakujący kanał na mniejszy z dwóch pozostałych kanałów.

local inp = love.image.newImageData(arg[2])

local channels = {1, 2, 3}
local removed = nil
local removed_options = {true,true,true}

inp:mapPixel(function(x,y,r,g,b)
    local o = {r,g,b}
    for k,v in pairs(o) do
        if v > 0 then
            removed_options[k] = false
        end
    end
    return r,g,b
end)

for k,v in pairs(removed_options) do
    if v then
        removed = k
        break
    end
end
inp:mapPixel(function(x,y,r,g,b)
    local o = {r,g,b}
    o[removed] = math.min(o[removed%3+1], o[(removed+1)%3 + 1])
    return unpack(o)
end)

inp:encode('png', IMAGE:gsub("%.png", "2.png"))

Bierze nazwę pliku jako argument w wierszu poleceń.

Las Lis Śnieg

Premia

Próbowałem ustawić brakujący kanał na 255- (a + b), ustalając wartość. Co do „uzupełnienia luki”. Wyniki są bezużyteczne, ale chwalebne.

Forrest Red Teal Lis Żółty Niebieski Snow Purple Green

I z 255- (a + b) / 2

Forest Red Cyan Nudne Lis Żółto-niebieski nudny Snow Purple Green Nudne

ATaco
źródło
Obrazy wyglądają jeszcze bardziej realistycznie niż inna odpowiedź. Dobra robota! Z ciekawości, co się stanie, jeśli zamiast tego wykonasz 255- (a + b) / 2 (bez potrzeby zaciskania)?
ETHprodukcje
Wyniki są mniej nasyconą wersją tych opublikowanych powyżej. Dodam je do odpowiedzi na chichoty.
ATaco
W rzeczywistości chichotałem. Dziękuję Ci.
Gabriel Benamy