Flip It, Flop It, Mean It

24

Przegląd

Biorąc pod uwagę obraz w formacie PPM (P3) jako dane wejściowe, dla każdego piksela pna obrazie zamień każdy z następujących 4 pikseli na czerwony, zielony i niebieski na uśrednioną średnią z odpowiednich kanałów wszystkich 4 pikseli:

  1. p samo

  2. Piksel zlokalizowany w pmiejscu, w którym obraz jest obrócony w pionie

  3. Piksel zlokalizowany w pmiejscu, w którym obraz jest obrócony w poziomie

  4. Piksel zlokalizowany w pmiejscu, w którym obraz jest odwracany zarówno w pionie, jak iw poziomie

Wygeneruj uzyskany obraz w zwykłym formacie PPM (P3).

Aby uzyskać dalsze wyjaśnienia, rozważ ten obraz 8 x 8 powiększony do 128 x 128:

przykład kroku 2

Niech pbędzie czerwonym pikselem. Aby obliczyć nową wartość p(i 3 niebieskie piksele), wartości pi 3 niebieskie piksele zostaną uśrednione razem:

p1 = (255, 0, 0)
p2 = (0, 0, 255)
p3 = (0, 0, 255)
p4 = (0, 0, 255)
p_result = (63, 0, 191)

Przykłady

PPM: wejście , wyjście


PPM: wejście , wyjście


PPM: wejście , wyjście


PPM: wejście , wyjście


Wdrożenie referencyjne

#!/usr/bin/python

import sys
from itertools import *

def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return list(izip_longest(*args, fillvalue=fillvalue))

def flatten(lst):
    return sum(([x] if not isinstance(x, list) else flatten(x) for x in lst), [])

def pnm_to_bin(p):
    w,h = map(int,p[1].split(' '))
    data = map(int, ' '.join(p[3:]).replace('\n', ' ').split())
    bin = []
    lines = grouper(data, w*3)
    for line in lines:
        data = []
        for rgb in grouper(line, 3):
            data.append(list(rgb))
        bin.append(data)
    return bin

def bin_to_pnm(b):
    pnm = 'P3 {} {} 255 '.format(len(b[0]), len(b))
    b = flatten(b)
    pnm += ' '.join(map(str, b))
    return pnm

def imageblender(img):
    h = len(img)
    w = len(img[0])
    for y in range(w):
        for x in range(h):
            for i in range(3):
                val = (img[x][y][i] + img[x][~y][i] + img[~x][y][i] + img[~x][~y][i])//4
                img[x][y][i],img[x][~y][i],img[~x][y][i],img[~x][~y][i] = (val,)*4
    return img

def main(fname):
    bin = pnm_to_bin(open(fname).read().split('\n'))
    bin = imageblender(bin)
    return bin_to_pnm(bin)

if __name__ == '__main__':
    print main(sys.argv[1])

Ten program pobiera jako dane wejściowe pojedynczą nazwę pliku, sformatowaną jak dane wyjściowe pngtopnm <pngfile> -plaini wysyła pojedynczy wiersz danych PPM oddzielony spacjami.


Krótki opis formatu P3

Plik tekstowy PPM wygenerowany z pngtopnm <pngfile> -plainbędzie wyglądał następująco:

P3
<width in pixels> <height in pixels>
<maximum value as defined by the bit depth, always 255 for our purposes>
<leftmost 24 pixels of row 1, in RGB triples, space-separated; like (0 0 0 1 1 1 ...)>
<next 24 pixels of row 1>
<...>
<rightmost (up to) 24 pixels of row 1>

<leftmost 24 pixels of row 2>
<next 24 pixels of row 2>
<...>
<rightmost (up to) 24 pixels of row 2>

<...>

Jest to format używany w przykładowych plikach wejściowych i wyjściowych. Jednak formatowanie danych PNM jest bardzo luźne - każda biała spacja może rozdzielać wartości. Możesz zastąpić wszystkie znaki nowego wiersza w powyższym pliku pojedynczym odstępem i nadal mieć poprawny plik. Na przykład ten plik i ten plik są poprawne i reprezentują ten sam obraz. Jedyne inne wymagania to to, że plik musi kończyć się znakiem nowej linii, a po nim muszą być width*heighttrojaczki RGB 255.


Zasady

  • To jest , więc wygrywa najkrótsze prawidłowe rozwiązanie.
  • Możesz wprowadzać i wyprowadzać dane PPM sformatowane w dowolny wygodny i spójny sposób, o ile są one zgodne z opisanym powyżej formatem PPM. Jedynym wyjątkiem jest to, że musisz użyć formatu zwykłego (P3), a nie formatu binarnego (P6).
  • Musisz potwierdzić, że Twoje rozwiązanie wyświetla prawidłowe obrazy dla powyższych obrazów testowych.
  • Wszystkie obrazy będą miały głębię 8 bitów.

Dodatkowa lektura: strona Wikipedii w formacie Netpbm


Testowanie fragmentu kodu (dzięki za to hobby Calvina)

Mego
źródło
Czy biblioteki obrazów, które otwierają / zapisują pliki ppm są dozwolone?
Calvin's Hobbies
@ Calvin'sHobbies Tak
Mego
3
Odwróć, flop, uśrednij
Luis Mendo
3
Może „Odwróć to, wyrzuć to, oznacz to”?
Conor O'Brien
2
@ CᴏɴᴏʀO'Bʀɪᴇɴ To brzmi jak impreza, och, czekaj, co opublikował Luis.
Addison Crump

Odpowiedzi:

4

Pyth, 30 29 bajtów

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Mój program oczekuje wszystkich metadanych w pierwszym wierszu, a dane obrazu wiersz po wierszu w wierszach po włączeniu standardowego wejścia. Aby pomóc, jest to mały program w języku Python do konwersji dowolnego prawidłowego pliku PPM na plik PPM, który mój program może zrozumieć:

import sys
p3, w, h, d, *data = sys.stdin.read().split()
print(p3, w, h, d)
for i in range(0, int(w) * int(h), int(w)):
    print(" ".join(data[i:i+int(w)]))

Po uzyskaniu danych obrazu wiersz po rzędzie operacje są naprawdę proste. Najpierw czytam dane obrazu do listy list liczb całkowitych ( JrR7.z), a następnie tworzę wersję lustrzaną w poziomie, grupując co 3 liczby całkowite i odwracając je dla każdego wiersza ( Km_cd3J). Wersje lustrzane w pionie są po prostu _J_K, ponieważ możemy po prostu odwrócić rzędy.

Biorę wszystkie te macierze, spłaszczam każdą z nich do tablicy 1d .nM, transponuję za pomocą, Caby uzyskać listę list każdego ze składników pikseli, uśredniam i obcinam do każdej z tych list ( ms.Od), a na końcu drukuję dołączając nowe linie j.

Zauważ, że mój program generuje dane wyjściowe w innym formacie (ale nadal prawidłowym PPM). Obrazy demo można obejrzeć w tym albumie imgur .

orlp
źródło
13

Bash (+ ImageMagick), 64 + 1 = 65 bajtów

C=convert;$C a -flip b;$C a -flop c;$C c -flip d;$C * -average e

Odpowiednie narzędzie do pracy.

Musi być uruchomiony w katalogu zawierającym pojedynczy plik azawierający dane PPM do transformacji. Ponieważ ta nazwa pliku jest znacząca, dodałem jeden bajt do liczby bajtów.

Dane wyjściowe miniatury PNG (nie jestem pewien, dlaczego jest to konieczne, ponieważ i tak wszystkie są takie same, ale pytanie tak mówi, więc ...):

pingwin kwintopia Piotr minibity

Dzięki nneonneo za oszczędność 2 bajtów!

Klamka
źródło
3
Potrzebuję wyników, ponieważ ludzie mają zły nawyk publikowania rozwiązań bez ich testowania. +1 za -flop, naprawdę chcę być zaskoczony, że to flaga.
Mego
1
Ogol 2 bajty za pomocą C=converti $Czamiast alias.
nneonneo
12

Matlab, 106 82 80 bajtów

i=imread(input(''))/4;for k=1:2;i=i+flipdim(i,k);end;imwrite(i,'p3.pnm','e','A')

Obraz jest ładowany jako n*m*3matryca. Następnie odwracamy macierz i dodajemy do siebie dla obu osi i zapisujemy ją ponownie do pliku.


Nie mogłem znaleźć miejsca na przesyłanie plików tekstowych tak dużych, więc oto wersje PNG:

wada
źródło
Omg, nawet nie wiedziałem, że możesz używać <imgtagów!
flawr
1
W MATLAB R2013b i nowszych można zastosować flip zamiast flipdim . To powinno zaoszczędzić Ci jeszcze 3 bajty. Pomoc Flipdima mówi: „Flipdim zostanie usunięty w przyszłej wersji. Zamiast tego użyj FLIP”.
slvrbld
10

Mathematica, 86 84 bajtów

Dzięki DavidC za radę. (zapisuje 2 bajty)

Export[#2,⌊Mean@Join[#,(r=Reverse)/@#]&@{#,r/@#}&@Import[#,"Data"]⌋~Image~"Byte"]&

Pierwszy i drugi parametr to odpowiednio ścieżki do obrazów wejściowych i wyjściowych.


Przypadki testowe

f=%; (assign the function to symbol f)
f["penguin.pnm","penguin2.pnm"]
f["quintopia.pnm","quintopia2.pnm"]
f["peter.pnm","peter2.pnm"]

Wynik

(Wersje obrazów PNG są przesyłane poniżej)

Import["penguin2.pnm"]

Import["quintopia2.pnm"]

Import["peter2.pnm"]

njpipeorgan
źródło
Join[#,(r=Reverse)/@#]
DavidC
4

Julia, 157 bajtów

using FileIO
s->(a=load(s);b=deepcopy(a);d=a.data;(n,m)=size(d);for i=1:n,j=1:m b.data[i,j]=mean([d[i,j];d[n-i+1,j];d[i,m-j+1];d[n-i+1,m-j+1]])end;save(s,b))

Jest to funkcja lambda, która akceptuje ciąg zawierający pełną ścieżkę do pliku PPM i zastępuje go przekształconym obrazem. Aby go wywołać, przypisz go do zmiennej.

Nie golfowany:

using FileIO

function f(s::AbstractString)
    # Load the input image
    a = load(s)

    # Create a copy (overwriting does bad things)
    b = deepcopy(a)

    # Extract the matrix of RGB triples from the input
    d = a.data

    # Store the size of the matrix
    n, m = size(d)

    # Apply the transformation
    # Note that we don't floor the mean; this is because the RGB values
    # aren't stored as integers, they're fixed point values in [0,1].
    # Simply taking the mean produces the desired output.
    for i = 1:n, j = 1:m
        b.data[i,j] = mean([d[i,j]; d[n-i+1,j]; d[i,m-j+1]; d[n-i+1,m-j+1]])
    end

    # Overwrite the input
    save(s, b)
end

Przykładowe wyniki:

pingwin kwintopia Piotr minibity

Alex A.
źródło
4

python 2 + PIL, 268

Teraz masowo używam PIL, używając przewijania obrazu i mieszania alfa

from PIL import Image
I=Image
B,T=I.blend,I.FLIP_TOP_BOTTOM
a=I.open(raw_input()).convert('RGB')
exec'[email protected]_LEFT_RIGHT);c=a@T);d=b@T)'.replace('@','.transpose(')
x,y=a.size
print'P3',x,y,255
for r,g,b in list(B(B(B(a,b,0.5),c,0.25),d,0.25).getdata()):print r,g,b

Powstałe obrazy są dostępne tutaj

dieter
źródło
1
Podaj dane wyjściowe dla przypadków testowych, zgodnie z wymogami reguł.
Mego