Sắp xếp tất cả các pixel của một hình ảnh theo số lần xuất hiện


8

Đầu vào

Tên của một tệp trong định dạng đồ họa raster bạn chọn. Định dạng được chọn phải hỗ trợ ít nhất 8 bit cho mỗi kênh và 3 kênh.

Đầu ra

Một tệp có cùng định dạng, có cùng kích thước và pixel như đầu tiên, nhưng có pixel được nhóm theo thứ tự giảm dần về số lần chúng xảy ra, được sắp xếp từ trái sang phải, từ trên xuống dưới.

  • Nếu các màu nhất định của pixel xuất hiện cùng một số lần, thứ tự của chúng là không xác định.
  • Bạn không được ghi đè lên tệp đầu vào (sử dụng tên tệp khác cho đầu ra).
  • Bất kỳ và tất cả các thư viện xử lý hình ảnh của bên thứ ba đều được cho phép.

Thí dụ

gấu trúc

Sẽ cho đầu ra tương tự như:

pixel được sắp xếp từ hình ảnh gấu trúc

Đặc biệt ở phần dưới của hình ảnh, một số biến thể có thể xảy ra, do sự phá vỡ liên kết khác nhau giữa các màu có tần số bằng nhau.


1
Chúng tôi có thể sử dụng các định dạng tệp khác, như PNM, cho đầu ra không?
FUZxxl 14/03/2015

@EMBLEM Tôi không chắc ý của bạn với thang máy forego grayscale.
FUZxxl

@ MartinBüttner Điểm hay, tôi đã thay đổi nó thành đầu vào và đầu ra có cùng định dạng.
EMBLEM

1
@EMBLEM Tôi nghĩ rằng anh ấy có nghĩa là mối quan hệ của người Hồi giáo như trong hai pixel xuất hiện với cùng tần số. Tôi có thể cho rằng thứ tự của họ là không xác định trong trường hợp này?
FUZxxl 14/03/2015

1
Để rõ ràng về đầu vào / đầu ra ... chúng ta có thể sử dụng một chuỗi (tên tệp), một luồng byte hoặc một Fileđối tượng kiểu phức tạp ...? Điều đó sẽ tạo ra một sự khác biệt lớn trong một số ngôn ngữ.
Geobits 14/03/2015

Câu trả lời:


4

J, 94 81 byte

Một hàm lấy tên của tệp PNG (không có kênh trong suốt) và ghi kết quả vào tên tệp đầu vào được thêm vào bởi "o".

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

đầu vào đầu ra

phương pháp

  • Tạo một danh sách mỗi số màu và số lần xuất hiện của nó
  • Sắp xếp danh sách theo số lần xuất hiện của nó
  • Nhân mỗi số màu bằng nhau, nó xuất hiện
  • Định hình lại danh sách mới về hình dạng của ảnh gốc

bạn có thể lưu một ký tự nếu bạn thực hiện chức năng dyadic và lưu PNG được sắp xếp vào x.
FUZxxl 15/03/2015

@FUZxxl Nó thực sự sẽ tiết kiệm được 3 ký tự nhưng tôi không nghĩ rằng nó phù hợp với đặc điểm kỹ thuật. Tôi cũng có thể lưu hình ảnh vào một tập tin mở rộng 1 chữ cái nhưng điều đó không quá tao nhã.
Randomra 15/03/2015

@FUZxxl Chà, hóa ra có khá nhiều ký tự trong cơ thể của chức năng ...
Randomra 17/03/2015

Tôi không nói J, nhưng trong đặc tả có một chuỗi làm đầu vào. Ở đây tên tập tin đầu vào được mã hóa cứng trong chương trình.
edc65

@ edc65 Trong J nếu bạn xác định hàm thì đối số luôn được ynhân vật truy cập . (Nếu bạn định nghĩa một hàm với hai đối số những người đang truy cập bằng xyvà bạn không thể xác định chức năng với các đối số hơn.)
randomra

6

Toán học, 125 123 byte

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

Điều này xác định một hàm không tên, lấy tên tệp theo bất kỳ định dạng hình ảnh phổ biến nào và ghi kết quả vào một tệp có cùng tên nhưng được đặt trước a. Kết quả trông hơi khác so với OP, vì Mathicala SortByphá vỡ các mối quan hệ theo thứ tự sắp xếp mặc định, do đó, các bit dưới cùng có vô số mối quan hệ xuất hiện trông gọn gàng hơn một chút:

Không phải gấu trúc.

Việc thực hiện chính nó là rất đơn giản:

  • ImageData để có được một lưới các giá trị màu.
  • Join để làm phẳng mảng.
  • Tally để đếm sự xuất hiện của mỗi màu.
  • SortBy[...,-Last@#&] để sắp xếp theo tần số từ cao nhất đến thấp nhất.
  • ConstantArrayJoinđể mở rộng các nàng tiên một lần nữa.
  • ArrayReshapeđể phục hồi hình dạng ban đầu (thu được với Dimensions).
  • Image để chuyển đổi dữ liệu trở lại một đối tượng hình ảnh.

FYI, 22 byte được sử dụng trên tệp I / O. Một phiên bản tương đương có và trả về một đối tượng hình ảnh có đến 103 byte:

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

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)

Thay đổi

Phiên bản ngắn hơn bởi 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)

Chà, ít nhất hãy thử, mặc dù nó đã bị đánh bại.

Nó cực kỳ chậm, Panda đã xử lý vài phút trên máy tính xách tay của tôi.

Lưu với một tên tệp với tên tệp gốc được lặp lại hai lần.

gấu trúc


bạn có thể lưu 32 byte bằng cách sử dụng i=open(raw_input());d=list(i.getdata());i.putdata(sorted(d,key=lambda D:d.count(D)));i.save('o.png'), mặc dù nó rất rất chậm đối với các hình ảnh lớn (gọi list.count trên mỗi pixel).
stokastic

@stokastic Vâng, tôi sẽ thêm nó nhưng tín dụng bạn cho nó. Tôi thích đọc tên cho một biến (những gì nếu người dùng đầu vào một hình ảnh được gọi là o.png?)
PurkkaKoodari

đủ công bằng! :)
stokastic 17/03/2015

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

Các pngmô-đun tôi đã sử dụng .


2
Cảm ơn bạn đã cung cấp một giải pháp tham khảo! Chúng tôi thường đặt những điều này vào bài đăng thử thách để mọi người có thể tìm thấy chúng dễ dàng hơn, nhưng đăng chúng dưới dạng câu trả lời cũng không sao.
FUZxxl

1

C # 413

Hoàn thành chương trình. Truyền tên tệp trên dòng lệnh, đầu ra được lưu ở cùng định dạng với tệp "o".

Không sử dụng một số tính năng gọn gàng của linq, như SelectMany và Enumerable.Range, vì chương trình sẽ sạch hơn nhưng lâu hơn.

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");
}}

Định dạng có thể đọc được của VS2010

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]+".");
    }
}

Có thể tôi sai nhưng tôi nghĩ bạn có thể xóa các dòng mới sau {ký tự
sergiol

Và trước khi }ký tự
sergiol

Tôi đoán một cái gì đó như tio.run/##VY/Ba8IwGMX/ sẽ hoạt động!
sergiol

1

Python 2: 191 byte

Đây là nỗ lực của tôi. Tôi cho rằng tôi có thể tiết kiệm được một số không gian bằng cách sử dụng Counter, nhưng nó không nhỏ như câu trả lời của 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")

Đầu ra từ Panda

Đầu ra từ Panda

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.