Переверніть його, сплітайте, майте на увазі


24

Огляд

Надавши зображення в простому форматі PPM (P3) як вхідне, для кожного пікселя pна зображенні замініть кожен із наступних 4 пікселів червоним, зеленим та синім кольором на середнє значення відповідних каналів усіх 4 пікселів:

  1. p себе

  2. Піксель, розташований у pмісці, коли зображення перевернуто вертикально

  3. Піксель, розташований у pмісці розташування, коли зображення перевертається горизонтально

  4. Піксель, розташований у pмісці розташування, коли зображення перевертається як вертикально, так і горизонтально

Виведіть отримане зображення у звичайному форматі PPM (P3).

Для подальшого пояснення розглянемо це зображення 8х8, збільшене до 128х128:

крок 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
" Переверніть, промацуйте, середнє значення " youtube.com/watch?v=D8K90hX4PrE
Луїс Мендо

3
Можливо, "Переверніть, промацуйте, значить"?
Conor O'Brien

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, оскільки ми можемо просто повернути рядки.

Я беру всі ці матриці, вирівнюю кожну з них в 1d масив .nM, переміщую з, Cщоб отримати список списків кожного з піксельних компонентів, середній і усікаю, щоб вставити кожен із цих списків ( 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 (не впевнені, для чого це потрібно, оскільки вони все одно однакові, але питання говорить так, тож ...):

пінгвін кінтопія пітер мінібіти

Завдяки nneonneo за збереження 2 байтів!


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

1
Поголіть 2 байти за допомогою C=convertта $Cзамість цього alias.
nneonneo

12

Матлаб, 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:


Omg, я навіть не знав, що ти можеш використовувати <imgтеги!
невдача

1
У MATLAB R2013b та новіших версіях можна використовувати flip замість flipdim . Це має заощадити ще 3 байти. Довідка flipdim насправді говорить: "flipdim буде видалений у майбутньому випуску. Замість цього використовуйте FLIP."
slvrbld

10

Математика, 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, і перезаписує його перетвореним зображенням. Щоб викликати його, призначте його змінній.

Безголівки:

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

Приклади виходів:

пінгвін кінтопія пітер мінібіти


4

пітон 2 + ПІЛ, 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
Будь ласка, включіть результати для тестових випадків, як того вимагають правила.
Mego
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.