Urutkan semua piksel gambar dengan jumlah kemunculannya

8

Memasukkan

Nama file dalam format grafik raster pilihan Anda. Format yang dipilih harus mendukung setidaknya 8 bit per saluran dan 3 saluran.

Keluaran

File dalam format yang sama, dengan dimensi dan piksel yang sama dengan yang pertama, tetapi pikselnya dikelompokkan berdasarkan urutan berapa kali terjadinya, diurutkan dari kiri ke kanan, atas ke bawah.

  • Jika warna-warna piksel tertentu muncul beberapa kali sama, urutannya tidak ditentukan.
  • Anda tidak boleh menimpa file input (gunakan nama file yang berbeda untuk output).
  • Setiap dan semua perpustakaan pemrosesan gambar pihak ketiga diizinkan.

Contoh

panda

Akan memberikan hasil yang mirip dengan:

piksel yang diurutkan dari gambar panda

Terutama di bagian bawah gambar beberapa variasi dapat terjadi, karena ikatan yang berbeda antara warna dengan frekuensi yang sama.

LAMBANG
sumber
1
Bisakah kita menggunakan format file lain, seperti PNM, untuk hasilnya?
FUZxxl
@EMBLEM Saya tidak yakin apa yang Anda maksud dengan "lupakan grayscale."
FUZxxl
@ MartinBüttner Poin bagus, saya telah mengubahnya menjadi input dan output dengan format yang sama.
EMBLEM
1
@EMBLEM Saya pikir maksudnya "ikatan" seperti pada "dua piksel terjadi dengan frekuensi yang sama." Dapatkah saya berasumsi bahwa pesanan mereka tidak ditentukan dalam kasus ini?
FUZxxl
1
Agar jelas pada input / output ... bisakah kita menggunakan string (nama file), aliran byte, atau Fileobjek tipe- kompleks ...? Itu akan membuat perbedaan besar dalam beberapa bahasa.
Geobits

Jawaban:

4

J, 94 81 byte

Sebuah fungsi mengambil nama file PNG (tanpa saluran transparansi) dan menulis hasilnya dalam nama file input yang diawali dengan "o".

f=.3 :0
load'graphics/png'
(($a)$#/|:\:~(#,{.)/.~,a=.readpng y)writepng'o',y
)

memasukkan keluaran

metode

  • Buat daftar setiap nomor warna dan jumlah penampilannya
  • Urutkan daftar berdasarkan jumlah penampilannya
  • Gandakan setiap angka warna sama dengan penampilannya
  • Bentuk kembali daftar baru dengan bentuk gambar asli
randomra
sumber
Anda dapat menyimpan satu karakter jika Anda membuat fungsi diad dan menyimpan PNG yang diurutkan x.
FUZxxl
@ FuZxxl Sebenarnya akan menghemat 3 karakter tapi saya tidak berpikir itu sesuai dengan spesifikasi. Saya juga bisa menyimpan gambar ke file tanpa ekstensi 1 huruf tapi itu tidak terlalu elegan.
randomra
@ Fuzxxl Nah, ternyata ada beberapa karakter tambahan di tubuh fungsi ...
randomra
Saya tidak berbicara J, tetapi dalam spesifikasi ada string sebagai input. Di sini nama file input dimasukkan ke dalam hardcode dalam program.
edc65
@ edc65 Dalam J jika Anda mendefinisikan suatu fungsi, argumennya selalu diakses oleh ykarakter. (Jika Anda mendefinisikan fungsi dengan dua argumen yang diakses oleh xdan ydan Anda tidak dapat mendefinisikan fungsi dengan lebih banyak argumen.)
randomra
6

Mathematica, 125 123 byte

Export["a"<>#,i=ImageData@Import@#;Image@ArrayReshape[Join@@ConstantArray@@@SortBy[Tally[Join@@i],-Last@#&],Dimensions@i]]&

Ini mendefinisikan fungsi yang tidak disebutkan namanya yang mengambil nama file dalam format gambar umum dan menulis hasilnya ke file dengan nama yang sama tetapi diawali dengan a. Hasilnya terlihat sedikit berbeda dari OP, karena Mathematica SortBymemutus ikatan dengan urutan urutan default, sehingga bit bawah tempat banyak ikatan terlihat terlihat lebih rapi:

Bukan panda.

Implementasinya sendiri sangat mudah:

  • ImageData untuk mendapatkan kisi nilai warna.
  • Join untuk meratakan array.
  • Tally untuk menghitung kemunculan setiap warna.
  • SortBy[...,-Last@#&] untuk mengurutkan berdasarkan frekuensi dari tertinggi ke terendah.
  • ConstantArraydan Joinuntuk memperluas penghitungan lagi.
  • ArrayReshapeuntuk memulihkan bentuk gambar asli (diperoleh dengan Dimensions).
  • Image untuk mengubah data kembali ke objek gambar.

FYI, 22 byte digunakan pada file I / O. Versi setara yang mengambil dan mengembalikan objek gambar muncul pada 103 byte:

(i=ImageData@#;Image@ArrayReshape[Join@@ConstantArray@@@SortBy[Tally[Join@@i],-Last@#&],Dimensions@i])&
Martin Ender
sumber
4

Python2 / PIL, 244 226 225 223 222 202 186 182 170 159

from PIL.Image import*
s=raw_input();i=open(s);g=list(i.getdata());i.putdata(sum([[c[1]]*-c[0]for c in sorted((-g.count(r),r)for r in set(g))],[]));i.save(2*s)

Changelog

Versi lebih pendek oleh stokastic , 123

from PIL.Image import*
s=raw_input();i=open(s);d=list(i.getdata());i.putdata(sorted(d,key=lambda D:d.count(D)));i.save(2*s)

Yah, setidaknya mari kita coba, meskipun sudah dikalahkan.

Ini sangat lambat, Panda diproses selama beberapa menit di laptop saya.

Menghemat dengan nama file dengan nama file asli diulang dua kali.

panda

PurkkaKoodari
sumber
Anda dapat menyimpan 32 byte dengan menggunakan i=open(raw_input());d=list(i.getdata());i.putdata(sorted(d,key=lambda D:d.count(D)));i.save('o.png'), meskipun sangat sangat lambat untuk gambar besar (panggilan list.count pada setiap piksel).
stokastic
@stokastic Baiklah, saya akan menambahkannya, tetapi saya menghargai itu. Saya lebih suka membaca nama ke variabel (bagaimana jika pengguna memasukkan gambar yang disebut o.png?)
PurkkaKoodari
cukup adil! :)
stokastic
2

Python, 1197 byte

# -*- coding: utf-8 -*-
from __future__ import division
from collections import Counter
import png
from sys import argv,exit
script,file_name,output_file_name=argv
def group(s,n):
    return zip(*[iter(s)]*n)
def flatten(list_of_lists):
    result=[]
    for lst in list_of_lists:
        result.extend(lst)
    return result
def group_list(old_list,tuples_per_list):
    new_list=[]
    i=1
    appended_row=[]
    for item in old_list:
        appended_row.extend(flatten([item]))
        if i==tuples_per_list:
            new_list.append(appended_row)
            i=1
            appended_row=[]
        else:
            i+=1
    return new_list
input_image=png.Reader(file_name)
image_data=input_image.read()
width=image_data[0]
height=image_data[1]
pixels=list(image_data[2])
if image_data[3]["alpha"]:
    ints_per_colour=4
elif image_data[3]["greyscale"]:
    ints_per_colour=2
else:
    ints_per_colour=3
colours=Counter(colour for row in pixels for colour in group(row,ints_per_colour)).most_common()
pixel_list=flatten([element]*count for element,count in colours)
ordered_rows=group_list(pixel_list,width)
f=open(output_file_name,"wb")
png_object=png.Writer(width,height,greyscale=image_data[3]["greyscale"],alpha=image_data[3]["alpha"])
png_object.write(f,ordered_rows)
f.close()

The pngmodul I digunakan .

LAMBANG
sumber
2
Terima kasih telah memberikan solusi referensi! Kami biasanya memasukkan ini ke pos tantangan itu sendiri sehingga orang dapat menemukannya dengan lebih mudah, tetapi mempostingnya sebagai jawaban juga tidak apa-apa.
FUZxxl
1

C # 413

Program lengkap. Lulus nama file pada baris perintah, output disimpan dalam format yang sama dengan file "o".

Tidak menggunakan beberapa fitur linq yang rapi, seperti SelectMany dan Enumerable.Range, karena programnya akan lebih bersih tetapi lebih lama.

using System.Collections.Generic;using System.Linq;using System.Drawing;
class P{
static void Main(string[]a){
var d=new Dictionary<Color,int>();var b=new Bitmap(a[0]);
int n,x,y,w=b.Width,h=b.Height;
for (x=w;x-->0;)for(y=h;y-->0;){var p=b.GetPixel(x,y);d[p]=d.ContainsKey(p)?d[p]+1:1;}
y=h;foreach(var q in d.OrderBy(v=>v.Value)){for(n=q.Value;n-->0;){
if(x<=0){x=w;--y;}b.SetPixel(--x, y, q.Key);}}b.Save("o");
}}

Formating courtesy of VS2010 yang dapat dibaca

using System.Collections.Generic;
using System.Linq;
using System.Drawing;

class P
{
    static void Main(string[] a)
    {
        var d = new Dictionary<Color, int>();
        var b = new Bitmap(a[0]);
        int n,x,y,w = b.Width, h=b.Height;

        for (x = w; x-- > 0;)    
            for (y = h; y-- > 0;)
            {
                var p = b.GetPixel(x, y);
                d[p] = d.ContainsKey(p) ? d[p]+1 : 1;
            }
        y = h;
        foreach (var q in d.OrderBy(v => v.Value))
        {
            for (n = q.Value; n-- > 0; )
            {
                if (x <= 0)
                {
                    x = w;
                    --y;
                 }
                 b.SetPixel(--x, y, q.Key);
            }
        }
        b.Save(a[0]+".");
    }
}
edc65
sumber
Mungkin saya salah tapi saya pikir Anda dapat menghapus baris baru setelah {karakter
sergiol
Dan sebelum }karakter
sergiol
Saya menanyakan sesuatu seperti tio.run/##VY/Ba8IwGMX/… akan bekerja!
sergiol
1

Python 2: 191 byte

Inilah usaha saya. Saya pikir saya mungkin bisa menghemat ruang dengan menggunakan Counter, tetapi tidak berakhir sekecil jawaban Pietu1998.

from collections import Counter
from PIL import Image
i=Image.open(raw_input())
s=reduce(lambda x,y:x+y,map(lambda(a,b):[a]*b,Counter(i.getdata()).most_common()))
i.putdata(s)
i.save("o.png")

Output dari Panda

Output dari Panda

danmcardle
sumber