Flip It, Flop It, значит это


24

обзор

Для входного изображения в формате простого PPM (P3) для каждого пикселя pв изображении замените каждый из следующих 4 пикселей, красный, зеленый и синий, средним значением соответствующих каналов всех 4 пикселей:

  1. p сам

  2. Пиксель, расположенный на pместе, когда изображение перевернуто вертикально

  3. Пиксель, расположенный в том pместе, где изображение перевернуто горизонтально

  4. Пиксель, расположенный на pместе, когда изображение переворачивается как вертикально, так и горизонтально

Выведите полученное изображение в формате обычного PPM (P3).

Для дальнейшего объяснения рассмотрим это изображение 8x8, увеличенное до 128x128:

пример шага 2

Позвольте pбыть красным пикселем. Чтобы вычислить новое значение для p(и 3 синих пикселя), значения pи 3 синих пикселя будут усреднены вместе:

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

Примеры

PPM: вход , выход


PPM: вход , выход


PPM: вход , выход


PPM: вход , выход


Реализация эталона

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

Эта программа принимает одно имя файла в качестве входных данных, форматируется как выходные данные pngtopnm <pngfile> -plainи выводит одну строку данных PPM, разделенных пробелами.


Краткое описание формата P3

Открытый текстовый файл PPM pngtopnm <pngfile> -plainбудет выглядеть так:

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>

<...>

Это формат, используемый в примерах файлов ввода и вывода. Однако PNM очень плохо разбирается в своем форматировании - любой пробел может разделять значения. Вы можете заменить все символы новой строки в приведенном выше файле на один пробел, и при этом иметь действительный файл. Например, этот файл и этот файл являются действительными и представляют одно и то же изображение. Единственными другими требованиями являются то, что файл должен заканчиваться завершающим символом новой строки, и после него должны быть width*heightтройки RGB 255.


правила

  • Это , поэтому выигрывает самое короткое из возможных решений.
  • Вы можете вводить и выводить данные PPM, отформатированные любым удобным и согласованным способом, при условии, что они действительны в соответствии с форматом PPM, описанным выше. Единственным исключением является то, что вы должны использовать простой (P3) формат, а не двоичный (P6) формат.
  • Вы должны убедиться, что ваше решение выводит правильные изображения для указанных тестовых изображений.
  • Все изображения будут иметь битовую глубину 8 бит.

Дополнительное чтение: страница википедии в формате Netpbm


Тестирующий сниппет (спасибо Хелвину за это)


Разрешены ли библиотеки изображений, которые открывают / сохраняют ppm-файлы?
Увлечения Кэлвина

@ Calvin'sHobbies Да
Mego

3
« Переверни, провали, усредни
Луис Мендо

3
Может быть, «Переверни, проваливай, имей в виду»?
Конор О'Брайен

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Звучит как вечеринка, подождите, что отправил Луис.
Эддисон Крамп

Ответы:


4

Pyth, 30 29 байт

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Моя программа ожидает все метаданные в первой строке, а данные изображения построчно в строках после ввода в stdin. Чтобы помочь, это небольшая программа на Python для преобразования любого действительного файла PPM в файл PPM, который моя программа может понять:

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

Если у вас есть данные изображения строка за строкой, операции действительно просты. Сначала я считываю данные изображения в список списков целых чисел ( JrR7.z), затем создаю версию с горизонтальным зеркальным отображением, группируя каждые 3 целых числа и обращая их в обратном порядке для каждой строки ( Km_cd3J). Тогда версии с вертикальным зеркальным отображением просты _J_K, так как мы можем просто перевернуть строки.

Я беру все эти матрицы, объединяю каждую из них в одномерный массив с помощью .nM, транспонирую с, Cчтобы получить список списков каждого из компонентов пикселя, усредняю ​​и усекаю до int каждого из этих списков ( ms.Od), и, наконец, печатаю, присоединяя новые строки j.

Обратите внимание, что моя программа генерирует вывод в другом формате (но все еще действительный PPM). Демо-изображения можно посмотреть в этом альбоме imgur .


13

Bash (+ ImageMagick), 64 + 1 = 65 байт

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

Правильный инструмент для работы.

Должен выполняться в каталоге, содержащем один файл a, содержащий данные PPM для преобразования. Поскольку это имя файла является значительным, я добавил один байт к числу байтов.

Вывод миниатюр PNG (не уверен, почему это необходимо, потому что они все равно одинаковы, но вопрос так говорит, так что ...):

пингвин quintopia Питер minibits

Спасибо nneonneo за сохранение 2 байта!


3
Мне нужны результаты, потому что люди имеют плохую привычку публиковать решения без их тестирования. +1 -flop, я очень хочу удивляться, что это флаг.
Мего

1
Сбрей 2 байта, используя C=convertи $Cвместо alias.
nneonneo

12

Matlab, 106 82 80 байт

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

Изображение загружается в виде n*m*3матрицы. Затем мы переворачиваем матрицу и добавляем к себе обе оси и снова записываем ее в файл.


Я не смог найти место для загрузки таких текстовых файлов, поэтому вот версии PNG:


Боже, я даже не знал, что вы можете использовать <imgтеги!
flawr

1
В MATLAB R2013b и новее можно использовать flip вместо flipdim . Это должно сэкономить вам еще 3 байта. Справка flipdim на самом деле гласит: «flipdim будет удален в следующем выпуске. Вместо этого используйте FLIP».
slvrbld

10

Mathematica, 86 84 байта

Спасибо DavidC за совет. (сохраняет 2 байта)

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

Первый и второй параметры являются путями к входному и выходному изображениям соответственно.


Контрольные примеры

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

Результат

(PNG-версии изображений загружены ниже)

Import["penguin2.pnm"]

Import["quintopia2.pnm"]

Import["peter2.pnm"]


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

4

Юлия, 157 байт

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

Это лямбда-функция, которая принимает строку, содержащую полный путь к файлу PPM, и перезаписывает ее преобразованным изображением. Чтобы вызвать его, присвойте его переменной.

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

Пример выходов:

пингвин quintopia Питер minibits


4

питон 2 + PIL, 268

Теперь я широко использую PIL, используя переворачивание изображения и альфа-смешение

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

Результирующие изображения доступны здесь


1
Пожалуйста, включите выходные данные для тестовых случаев, как требуется правилами.
Мего
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.