Flip It, Flop It, Mean It


24

Panoramica

Data un'immagine in formato PPM (P3) semplice come input, per ciascun pixel pnell'immagine, sostituisci ciascuno dei seguenti 4 pixel in rosso, verde e blu con il valore medio pavimentato dei rispettivi canali di tutti e 4 i pixel:

  1. p si

  2. Il pixel situato nella pposizione dell 'immagine quando l'immagine viene capovolta verticalmente

  3. Il pixel situato nella pposizione dell 'immagine quando l'immagine viene capovolta orizzontalmente

  4. Il pixel situato nella pposizione dell 'immagine quando l'immagine viene capovolta sia in verticale che in orizzontale

Stampa l'immagine risultante in formato PPM (P3) semplice.

Per ulteriori spiegazioni, considera questa immagine 8x8, ingrandita a 128x128:

esempio del passaggio 2

Lascia che psia il pixel rosso. Per calcolare il nuovo valore per p(e i 3 pixel blu), i valori di pe dei 3 pixel blu saranno calcolati insieme in media:

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

Esempi

PPM: input , output


PPM: input , output


PPM: input , output


PPM: input , output


Implementazione di riferimento

#!/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])

Questo programma utilizza un singolo nome file come input, formattato come l'output di pngtopnm <pngfile> -plaine genera una singola riga di dati PPM separati da spazi.


Una breve descrizione del formato P3

Un file in testo semplice PPM generato da pngtopnm <pngfile> -plainsarà simile al seguente:

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>

<...>

Questo è il formato utilizzato dai file di input e output di esempio. Tuttavia, PNM è molto libero riguardo alla sua formattazione: qualsiasi spazio bianco può separare i valori. È possibile sostituire tutte le nuove righe nel file sopra con un singolo spazio ciascuna e avere comunque un file valido. Ad esempio, questo file e questo file sono entrambi validi e rappresentano la stessa immagine. Gli unici altri requisiti sono che il file deve terminare con una nuova riga finale e che devono essere presenti width*heightterzine RGB 255.


Regole

  • Questo è , quindi vince la soluzione valida più breve.
  • È possibile immettere e produrre dati PPM formattati in qualsiasi modo conveniente e coerente, purché sia ​​valido secondo il formato PPM sopra descritto. L'unica eccezione è che è necessario utilizzare il formato normale (P3) e non il formato binario (P6).
  • È necessario fornire la verifica che la soluzione fornisca le immagini corrette per le immagini di prova sopra riportate.
  • Tutte le immagini avranno una profondità di 8 bit.

Letture extra: pagina Wikipedia in formato Netpbm


Test dello snippet (grazie a Hobby di Calvin per questo)


Sono consentite librerie di immagini che aprono / salvano file ppm?
Hobby di Calvin il

@Calvin'sHobbies Sì
Mego

3
" Capovolgi, flop, media " youtube.com/watch?v=D8K90hX4PrE
Luis Mendo

3
Forse "Capovolgi, flop, vuoi dire"?
Conor O'Brien,

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Sembra un po 'di festa, oh, aspetta, quello che Luis ha pubblicato.
Addison Crump,

Risposte:


4

Pyth, 30 29 byte

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Il mio programma prevede tutti i metadati sulla prima riga e i dati dell'immagine riga per riga sulle righe dopo su stdin. Per aiutare, questo è un piccolo programma Python per convertire qualsiasi file PPM valido in un file PPM che il mio programma può capire:

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)]))

Una volta che hai i dati dell'immagine riga per riga le operazioni sono davvero semplici. Prima leggo i dati dell'immagine in un elenco di elenchi di numeri interi ( JrR7.z), quindi creo la versione con mirroring orizzontale raggruppando ogni 3 numeri interi e invertendoli per ogni riga ( Km_cd3J). Quindi le versioni con mirroring verticale sono semplicemente _J_K, dal momento che possiamo semplicemente invertire le righe.

Prendo tutte quelle matrici, le appiattisco ognuna in un array 1d .nM, traspone con Cper ottenere un elenco di elenchi di ciascuno dei componenti pixel, la media e troncare per int ciascuno di quegli elenchi ( ms.Od), e infine stampare uniti da nuove linee j.

Nota che il mio programma genera output in un formato diverso (ma ancora valido PPM). Le immagini demo possono essere visualizzate in questo album imgur .


13

Bash (+ ImageMagick), 64 + 1 = 65 byte

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

Strumento giusto per il lavoro.

Deve essere eseguito in una directory contenente un singolo file ache contiene i dati PPM da trasformare. Poiché questo nome file è significativo, ho aggiunto un byte al conteggio dei byte.

Output delle miniature PNG (non so perché questo sia necessario perché sono tutti uguali comunque, ma la domanda lo dice, quindi ...):

pinguino quintopia Peter minibits

Grazie a nneonneo per aver salvato 2 byte!


3
Ho bisogno dei risultati perché le persone hanno la cattiva abitudine di pubblicare soluzioni senza testarle. +1 per -flop, voglio davvero essere sorpreso che sia una bandiera.
Mego

1
Elimina 2 byte usando C=converte $Cinvece di alias.
nneonneo,

12

Matlab, 106 82 80 byte

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

L'immagine viene caricata come n*m*3matrice. Quindi capovolgiamo la matrice e la aggiungiamo a se stessa per entrambi gli assi e la riscriviamo in un file.


Non sono riuscito a trovare un posto dove caricare file di testo così grandi, quindi ecco le versioni PNG:


Oh mio Dio, non sapevo nemmeno che potessi usare i <imgtag!
flawr

1
In MATLAB R2013b e versioni successive è possibile utilizzare flip anziché flipdim . Ciò dovrebbe farti risparmiare altri 3 byte. La guida di flipdim in realtà dice: "flipdim verrà rimosso in una versione futura. Usa invece FLIP".
slvrbld,

10

Mathematica, 86 84 byte

Grazie a DavidC per il consiglio. (salva 2 byte)

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

Il primo e il secondo parametro sono rispettivamente i percorsi delle immagini di input e output.


Casi test

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

Risultato

(Le versioni PNG delle immagini sono caricate di seguito)

Import["penguin2.pnm"]

Import["quintopia2.pnm"]

Import["peter2.pnm"]


Join[#,(r=Reverse)/@#]
DavidC,

4

Julia, 157 byte

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))

Questa è una funzione lambda che accetta una stringa contenente il percorso completo di un file PPM e lo sovrascrive con l'immagine trasformata. Per chiamarlo, assegnarlo a una variabile.

Ungolfed:

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

Esempi di output:

pinguino quintopia Peter minibits


4

python 2 + PIL, 268

Ora uso in modo massiccio PIL, usando il capovolgimento delle immagini e la fusione alfa

from PIL import Image
I=Image
B,T=I.blend,I.FLIP_TOP_BOTTOM
a=I.open(raw_input()).convert('RGB')
exec'b=a@I.FLIP_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

Le immagini risultanti sono disponibili qui


1
Includere gli output per i casi di test, come richiesto dalle regole.
Mego,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.