Filtr odwrotny Bayera obrazu

9

Prawie wszystkie czujniki aparatu cyfrowego są zorganizowane w siatkę fotoczujników. Każdy czujnik fotograficzny jest wrażliwy na jeden z podstawowych kolorów : czerwony, zielony i niebieski. Sposób, w jaki te fotoczujniki są zorganizowane, nazywa się filtrem Bayera , od jego wynalazcy, Bryce Bayer z Eastman Kodak. Po zrobieniu zdjęcia cztery czujniki fotograficzne składają wartość RGB jednego piksela na otrzymanym obrazie. Twoim zadaniem jest odwrócenie tego procesu i pokolorowanie powstałych pikseli zgodnie z ich kolorem filtra. Dla uproszczenia zignorujemy korekcję gamma .

Na przykład: „normalne” kroki filtrowania Bayera do przodu to:

  • czujnik światła z kolorem wosku pszczelego Pantone uderza w czujnik;
  • filtr BGGR (niebieski - zielony / zielony - czerwony) rozkłada to na cztery promienie.
  • Cztery promienie uderzają w czujnik, który brzmi: 81 - 168/168 - 235 (wartości czujnika w zakresie od 0 - 255);
  • Filtr Bayera tłumaczy to na jeden piksel RGB z kolorem (235, 168, 81).

Odwrotne kroki filtra Bayera to:

  • Piksel RGB z kolorem (235, 168, 81) jest dzielony na cztery piksele o wartościach RGB: (0,0,81) - (0,168,0) / (0,168,0) - (235,0,0).

Wyzwanie

Powinieneś napisać możliwie najkrótszą funkcję lub program, który wykonuje następujące czynności:

  • Weź nazwę pliku jak na wejściu i wyślij obraz DeBayered.
  • Dane wyjściowe można zapisać do pliku lub wyświetlić na ekranie.
  • Dane wyjściowe muszą być dwukrotnie szersze i dwukrotnie wyższe niż oryginalny obraz.
  • Każdy piksel obrazu wejściowego musi być odwzorowany zgodnie z wzorcem filtra Bayera BGGR (niebieski - zielony / zielony - czerwony), jak wyjaśniono graficznie na poniższym obrazie:

    Filtr Bayera - BGGR - objaśnienie graficzne

  • Zakładamy, że oba zielone fotosensory odbierają ten sam sygnał, więc obie wartości G w macierzy Bayera są równe wartości G na obrazie RGB.

  • Być może nie zwrócić reprezentację tablicy obrazu wynikowego. Dane wyjściowe muszą być obrazem lub plikiem (w dowolnym odpowiednim formacie obrazu ), który może być wyświetlany jako obraz.

Przykład

Biorąc pod uwagę ten plik jako dane wejściowe:

Mona Lisa

Powstały obraz powinien być:

DeBayered Mona Lisa

Referencyjna implementacja python:

from PIL import Image
import numpy
import sys

if len(sys.argv) == 1:
    print "Usage: python DeByer.py <<image_filename>>"
    sys.exit()

# Open image and put it in a numpy array
srcArray = numpy.array(Image.open(sys.argv[1]), dtype=numpy.uint8)
w, h, _ = srcArray.shape

# Create target array, twice the size of the original image
resArray = numpy.zeros((2*w, 2*h, 3), dtype=numpy.uint8)

# Map the RGB values in the original picture according to the BGGR pattern# 

# Blue
resArray[::2, ::2, 2] = srcArray[:, :, 2]

# Green (top row of the Bayer matrix)
resArray[1::2, ::2, 1] = srcArray[:, :, 1]

# Green (bottom row of the Bayer matrix)
resArray[::2, 1::2, 1] = srcArray[:, :, 1]

# Red
resArray[1::2, 1::2, 0] = srcArray[:, :, 0]

# Save the imgage
Image.fromarray(resArray, "RGB").save("output.png")

Pamiętaj: to jest , więc najkrótszy kod wygrywa!

agtoever
źródło
5
Prawie dostałem ataku, gdy
przewinąłem
1
@ Fatalnie przepraszam za to! ;-) Dziwny efekt, prawda?
agtoever
Instrukcje pokazują komórkę BGw górnym wierszu i GRna dole, a przykładowy obraz pokazuje RGna górze i GBna dole. Czy to oznacza, że ​​jakikolwiek układ, który umieszcza dwie zielone komórki na przekątnej, jest dopuszczalny? (pozostałe to GB / RG i GR / BG.)
Level River St
@LevelRiverSt moim zamiarem było zastosowanie się do BGGR (jak określono w czwartym wyzwaniu). Mój błąd, jeśli rzeczywisty przykładowy obraz jest w RGGB. Poprawię to, jak tylko będę na laptopie.
agtoever
Nie sądzę, aby twój przykładowy obraz był poprawny, na przykład ma dziwny niebieski odcień
lub

Odpowiedzi:

6

Pyth, 26 bajtów

[email protected],U2tU3'

Oczekuje wejściowej nazwy pliku ze znakami cudzysłowu na stdin i zapisuje w o.png. Przykładowe dane wyjściowe:

orlp
źródło
Odpowiedź jest najkrótsza jak dotąd. Zwykle to akceptuję, ale byłoby miło, gdybyś mógł wyjaśnić, jak działa twój program.
agtoever
Używałem produkt Kroneckera, używając odpowiedź z poprzedniego pytania: codegolf.stackexchange.com/questions/78797/... .
orlp
6

Matlab, 104 92 bajty

Wykorzystuje to reprezentację macierzy 3d obrazów RGB w Matlabie, a także produkt Kronecker, który jest dokładnie tym, czego potrzebujemy do stworzenia tego nowego „metapiksela” 2x2 z każdego piksela źródłowego. Dane wyjściowe są następnie wyświetlane w oknie podręcznym.

a=double(imread(input('')));for n=1:3;b(:,:,n)=kron(a(:,:,n),[1:2;2:3]==n)/255;end;imshow(b)

Zmiana rozmiaru ekranu:

wada
źródło
To [1:2;2:3]==nsprytne! Nie można usunąć b=[a,a;a,a];?
Luis Mendo,
@LuisMendo Dzięki =) To naprawdę działa, nie spodziewałem się tego!
flawr
5

Python 3, 259 254 bajtów

from PIL.Image import*
o=open(input())
w,h=o.size
n=new('RGB',(2*w,2*h))
P=Image.putpixel
for b in range(w*h):x=b//h;y=b%h;r,g,b=o.getpixel((x,y));c=2*x;d=2*y;G=0,g,0;P(n,(c,d),(0,0,b));P(n,(c+1,d),G);P(n,(c,d+1),G);P(n,(c+1,d+1),(r,0,0))
n.save('o.png')

Nazwa pliku wejściowego jest podana na standardowym wejściu. Wyjścia do o.png.

Przykładowe użycie:

$ echo mona-lisa.jpg | python bayer.py

Mona Lisa z zastosowanym odwrotnym filtrem Bayera

Miedź
źródło
2
Witamy w PPCG, fajna pierwsza odpowiedź!
Leaky Nun
4

Mathematica 118 127 bajtów

Oryginalne zgłoszenie wykorzystało rzeczywisty obraz jako dane wejściowe. Zamiast tego używa nazwy pliku.

Stosuje dwie zasady zastępowania do danych obrazu w pliku, do którego istnieje odwołanie:

  1. Dla każdego wiersza macierzy danych obrazu zamień każdy piksel {r, b, g} na niebieski piksel, {0,0, b}, a następnie zielony piksel, {0, g, 0};
  2. Oddzielnie, dla każdego wiersza macierzy danych obrazu, zamień każdy piksel {r, b, g} na zielony piksel {0, g, 0}, a następnie na czerwony piksel {r, 0,0};

Następnie Riffle(tj. Przeplataj) macierze wynikające z 1 i 2.

Image[Riffle[#/.{{_,g_,b_}:>(s=Sequence)[{0,0,b},{0,g,0}]}&/@(m=Import[#,"Data"]/255),#/.{{r_,g_,_}:>s[{0,g,0},{r,0,0}]}&/@m]]&

Image[Riffle[#/.{{_,g_,b_}:>(s=Sequence)[{0,0,b},{0,g,0}]}&/@(m=Import[#,"Data"]/255),#/.{{r_,g_,_}:>s[{0,g,0},{r,0,0}]}&/@m]]&["mona.jpg"]

odwrotny bayer

DavidC
źródło
Nie jestem pewien, ale wydaje się, że to nie spełnia
wymagań
odtąd używa teraz nazwy pliku zamiast obrazu.
DavidC
3

J, 100 96 90 bajtów

load'bmp'
'o'writebmp~,./,./($a)$2 1 1 0(_2]\(2^0 8 8 16)*{)"1(3#256)#:,a=:readbmp]stdin''

To jest skrypt w J, który odczytuje nazwę pliku wejściowego ze standardowego wejścia i wysyła wynik do pliku o nazwie o. Obrazy wejściowe i wyjściowe będą miały bmpformat. Oczekuje również, że wprowadzona zostanie tylko nazwa pliku, co oznacza, że ​​początkowe i końcowe białe znaki nie powinny być obecne.

Przykładowe użycie

$ echo -n mona.bmp | jconsole reversebayer.ijs

Próba

Wyjaśnienie

A=:readbmp]stdin''  Store the image in A as a 2d array of 24-bit rgb ints
,                   Flatten it into a list
(3#256) #:          Convert each 24-bit int to a tuple of 8-bit r/g/b ints
2 1 1 0 {"1         Select each column in BGGR order
(2^0 8 8 16) *      Shift each color to make it a 24-bit rgb value
_2 ]\               Convert each row from dimensions 1x4 to 2x2
($A) $              Reshape the list of 2x2 matrices into a matrix of
                    2x2 matrices with dimensions matching A
,./                 Append the 2x2 matrices by column
,./                 Append the 2x2 matrices by row - This is now a matrix of
                     24-bit rgb values with twice the dimensions of A
'o'writebmp~        Write the image array to a bmp file named 'o'
mile
źródło
0

Python 2, 256 275 bajtów

Najpierw uprościłem oryginalny kod:

from PIL import Image
from numpy import*
import sys

# Open image and put it in a numpy array
srcArray = array(Image.open(sys.argv[1]), dtype=uint8)
w, h, _ = srcArray.shape

# Create target array, twice the size of the original image
resArray = zeros((2*w, 2*h, 3), dtype=uint8)

# Map the RGB values in the original picture according to the BGGR pattern# 

# Blue
resArray[::2, ::2, 2] = srcArray[:, :, 2]

# Green (top row of the Bayer matrix)
resArray[1::2, ::2, 1] = srcArray[:, :, 1]

# Green (bottom row of the Bayer matrix)
resArray[::2, 1::2, 1] = srcArray[:, :, 1]

# Red
resArray[1::2, 1::2, 0] = srcArray[:, :, 0]

# Save the imgage
Image.fromarray(resArray, "RGB").save("o.png")

Następnie zminimalizuj, aby:

from PIL import Image
from numpy import*
import sys
a=array(Image.open(sys.argv[1]),dtype=uint8)
w,h,_=a.shape
b=zeros((2*w,2*h,3),dtype=uint8)
b[::2,::2,2]=a[:,:,2]
b[1::2,::2,1]=a[:,:,1]
b[::2,1::2,1]=a[:,:,1]
b[1::2,1::2,0]=a[:,:,0]
Image.fromarray(b,"RGB").save("o.png")

Wynikające z obrazu o.png:

o.png obraz po przetworzeniu

Logic Knight
źródło