Flip It, Flop It, Mean It

24

Présentation

Étant donné une image au format PPM (P3) ordinaire en entrée, pour chaque pixel pde l'image, remplacez chacun des 4 pixels suivants rouge, vert et bleu par la valeur moyenne plancher des canaux respectifs des 4 pixels:

  1. p lui-même

  2. Le pixel situé à pl'emplacement de lorsque l'image est retournée verticalement

  3. Le pixel situé à pl'emplacement de lorsque l'image est retournée horizontalement

  4. Le pixel situé à pl'emplacement de lorsque l'image est retournée verticalement et horizontalement

Sortez l'image résultante au format PPM (P3).

Pour plus d'explications, considérez cette image 8x8, agrandie à 128x128:

exemple de l'étape 2

Soit ple pixel rouge. Pour calculer la nouvelle valeur pour p(et les 3 pixels bleus), les valeurs de pet les 3 pixels bleus seront moyennées ensemble:

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

Exemples

PPM: entrée , sortie


PPM: entrée , sortie


PPM: entrée , sortie


PPM: entrée , sortie


Implémentation de référence

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

Ce programme prend un seul nom de fichier en entrée, formaté comme la sortie de pngtopnm <pngfile> -plain, et génère une seule ligne de données PPM séparées par des espaces.


Une brève description du format P3

Un fichier texte en clair PPM généré à partir de pngtopnm <pngfile> -plainressemblera à ceci:

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>

<...>

Il s'agit du format utilisé par les exemples de fichiers d'entrée et de sortie. Cependant, PNM est très vague quant à sa mise en forme - tout espace peut séparer les valeurs. Vous pouvez remplacer tous les retours à la ligne du fichier ci-dessus par un seul espace chacun et conserver un fichier valide. Par exemple, ce fichier et ce fichier sont tous deux valides et représentent la même image. Les seules autres exigences sont que le fichier doit se terminer par un retour à la ligne de fin et qu'il doit y avoir width*heightdes triplets RVB après le 255.


Règles

  • C'est le , donc la solution valide la plus courte l'emporte.
  • Vous pouvez entrer et sortir des données PPM formatées de toute manière pratique et cohérente, tant qu'elles sont valides selon le format PPM décrit ci-dessus. La seule exception est que vous devez utiliser le format ordinaire (P3) et non le format binaire (P6).
  • Vous devez vérifier que votre solution génère les images correctes pour les images de test ci-dessus.
  • Toutes les images auront une profondeur de 8 bits.

Lecture supplémentaire: page wikipedia au format Netpbm


Test d'extrait (merci à Calvin's Hobbies pour cela)

Mego
la source
Les bibliothèques d'images qui ouvrent / enregistrent des fichiers ppm sont-elles autorisées?
Hobbies de Calvin
@ Calvin'sHobbies Yes
Mego
3
" Flip it, flop it, average it " youtube.com/watch?v=D8K90hX4PrE
Luis Mendo
3
Peut-être "Flip it, flop it, mean it"?
Conor O'Brien
2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Cela ressemble à une fête anth- oh, attendez, ce que Luis a posté.
Addison Crump

Réponses:

4

Pyth, 30 29 octets

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Mon programme attend toutes les métadonnées sur la première ligne, et les données d'image ligne par ligne sur les lignes après sur stdin. Pour vous aider, voici un petit programme Python pour convertir n'importe quel fichier PPM valide en un fichier PPM que mon programme peut comprendre:

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

Une fois que vous avez les données d'image ligne par ligne, les opérations sont vraiment simples. J'ai d'abord lu les données d'image dans une liste de listes d'entiers ( JrR7.z), puis je crée la version en miroir horizontal en regroupant tous les 3 entiers et en les inversant pour chaque ligne ( Km_cd3J). Ensuite, les versions en miroir vertical sont simplement _J_K, car nous pouvons simplement inverser les lignes.

Je prends toutes ces matrices, aplatis chacune d'elles dans un tableau 1d avec .nM, transpose avec Cpour obtenir une liste de listes de chacun des composants de pixel, moyenne et tronque à int chacune de ces listes ( ms.Od), et enfin imprimer joint par des retours à la ligne j.

Notez que mon programme génère une sortie dans un format différent (mais toujours valide PPM). Les images de démonstration peuvent être consultées dans cet album imgur .

orlp
la source
13

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

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

Le bon outil pour le travail.

Doit être exécuté dans un répertoire contenant un seul fichier acontenant les données PPM à transformer. Étant donné que ce nom de fichier est significatif, j'ai ajouté un octet au nombre d'octets.

Sorties de vignettes PNG (je ne sais pas pourquoi cela est nécessaire car elles sont toutes les mêmes de toute façon, mais la question le dit, alors ...):

manchot quintopie peter minibits

Merci à nneonneo pour avoir économisé 2 octets!

Poignée de porte
la source
3
J'ai besoin des sorties car les gens ont la mauvaise habitude de poster des solutions sans les tester. +1 pour -flop, je veux vraiment être surpris que ce soit un drapeau.
Mego
1
Raser 2 octets en utilisant C=convertet $Cau lieu de alias.
nneonneo
12

Matlab, 106 82 80 octets

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

L'image est chargée comme n*m*3matrice. Ensuite, nous inversons la matrice et l'ajoutons à elle-même pour les deux axes, puis l'écrivons à nouveau dans un fichier.


Je n'ai pas trouvé d'endroit pour télécharger des fichiers texte si gros, alors voici les versions PNG:

flawr
la source
Omg, je ne savais même pas que vous pouviez utiliser des <imgtags!
flawr
1
Dans MATLAB R2013b et plus récent, il est possible d'utiliser flip au lieu de flipdim . Cela devrait vous faire économiser 3 octets supplémentaires. L'aide de flipdim dit en fait: "flipdim sera supprimé dans une prochaine version. Utilisez plutôt FLIP."
slvrbld
10

Mathematica, 86 84 octets

Merci à DavidC pour les conseils. (enregistre 2 octets)

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

Les premier et second paramètres sont respectivement les chemins d'accès aux images d'entrée et de sortie.


Cas de test

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

Résultat

(Les versions PNG des images sont téléchargées ci-dessous)

Import["penguin2.pnm"]

Import["quintopia2.pnm"]

Import["peter2.pnm"]

njpipeorgan
la source
Join[#,(r=Reverse)/@#]
DavidC
4

Julia, 157 octets

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

Il s'agit d'une fonction lambda qui accepte une chaîne contenant le chemin d'accès complet à un fichier PPM et l'écrase avec l'image transformée. Pour l'appeler, affectez-le à une variable.

Non golfé:

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

Exemples de sorties:

manchot quintopie peter minibits

Alex A.
la source
4

python 2 + PIL, 268

Maintenant, j'utilise massivement PIL, en utilisant le retournement d'image et le mélange alpha

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

Les images résultantes sont disponibles ici

diète
la source
1
Veuillez inclure les sorties pour les cas de test, comme requis par les règles.
Mego