Hilbertify một hình ảnh


28

Tôi thích đường cong Hilbert .


Nhiệm vụ của bạn cho thử thách này là chụp một bức ảnh (đúng là một hình vuông trong đó tất cả các cạnh đều có sức mạnh hai pixel) và làm sáng tỏ nó theo từng đường theo hình zig-zagging và quay ngược lại theo đường cong giả-Hilbert .

Làm sáng tỏ

Để làm sáng tỏ, bạn sẽ bắt đầu với pixel ở góc trên bên trái và di chuyển sang phải cho đến khi bạn đến cạnh của hình ảnh. Khi bạn đã chạm vào cạnh của hình ảnh, bạn sẽ di chuyển xuống hàng tiếp theo và bắt đầu di chuyển sang trái cho đến khi bạn chạm vào cạnh một lần nữa. Bạn sẽ tiếp tục làm sáng tỏ hàng bằng cách chuyển đổi hướng mỗi lần để bạn có được một đường cong liên tục. Đây trông giống như một trò chơi rắn

Kết quả làm sáng tỏ phải là một thứ tự các pixel bao gồm mọi pixel chính xác một lần

Chạy lại

Khi bạn đã đặt hàng các pixel, bạn sẽ sắp xếp lại chúng trên một khung vẽ mới có kích thước tương đương theo đường cong của đường cong giả-Hilbert. Đối với một 2**nhình ảnh vuông có kích thước, bạn nên sử dụng lần lặp thứ n của đường cong giả-hilbert. Mỗi pixel sẽ được đặt chính xác vào một vị trí trên khung vẽ mới. Bạn nên đọc lại hình ảnh để điểm ban đầu ở phía trên bên trái (điểm bắt đầu của đường cong con rắn của chúng ta) sẽ vẫn ở đó và điểm ở phía dưới bên phải (điểm cuối của đường cong con rắn của chúng ta) sẽ được đặt ở phía trên bên phải.

Tôi / O

Chương trình hoặc chức năng của bạn sẽ đưa vào một hình ảnh các ràng buộc được chỉ định thông qua các phương thức tiêu chuẩn và xuất ra một hình ảnh khác thông qua các phương thức tiêu chuẩn.

Chấm điểm

Đây là chương trình với ít byte nhất sẽ thắng.

Ví dụ

Đầu vào

Thứ hai

Đầu ra

Đầu ra 1


Đầu vào

Rothko

Đầu ra

Đầu ra 2


Đầu vào

Xáo trộn

Đầu ra

sư tử


Tôi cũng khuyên bạn nên thử nghiệm trên một hình ảnh màu trắng hoặc màu trắng để đảm bảo bạn không thiếu bất kỳ pixel nào.

Hãy bao gồm kết quả của riêng bạn trong câu trả lời của bạn!


Có thể lấy một mảng các giá trị RGB thay vì hình ảnh làm đầu vào không? Còn sản lượng thì sao?
JungHwan tối

@JHM Không bạn không thể. Mặc dù vậy, bạn có thể chọn bất kỳ định dạng hình ảnh nào bạn muốn, vì vậy nếu ngôn ngữ của bạn không có hỗ trợ hình ảnh dựng sẵn, bạn có thể sử dụng tệp .ppm không nén, rất giống với một mảng các giá trị RGB.
Thuật sĩ lúa mì

Câu trả lời:


8

Toán học, 286 273 byte

Image[Array[1,{l=Length@#,l}]~ReplacePart~Thread[#&@@@Split[#&@@@FoldList[Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@#,0},_,#]&,{{1,1},I},Characters@Nest[StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"},"L",Log2@l]]]->Join@@MapAt[Reverse,#,2;;;;2]]]&@*ImageData

Phù! Thử thách nhưng vui!

Giải trình

ImageData

Chuyển đổi một Imagemảng thành các giá trị RGB.

Array[1,{l=Length@#,l}]

Tạo một lbằng lmảng với người đứng đầu 1, nơi llà chiều dài của đầu vào (tức là chiều rộng của hình ảnh).

Sản lượng này {{1[1, 1], 1[1, 2], ..., 1[1, L]}, {1[2, 1], ..., 1[2, L]}, ..., {1[L, 1], ..., 1[L, L]}}( lviết bằng mũ để giảm nhầm lẫn)

StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"}

Một StringReplacechức năng thay thế mọi "L"với "+RF-LFL-FR+""R"với"-LF+RFR+FL-"

Nest[ ... ,"L",Log2@l]

Áp dụng StringReplacehàm cho String "L", Log2[l]lần.

Characters

Chuyển đổi kết quả Stringthành một Listký tự.

Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@#,0},_,#]&

Một hàm không tên mà:

  • Nếu đầu vào thứ hai là "-", nhân phần tử thứ hai của đầu vào thứ nhất với I.
  • Nếu đầu vào thứ hai là "+", chia phần tử thứ hai của đầu vào thứ nhất cho I.
  • Nếu đầu vào thứ hai là "F", hãy tăng đầu vào đầu tiên bằng ReIm(tách phần thực và phần ảo của đầu vào) của đầu vào thứ hai.
Danh sách thư mục [..., {{1,1}, I}, ...]

Bắt đầu với {{1,1},I}, áp dụng tích lũy hàm không tên ở trên, sử dụng từng phần tử của các Listký tự làm đầu vào thứ hai. Mã này mang lại kết quả đầu ra của tất cả các lần lặp.

#&@@@Split[#&@@@ ... ]

Loại bỏ các yếu tố thứ hai của mỗi Listvà xóa các bản sao. (Các bước cho đến thời điểm này tạo ra Listtọa độ của đường cong Hilbert)

Join@@MapAt[Reverse,#,2;;;;2]

Làm sáng tỏ mảng RGB đầu vào (đảo ngược mọi hàng khác và làm phẳng).

Thread[ ... -> ... ]

Tạo Rulecác đối tượng, sao cho phần tử đầu tiên trong đầu vào đầu tiên (tọa độ của đường cong Hilbert) được ghép nối với phần tử đầu tiên của đầu vào thứ hai (hình ảnh được làm sáng), phần tử thứ hai với đầu vào thứ hai, v.v.

... ~ReplacePart~ ...

Áp dụng những thay thế Rulecho Arraybước thứ hai.

Image

Chuyển đổi sang mảng các giá trị RGB thành một Image.

Mẫu vào / ra

Đầu vào:

Trường hợp kiểm tra 1

Đầu ra:

đầu ra


Đầu vào:

Edward và Alphonse Elric từ Nhà giả kim Fullmetal

Đầu ra:

wat

Hàm nghịch đảo ( 266 253 byte)

Image[MapAt[Reverse,Extract[#,#&@@@Split[#&@@@FoldList[Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@b,0},_,#]&,{{1,1},I},Characters@Nest[StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"},"L",Log2[l=Length@#]]]]]~Partition~l,2;;;;2]]&@*ImageData

5

Octave 234 byte

I=imread(input(''));w=rows(I);X=[0,3;1,2];for k=2:log2(w);n=numel(X);X=[X',rot90(X',2)+3*n;X+n,X+2*n];end;for k = 1:3;I(2:2:end,:,k)=fliplr(I(2:2:end,:,k));end[~,S]=sort(X(:));I(S+(0:w^2:2*w^2))=permute(I,[2 1 3]);imwrite(I,input(''))

Tên tệp của hình ảnh đầu vào và đầu ra phải được cung cấp mẫu đầu vào tiêu chuẩn. kích thước của mã không có đầu vào / đầu ra là 194 byte .
Giải trình:

Mẫu cơ sở của các chỉ số là:

X =
  0 3
  1 2

Trong mỗi lần lặp, 4 bản sao từ kết quả của lần lặp trước được thực hiện và một số phép biến đổi được áp dụng cho mỗi bản sao sau đó tất cả các khối được nối để tạo thành kết quả hiện tại.

X =[0,3;1,2];
for k = 2:log2(s)
    n=numel(X);
    X = [X',rot90(X',2)+3*n;X+n,X+2*n];
end

vì vậy chúng tôi có:

block(1,1): X' 
block(1,2): rot90(X',2)+3*n 
block(2,1): X+n
block(2,2): X+2*n

0    1  | 14   15
3    2  | 13   12
--------|--------
4    7  |  8   11
5    6  |  9   10

Các chỉ số Hilbert được sắp xếp và các chỉ mục của các phần tử được sắp xếp trả về:

[~,S]=sort(X(:));

Làm sáng tỏ áp dụng lật tất cả các hàng chẵn:

for k = 1:3
    I(2:2:end,:,k) = fliplr(I(2:2:end,:,k));
end

Reraveling được áp dụng:
-S được lặp lại cho mỗi kênh -
biến đổi được áp dụng kể từ trong dữ liệu Octave sắp xếp cột khôn ngoan

I(S+(0:w^2:2*w^2))=permute(I,[2 1 3]);

Hình ảnh ví dụ:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


Bạn có thể chọn để chương trình của mình hoạt động như một chức năng nếu bạn muốn tránh sử dụng I / O.
Thuật sĩ lúa mì

chức năng + từ khóa kết thúc tiêu thụ nhiều byte hơn!
rahnema1
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.