Flip It, Flop It, Mean It


24

visão global

Dada uma imagem no formato simples PPM (P3) como entrada, para cada pixel pna imagem, substitua cada um dos 4 pixels a seguir, vermelho, verde e azul pelo valor médio do piso dos respectivos canais de todos os 4 pixels:

  1. p em si

  2. O pixel localizado no plocal quando a imagem é invertida verticalmente

  3. O pixel localizado na plocalização de quando a imagem é invertida horizontalmente

  4. O pixel localizado no plocal em que a imagem é invertida vertical e horizontalmente

Envie a imagem resultante no formato PPM (P3).

Para mais explicações, considere esta imagem 8x8, ampliada para 128x128:

exemplo da etapa 2

Let pSer o pixel vermelho. Para calcular o novo valor para p(e os 3 pixels azuis), os valores pe os 3 pixels azuis serão calculados em média juntos:

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

Exemplos

PPM: entrada , saída


PPM: entrada , saída


PPM: entrada , saída


PPM: entrada , saída


Implementação de referência

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

Este programa usa um único nome de arquivo como entrada, formatado como a saída de pngtopnm <pngfile> -plain, e gera uma única linha de dados PPM separados por espaços.


Uma Breve Descrição do Formato P3

Um arquivo de texto simples PPM gerado a partir pngtopnm <pngfile> -plainserá semelhante a este:

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>

<...>

Esse é o formato que os arquivos de entrada e saída de exemplo usam. No entanto, o PNM é muito flexível quanto à sua formatação - qualquer espaço em branco pode separar valores. Você pode substituir todas as novas linhas no arquivo acima por um único espaço cada e ainda assim ter um arquivo válido. Por exemplo, este arquivo e este arquivo são válidos e representam a mesma imagem. Os únicos outros requisitos são que o arquivo termine com uma nova linha à direita e que haja width*heighttrigêmeos RGB após o 255.


Regras

  • Isso é , então a solução válida mais curta vence.
  • Você pode inserir e enviar dados PPM formatados de qualquer maneira conveniente e consistente, desde que sejam válidos de acordo com o formato PPM descrito acima. A única exceção é que você deve usar o formato simples (P3) e não o formato binário (P6).
  • Você deve verificar se sua solução gera as imagens corretas para as imagens de teste acima.
  • Todas as imagens terão uma profundidade de 8 bits.

Leitura extra: página wikipedia no formato Netpbm


Snippet de teste (obrigado pelo hobby de Calvin)


São permitidas bibliotecas de imagens que abrem / salvam arquivos ppm?
Calvin Passatempos

@ Calvin'sHobbies Sim
Mego

3
" Flip-lo, flop que, média, " youtube.com/watch?v=D8K90hX4PrE
Luis Mendo

3
Talvez "Vire, jogue, fale sério"?
Conor O'Brien

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Isso soa como uma festa - ah, espere, o que Luis postou.
precisa saber é o seguinte

Respostas:


4

Pitão, 30 29 bytes

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Meu programa espera todos os metadados na primeira linha e os dados da imagem linha por linha nas linhas após stdin. Para ajudar, este é um pequeno programa Python para converter qualquer arquivo PPM válido em um arquivo PPM que meu programa possa entender:

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

Depois de ter os dados da imagem linha por linha, as operações são realmente simples. Primeiro, leio os dados da imagem em uma lista de listas de números inteiros ( JrR7.z) e, em seguida, crio a versão espelhada horizontalmente agrupando a cada 3 números inteiros e revertendo-os para cada linha ( Km_cd3J). As versões espelhadas verticalmente são simples _J_K, pois podemos apenas reverter as linhas.

Eu pego todas essas matrizes, alisei cada uma delas em uma matriz 1d .nM, transponho Cpara obter uma lista de listas de cada um dos componentes de pixel, calcule a média e trunque para int cada uma dessas listas ( ms.Od) e, finalmente, imprimai as novas linhas j.

Observe que meu programa gera saída em um formato diferente (mas ainda é válido para PPM). As imagens de demonstração podem ser visualizadas neste álbum imgur .


13

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

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

Ferramenta certa para o trabalho.

Deve ser executado em um diretório que contém um único arquivo aque contém os dados do PPM a serem transformados. Como esse nome de arquivo é significativo, adicionei um byte à contagem de bytes.

Saídas em miniatura PNG (não sei por que isso é necessário, porque são todos iguais, mas a pergunta diz isso, então ...):

pinguim quintopia Pedro minibits

Obrigado a nneonneo por salvar 2 bytes!


3
Exijo as saídas porque as pessoas têm o mau hábito de postar soluções sem testá-las. +1 para -flop, eu realmente quero ser surpreendido por ser uma bandeira.
Mego

11
Raspe 2 bytes usando C=converte em $Cvez de 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')

A imagem é carregada como n*m*3 matriz. Em seguida, invertemos a matriz e adicionamos a si mesma para ambos os eixos, e escrevemos novamente em um arquivo.


Não consegui encontrar um lugar para carregar arquivos de texto tão grandes, então aqui estão as versões PNG:


Omg, eu nem sabia que você poderia usar <imgtags!
flawr

11
No MATLAB R2013b e mais recente, é possível usar o flip em vez do flipdim . Isso deve economizar mais 3 bytes. A ajuda do flipdim realmente diz: "o flipdim será removido em uma versão futura. Use o FLIP."
slvrbld

10

Mathematica, 86 84 bytes

Agradeço a DavidC pelo conselho. (economiza 2 bytes)

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

O primeiro e o segundo parâmetros são os caminhos para as imagens de entrada e saída, respectivamente.


Casos de teste

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

Resultado

(As versões PNG das imagens são enviadas abaixo)

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

Essa é uma função lambda que aceita uma sequência que contém o caminho completo para um arquivo PPM e a substitui pela imagem transformada. Para chamá-lo, atribua-o a uma variável.

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

Exemplo de saídas:

pinguim quintopia Pedro minibits


4

python 2 + PIL, 268

Agora eu uso massivamente o PIL, usando inversão de imagem e mistura 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

As imagens resultantes estão disponíveis aqui


11
Inclua as saídas para os casos de teste, conforme exigido pelas regras.
Mego
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.