フリップ、フロップ、平均


24

概要

入力としてプレーンPPM(P3)形式の画像が与えられた場合、画像内の各ピクセルpについて、次の4ピクセルの赤、緑、青のそれぞれを、4ピクセルすべての各チャネルのフロア平均値に置き換えます。

  1. p 自体

  2. p画像が垂直に反転されたときにの位置にあるピクセル

  3. p画像が水平方向に反転されたときにの位置にあるピクセル

  4. p画像が垂直と水平の両方に反転されたときにの位置にあるピクセル

結果の画像をプレーンPPM(P3)形式で出力します。

詳細については、128x128に拡大されたこの8x8画像を検討してください。

ステップ2の例

ましょうp赤いピクセルになります。p(および3つの青いピクセル)の新しい値を計算するには、と3つの青いピクセルの値をp一緒に平均します。

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は、そのは、書式設定について非常に緩んでいる- 任意の空白は値を分離することができます。上記のファイル内のすべての改行をそれぞれ1つのスペースに置き換えても、有効なファイルを保持できます。たとえば、このファイルこのファイルは両方とも有効であり、同じイメージを表します。他の唯一の要件は、ファイルが最後の改行で終わらなければならないことであり、そこにする必要がありwidth*height、以下のRGBトリプレット255


ルール

  • これはであるため、最短の有効なソリューションが優先されます。
  • 上記のPPM形式に従って有効であれば、便利で一貫した方法でフォーマットされたPPMデータを入出力できます。唯一の例外は、バイナリ(P6)形式ではなく、プレーン(P3)形式を使用する必要があることです。
  • ソリューションが上記のテストイメージに対して正しいイメージを出力することを確認する必要があります。
  • すべての画像のビット深度は8ビットです。

補足資料Netpbm形式のウィキペディアのページ


スニペットのテスト(これはCalvinの趣味のおかげです)


ppmファイルを開く/保存する画像ライブラリは許可されていますか?
カルビンの趣味

@ Calvin'sHobbiesはい
Mego

3
フリップ、フロップ、アベレージyoutube.com/watch?v=D8K90hX4PrE
ルイスメンドー

3
たぶん「フリップ、フロップ、それを意味する」?
コナーオブライエン

2
@CᴏɴᴏʀO'Bʀɪᴇɴそれはいくつかのパーティーのように聞こえます-ああ、待って、ルイスが投稿したもの。
アディソンクランプ

回答:


4

Pyth、30 29バイト

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

私のプログラムでは、最初の行にすべてのメタデータがあり、stdinの後の行にある行ごとに画像データが必要です。これを支援するために、これは有効なPPMファイルを私のプログラムが理解できるPPMファイルに変換する小さなPythonプログラムです。

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行を逆にするだけなので、垂直にミラー化されたバージョンは単にです。

これらのすべての行列を取得し、それぞれを1次元配列にフラット化して.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データを含む単一のファイルを含むディレクトリで実行する必要があります。このファイル名は重要なので、バイトカウントに1バイトを追加しました。

PNGサムネイル出力(とにかくすべて同じであるため、なぜこれが必要なのかわかりませんが、質問はそう言うので...):

ペンギン キントピア ピーター ミニビット

2バイトを節約してくれたnneonneoに感謝します!


3
人々はソリューションをテストせずに投稿するという悪い習慣を持っているため、出力が必要です。+1のために-flop、私は本当にそれが旗であることに驚いたいと思います。
メゴ

1
の代わりにC=convertとを使用して、2バイトを削ります。$Calias
-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バージョンを次に示します。


Omg、<imgタグを使用できるとは知りませんでした!
フレイ

1
MATLAB R2013b以降では、flipdimの代わりにflipを使用できます。これにより、さらに3バイト節約できます。flipdimのヘルプには、「flipdimは将来のリリースで削除される予定です。代わりにFLIPを使用してください。」
slvrbld

10

Mathematica、86 84バイト

アドバイスしてくれたDavidCに感謝します。(2バイト保存)

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

1番目と2番目のパラメーターは、それぞれ入力イメージと出力イメージへのパスです。


テストケース

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

python 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
ルールの要求に応じて、テストケースの出力を含めてください。
メゴ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.