Flip It, Flop It, Mean It


24

Überblick

Ersetzen Sie bei einem Bild im PPM-Format (P3) als Eingabe für jedes Pixel pim Bild die folgenden 4 Pixel (rot, grün und blau) durch den bodenebenen Durchschnittswert der jeweiligen Kanäle aller 4 Pixel:

  1. p selbst

  2. Das Pixel an pder Position, an der sich das Bild befindet, wenn es vertikal gespiegelt wird

  3. Das Pixel an pder Position, an der sich das Bild befindet, wenn es horizontal gespiegelt wird

  4. Das Pixel an pder Position, an der sich das Bild befindet, wenn es vertikal und horizontal gespiegelt wird

Das resultierende Bild wird im PPM-Format (P3) ausgegeben.

Betrachten Sie zur weiteren Erläuterung das auf 128x128 vergrößerte 8x8-Bild:

Schritt 2 Beispiel

Sei pdas rote Pixel. Um den neuen Wert für p(und die 3 blauen Pixel) zu berechnen , werden die Werte von pund die 3 blauen Pixel zusammen gemittelt:

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

Beispiele

PPM: Eingabe , Ausgabe


PPM: Eingabe , Ausgabe


PPM: Eingabe , Ausgabe


PPM: Eingabe , Ausgabe


Referenzimplementierung

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

Dieses Programm verwendet einen einzelnen Dateinamen als Eingabe, der wie die Ausgabe von formatiert ist pngtopnm <pngfile> -plain, und gibt eine einzelne durch Leerzeichen getrennte Zeile mit PPM-Daten aus.


Eine kurze Beschreibung des P3-Formats

Eine PPM-Klartextdatei, die aus generiert wurde pngtopnm <pngfile> -plain, sieht folgendermaßen aus:

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>

<...>

Dies ist das Format, das die Beispiel-Eingabe- und Ausgabedateien verwenden. Allerdings PNM ist sehr locker über seine Formatierung - jede Leerzeichen kann Werte trennen. Sie können alle Zeilenumbrüche in der obigen Datei durch jeweils ein Leerzeichen ersetzen und dennoch eine gültige Datei haben. Zum Beispiel diese Datei und diese Datei sind beide gültig und repräsentieren das gleiche Bild. Die einzige andere Voraussetzung ist, dass die Datei mit einem abschließenden Zeilenumbruch endet und dass nach dem Zeilenumbruch width*heightRGB-Triplets folgen 255.


Regeln

  • Dies ist , also gewinnt die kürzeste gültige Lösung.
  • Sie können PPM-Daten eingeben und ausgeben, die auf eine bequeme und konsistente Weise formatiert sind, solange sie gemäß dem oben beschriebenen PPM-Format gültig sind. Die einzige Ausnahme ist, dass Sie das einfache Format (P3) und nicht das binäre Format (P6) verwenden müssen.
  • Sie müssen überprüfen, ob Ihre Lösung die richtigen Bilder für die obigen Testbilder ausgibt.
  • Alle Bilder haben eine Bittiefe von 8 Bit.

Zusätzliche Lektüre: Wikipedia-Seite im Netpbm-Format


Snippet testen (danke an Calvins Hobbys dafür)


Sind Bildbibliotheken erlaubt, die ppm-Dateien öffnen / speichern?
Calvins Hobbys

@ Calvin'sHobbies Ja
Mego

3
" Flip es, Flop es, den Durchschnitt " youtube.com/watch?v=D8K90hX4PrE
Luis Mendo

3
Vielleicht "Flip it, flop it, mean it"?
Conor O'Brien

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Das klingt nach Party und was Luis gepostet hat.
Addison Crump

Antworten:


4

Pyth, 30 29 Bytes

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Mein Programm erwartet alle Metadaten in der ersten Zeile und die Bilddaten Zeile für Zeile in den Zeilen nach auf stdin. Dies ist ein kleines Python-Programm zum Konvertieren einer gültigen PPM-Datei in eine PPM-Datei, die mein Programm verstehen kann:

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

Sobald Sie die Bilddaten Zeile für Zeile haben, sind die Operationen wirklich einfach. Zuerst lese ich die Bilddaten in eine Liste von Listen mit ganzen Zahlen ( JrR7.z), dann erstelle ich die horizontal gespiegelte Version, indem ich alle 3 ganzen Zahlen gruppiere und sie für jede Zeile umkehre ( Km_cd3J). Dann sind die vertikal gespiegelten Versionen einfach _J_K, da wir nur Zeilen umkehren können.

Ich nehme all diese Matrizen, drücke sie zu einem 1d-Array zusammen .nM, transponiere mit C, um eine Liste der Listen der einzelnen ms.OdPixelkomponenten zu erhalten, mittle und schneide auf jede dieser Listen ab ( ) und drucke schließlich zusammen mit Zeilenumbrüchen j.

Beachten Sie, dass mein Programm Ausgaben in einem anderen Format generiert (aber immer noch gültiges PPM). Die Demo-Bilder können in diesem Bildalbum angesehen werden .


13

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

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

Richtiges Werkzeug für den Job.

Muss in einem Verzeichnis ausgeführt werden, das eine einzelne Datei aenthält, die die zu transformierenden PPM-Daten enthält. Da dieser Dateiname von Bedeutung ist, habe ich der Byteanzahl ein Byte hinzugefügt.

PNG-Thumbnail-Ausgaben (nicht sicher, warum dies notwendig ist, da sie sowieso alle gleich sind, aber die Frage lautet so, so ...):

Pinguin Quintopie Peter Minibits

Danke an nneonneo für das Speichern von 2 Bytes!


3
Ich benötige die Ausgaben, weil die Leute die schlechte Angewohnheit haben, Lösungen zu veröffentlichen, ohne sie zu testen. +1 für -flop, ich möchte wirklich überrascht sein, dass es eine Flagge ist.
Mego

1
Rasieren Sie 2 Bytes mit C=convertund $Canstelle von alias.
Nneonneo

12

Matlab, 106 82 80 Bytes

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

Das Bild wird als n*m*3Matrix geladen . Dann drehen wir die Matrix um, addieren sie für beide Achsen zu sich selbst und schreiben sie erneut in eine Datei.


Ich konnte keinen Ort finden, an dem ich so große Textdateien hochladen konnte. Hier sind die PNG-Versionen:


Oh mein Gott, ich wusste gar nicht, dass du <imgTags verwenden kannst !
Fehler

1
Ab MATLAB R2013b ist es möglich, anstelle von flipdim flip zu verwenden . Das sollte Ihnen 3 weitere Bytes ersparen. In der Hilfe von flipdim heißt es tatsächlich: "flipdim wird in einer zukünftigen Version entfernt. Verwenden Sie stattdessen FLIP."
slvrbld

10

Mathematica, 86 84 Bytes

Danke an DavidC für den Rat. (spart 2 Bytes)

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

Der erste und der zweite Parameter sind die Pfade zu den Eingangs- bzw. Ausgangsbildern.


Testfälle

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

Ergebnis

(PNG-Versionen der Bilder werden unten hochgeladen)

Import["penguin2.pnm"]

Import["quintopia2.pnm"]

Import["peter2.pnm"]


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

4

Julia, 157 Bytes

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

Dies ist eine Lambda-Funktion, die eine Zeichenfolge akzeptiert, die den vollständigen Pfad zu einer PPM-Datei enthält, und diese mit dem transformierten Bild überschreibt. Um es aufzurufen, weisen Sie es einer Variablen zu.

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

Beispielausgaben:

Pinguin Quintopie Peter Minibits


4

Python 2 + PIL, 268

Jetzt verwende ich massiv PIL, indem ich das Spiegeln von Bildern und das Alpha-Blending verwende

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

Resultierende Bilder sind hier verfügbar


1
Bitte fügen Sie die in den Regeln geforderten Ausgaben für die Testfälle bei.
Mego
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.