Flip It, Flop It, Mean It


24

Ikhtisar

Diberikan gambar dalam format PPM (P3) polos sebagai input, untuk setiap piksel pdalam gambar, ganti masing-masing merah, hijau, dan biru 4 piksel berikut dengan nilai rata-rata lantai dari saluran masing-masing dari 4 piksel:

  1. p diri

  2. Pixel terletak di plokasi ketika gambar dibalik secara vertikal

  3. Pixel terletak di plokasi ketika gambar dibalik secara horizontal

  4. Pixel terletak di plokasi ketika gambar dibalik secara vertikal dan horizontal

Keluarkan gambar yang dihasilkan dalam format PPM (P3) polos.

Untuk penjelasan lebih lanjut, pertimbangkan gambar 8x8 ini, diperbesar menjadi 128x128:

contoh langkah 2

Membiarkan pmenjadi piksel merah. Untuk menghitung nilai baru untuk p(dan 3 piksel biru), nilai pdan 3 piksel biru akan dirata-ratakan bersama-sama:

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

Contohnya

PPM: input , output


PPM: input , output


PPM: input , output


PPM: input , output


Implementasi Referensi

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

Program ini mengambil nama file tunggal sebagai input, diformat seperti output pngtopnm <pngfile> -plain, dan output satu baris data PPM yang dipisahkan oleh spasi.


Penjelasan Singkat tentang Format P3

File plaintext PPM yang dihasilkan pngtopnm <pngfile> -plainakan terlihat seperti ini:

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>

<...>

Ini adalah format yang digunakan oleh file input dan output contoh. Namun, PNM sangat longgar tentang pemformatannya - spasi apa pun dapat memisahkan nilai. Anda dapat mengganti semua baris baru dalam file di atas dengan masing-masing satu ruang, dan masih memiliki file yang valid. Misalnya, file ini dan file ini sama-sama valid, dan mewakili gambar yang sama. Satu-satunya persyaratan lain adalah bahwa file harus diakhiri dengan baris baru, dan harus ada width*heighttriplet RGB yang mengikuti 255.


Aturan

  • Ini adalah , sehingga solusi terpendek yang valid menang.
  • Anda dapat memasukkan dan mengeluarkan data PPM yang diformat dengan cara apa pun yang nyaman dan konsisten, asalkan valid sesuai dengan format PPM yang dijelaskan di atas. Satu-satunya pengecualian adalah Anda harus menggunakan format biasa (P3), dan bukan format biner (P6).
  • Anda harus memberikan verifikasi bahwa solusi Anda menghasilkan gambar yang benar untuk gambar uji di atas.
  • Semua gambar akan memiliki kedalaman 8 bit.

Bacaan ekstra: halaman wikipedia format Netpbm


Menguji Cuplikan (terima kasih kepada Hobi Calvin untuk ini)


Apakah pustaka gambar yang membuka / menyimpan file ppm diperbolehkan?
Calvin Hobi

@ Calvin'sHobbies Ya
Mego

3
" Balik, gagal, rata-rata " youtube.com/watch?v=D8K90hX4PrE
Luis Mendo

3
Mungkin "Balik, gagal, serius"?
Conor O'Brien

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Kedengarannya seperti pesta anth- oh, tunggu, apa yang diposting Luis.
Addison Crump

Jawaban:


4

Pyth, 30 29 byte

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Program saya mengharapkan semua metadata di baris pertama, dan data gambar baris demi baris di baris setelah di stdin. Untuk membantu, ini adalah program Python kecil untuk mengubah file PPM yang valid menjadi file PPM yang dapat dipahami oleh program saya:

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

Setelah Anda memiliki baris data data baris, operasi sangat sederhana. Pertama saya membaca data gambar ke dalam daftar daftar bilangan bulat ( JrR7.z), kemudian saya membuat versi cermin horizontal dengan mengelompokkan setiap 3 bilangan bulat dan membalikkannya untuk setiap baris ( Km_cd3J). Maka versi yang dicerminkan secara vertikal adalah sederhana _J_K, karena kita bisa membalikkan baris.

Saya mengambil semua matriks itu, meratakan masing-masing ke dalam array 1d dengan .nM, transpos dengan Cuntuk mendapatkan daftar daftar masing-masing komponen pixel, rata-rata dan memotong ke int masing-masing daftar ( ms.Od), dan akhirnya mencetak bergabung dengan baris baru j.

Perhatikan bahwa program saya menghasilkan keluaran dalam format yang berbeda (tapi PPM masih valid). Gambar demo dapat dilihat di album imgur ini .


13

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

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

Alat yang tepat untuk pekerjaan itu.

Harus dijalankan di direktori yang berisi satu file ayang berisi data PPM untuk diubah. Karena nama file ini signifikan, saya telah menambahkan satu byte ke jumlah byte.

Output thumbnail PNG (tidak yakin mengapa ini perlu karena mereka semua tetap sama, tetapi pertanyaannya mengatakan demikian, jadi ...):

pinguin kuintopia Peter minibit

Terima kasih kepada nneonneo karena telah menghemat 2 byte!


3
Saya memerlukan hasil karena orang memiliki kebiasaan buruk memposting solusi tanpa mengujinya. +1 untuk -flop, saya benar-benar ingin terkejut bahwa ini adalah bendera.
Mego

1
Shave off 2 byte dengan menggunakan C=convertdan $Cbukannya 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')

Gambar dimuat sebagai n*m*3 matriks. Kemudian kita balikkan matriks dan ditambahkan ke dirinya sendiri untuk kedua sumbu, dan menulis lagi ke file.


Saya tidak dapat menemukan tempat untuk mengunggah file teks begitu besar, jadi di sini adalah versi PNG:


Omg, saya bahkan tidak tahu Anda bisa menggunakan <imgtag!
flawr

1
Dalam MATLAB R2013b dan yang lebih baru dimungkinkan untuk menggunakan flip, bukan flipdim . Itu akan menghemat 3 byte lebih banyak. Bantuan flipdim sebenarnya mengatakan: "flipdim akan dihapus dalam rilis mendatang. Gunakan FLIP sebagai gantinya."
slvrbld

10

Mathematica, 86 84 byte

Terima kasih kepada DavidC untuk sarannya. (menghemat 2 byte)

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

Parameter pertama dan kedua adalah jalur ke gambar input dan output, masing-masing.


Uji kasus

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

Hasil

(Versi gambar PNG diunggah di bawah)

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

Ini adalah fungsi lambda yang menerima string yang berisi path lengkap ke file PPM dan menimpanya dengan gambar yang diubah. Untuk menyebutnya, tetapkan ke variabel.

Tidak Disatukan:

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

Output contoh:

penguin quintopia peter minibits


4

python 2 + PIL, 268

Sekarang saya secara besar-besaran menggunakan PIL, menggunakan flipping gambar dan alpha blending

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

Gambar yang dihasilkan tersedia di sini


1
Harap sertakan output untuk kasus uji, seperti yang dipersyaratkan oleh aturan.
Mego
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.