Alt Piksel Yakınlaştırma


9

Göreviniz 24 BPP sRGB görüntü almak ve aynı görüntüyü 3 kat büyütülmüş kırmızı, yeşil ve mavi alt piksellere çıkarmaktır. Ortaya çıkan görüntü tamamen saf siyah, kırmızı, yeşil ve mavi piksellerden oluşacaktır.

Kaynak görüntüdeki her piksel, yakınlaştırıldığında, açık veya kapalı olabilen 9 alt piksel düzenlemesi oluşturur (yani ilgili renk veya siyah). Özel düzenleme, şu sırayla üç sütun kırmızı, yeşil ve mavi kullanır:

RGB alt pikselleri

(Bu "piksellerdeki" kenarlıkların yalnızca tanıtım amaçlı olduğunu unutmayın.)

Dokuz alt pikselden her biri yalnızca açık veya kapalı olabileceğinden, giriş görüntüsünü ölçmeniz ve 3 parlaklık seviyesi elde etmek için farklı alt piksel desenleri kullanmanız gerekir.

Resimdeki her alt piksel için:

  • 0-74 renk seviyeleri için tüm alt pikseller siyah olmalıdır.
  • 75-134 renk seviyeleri için, orta alt pikselin ilgili renk ve diğer ikisi siyah olmalıdır.
  • 135-179 renk seviyeleri için, orta alt piksel siyah olmalı ve diğer ikisi ilgili renk olmalıdır
  • 180-255 renk seviyeleri için her üç alt piksel de ilgili renk olmalıdır

Bu seviye aralıklarını seçtim çünkü iyi görünen şeyler bunlar

Bu dönüşümü görüntüdeki her piksele uygulayın ve alt piksel yükseltilmiş görüntünün çıktısını alın.

Tek piksel örnekleri

rgb (40, 130, 175) bu modeli üretecektir:

00B / 0G0 / 00B

rgb (160, 240, 100) bu kalıbı üretir:

RG0 / 0GB / RG0

Tam Görüntü Örnekleri

Mona Lisa Mona lisa alt piksel

Yıldızlı Gece Yıldızlı Gece Subpikselleri

Papağan Papağan Alt Pikselleri

Wikipedia kaynaklı görüntüler

Kurallar ve notlar

  • Giriş ve çıkış, ister gerçek görüntü dosyaları, ister (muhtemelen iç içe) RGB değerleri listeleri olsun, uygun herhangi bir biçimde olabilir.
  • Piksellerin 24BPP ile sRGB renk alanında olduğunu varsayabilirsiniz.

Mutlu golf!


2
İlk açıklama Bayering'den çıkma gibi geliyor. Kısmen alışılmadık 3x3 maskesi nedeniyle değil, esas olarak nicemleme nedeniyle olduğu anlaşılıyor, ancak IMO, Baying'e hala alt piksel yakınlaştırmasından daha yakındır (bu, anti- ad).
Peter Taylor

ilginç bir meydan okuma için teşekkürler .... Bu aslında gerçek hayatta herhangi bir şey için kullanılıyor mu?
Parlak don

Yanıtlar:


4

JavaScript (Düğüm, Chrome, Firefox), 111 bayt

I / O formatı: [R,G,B]değerlerin matrisi .

a=>[...a,...a,...a].map((r,y)=>r.flat().map((_,x)=>a[y/3|0][x/3|0].map(v=>x--%3|511+y%3%2*3104>>v/15&1?0:255)))

Çevrimiçi deneyin! (yalnızca tek bir piksel)

Nasıl?

Tüm eşik değerleri 15'in katlarıdır. Açık karşılaştırma testleri yapmak yerine, her bitin 15 değerlik bir aralığı temsil ettiği bir bit maskesini test etmek biraz daha kısadır (tek bir değere eşlenen en önemli bit hariç).

 bit | range   | top/bottom | middle
-----+---------+------------+--------
  0  |   0- 14 |     off    |   off
  1  |  15- 29 |     off    |   off
  2  |  30- 44 |     off    |   off
  3  |  45- 59 |     off    |   off
  4  |  60- 74 |     off    |   off
  5  |  75- 89 |     off    |    on
  6  |  90-104 |     off    |    on
  7  | 105-119 |     off    |    on
  8  | 120-134 |     off    |    on
  9  | 135-149 |      on    |   off
 10  | 150-164 |      on    |   off
 11  | 165-179 |      on    |   off
 12  | 180-194 |      on    |    on
 13  | 195-209 |      on    |    on
 14  | 210-224 |      on    |    on
 15  | 225-239 |      on    |    on
 16  | 240-254 |      on    |    on
 17  |   255   |      on    |    on

Biz kodlamak kapalı olarak ve üzerinde olarak önde gelen sıfırların sayısını maksimize etmek için.10

Biz:

  • 000000000111111111üst ve alt pikseller için ( ondalık olarak )511
  • 000000111000011111orta piksel için ( ondalık olarak )3615

Yorumlananlar

a =>                      // a[] = input matrix
  [...a, ...a, ...a]      // create a new matrix with 3 times more rows
  .map((r, y) =>          // for each row r[] at position y:
    r.flat()              //   turn [[R,G,B],[R,G,B],...] into [R,G,B,R,G,B,...]
                          //   i.e. create a new list with 3 times more columns
    .map((_, x) =>        //   for each value at position x:
      a[y / 3 | 0]        //     get [R,G,B] from the original matrix
       [x / 3 | 0]        //     for the pixel at position (floor(x/3), floor(y/3))
      .map(v =>           //     for each component v:
        x-- % 3 |         //       1) yield a non-zero value if this is not the component
                          //          that we're interested in at this position
        511 +             //       2) use either 511 for top and bottom pixels
        y % 3 % 2 * 3104  //          or 3615 for the middle pixel (y mod 3 = 1)
        >> v / 15         //          divide v by 15
        & 1               //          and test the corresponding bit
        ?                 //       if either of the above tests is truthy:
          0               //         yield 0
        :                 //       else:
          255             //         yield 255
      )                   //     end of map() over RGB components
    )                     //   end of map() over columns
  )                       // end of map() over rows

Misal

Aşağıdaki kod snippet'i Mona Lisa'nın başını (64x64) işler. Edge'de çalışmaz.


3

Jöle , 27 bayt

<“⁷KṆ‘‘Ḅœ?Ɗo⁹’)×€"3⁼þ¤)ẎZ)Ẏ

Liste (piksel) listelerinin (satırlarının) listesini (resmini) kabul eden monadik bir Bağlantı. Üç tamsayı olmak Her piksel , aynı biçimde sonucu verir ki.[0,255][r, g, b]

Çevrimiçi deneyin! Bu örnek, sol üst pikselin ilk örnek piksel, sağ üst piksel ikinci örnek piksel, sol alt piksel siyah piksel ve sağ alt piksel beyaz olan ikiye iki görüntü alıyor. piksel.

Nasıl?

<“⁷KṆ‘‘Ḅœ?Ɗo⁹’)×€"3⁼þ¤)ẎZ)Ẏ - Link: list of lists of lists of integers, I
                         )  - for each row, R, in I:
                      )     -   for each pixel, P, in R:
              )             -     for each integer, C, in P:
 “⁷KṆ‘                      -       list of code-page indices = [135,75,180]
<                           -       less than -> [C<135,C<75,C<180] 
          Ɗ                 -       last three links as a monad:
      ‘                     -         increment -> [1+(C<135),1+(C<75),1+(C<180)]
       Ḅ                    -         from binary -> 4*(1+(C<135))+2*(1+(C<75))+1+(C<180)
        œ?                  -         permutation at that index of [C<135,C<75,C<180]
                            -         when all permutations sorted lexicographically
                            -       ... a no-op for all but [0,0,1]->[0,1,0]
            ⁹               -       256
           o                -       logical OR  e.g. [0,1,0]->[256,1,256]
             ’              -       decrement               ->[255,0,255]
                     ¤      -     nilad followed by link(s) as a nilad:
                  3         -       three
                    þ       -       table with: (i.e. [1,2,3] . [1,2,3])
                   ⁼        -         equal?    -> [[1,0,0],[0,1,0],[0,0,1]]
                 "          -     zip with:
                €           -       for each:
               ×            -         multiply
                       Ẏ    -   tighten (reduce with concatenation)
                        Z   -   transpose
                          Ẏ - tighten

[[1,0,0]. [0,1,0], [0,0,1]] 'i nerede kodladığını anlamaya çalışıyorum ve şaşkınım.
Parlak don

@donbright 3⁼þ¤gerçekleştirir bir dış ürün [1,2,3]=[1,2,3]elde [[1=1,2=1,3=1],[2=1,2=2,2=3],[3=1,3=2,3=3]]olan [[1,0,0],[0,1,0],[0,0,1]].
Jonathan Allan

2

Wolfram Dili (Mathematica) , 186 bayt

Giriş ve Çıkış RGB değerlerinin listeleridir

(g=#;Flatten[(T=Transpose)@Flatten[T/@{{#,v={0,0,0},v},{v,#2,v},{v,v,#3}}&@@(If[(l=Max@#)<75,v,If[74<l<135,{0,l,0},If[134<l<179,{l,0,l},{l,l,l}]]]&/@#)&/@g[[#]],1]&/@Range[Length@g],1])&

Çevrimiçi deneyin!


Wolfram Dili (Mathematica), 243 bayt

Bu ikinci kod ise işlev girdi olarak bir alan görüntü ve çıkışları görüntü
(insanlar yorum karıştı neden bilmiyorum)

Bu img'yi beslerseniz

resim açıklamasını buraya girin

bu işleve

(i=#;Image[Flatten[(T=Transpose)@Flatten[T/@{{#,v={0,0,0},v},{v,#2,v},{v,v,#3}}&@@(If[(l=Max@#)<75,v,If[74<l<135,{0,l,0},If[134<l<179,{l,0,l},{l,l,l}]]]&/@#)&/@ImageData[i,"Byte"][[#]],1]&/@Range[Last@ImageDimensions@i],1],ColorSpace->"RGB"])&


bu çıktıyı alacaksın

resim açıklamasını buraya girin


2
Bu sabit kodlanmış bir giriş olarak sayılmaz mı?
attinat

Msgstr "Giriş ve çıkış, gerçek görüntü dosyaları olsun, uygun herhangi bir biçimde olabilir ...". Hayır, ibir görüntüdür.
J42161217

@Attinat ile aynı fikirdeyim, bu kodlama gibi görünüyor.
Jonathan Frech

Bazı değişiklikler yaptım ve umarım şimdi her şey açıktır.
J42161217

1

C # (Visual C # Etkileşimli Derleyici) , 157 bayt

n=>{int i=0,j=n[0].Length;for(;;Write(z(0)+",0,0|0,"+z(1)+",0|0,0,"+z(2)+"\n|"[++i%j&1]));int z(int k)=>(((511^i/j%3%2*4064)>>n[i/j/3][i%j][k]/15)&1^1)*255;}

Çıktının RGB'sini yazdırır. Çıktı satırsonu ayrılmıştır ve hizalanmamıştır. Başlangıçta, 1açık ve 0kapalı olmak için bir bit maskesi kullandım , ama sonra Arnauld'un cevabını gördüm ve 0açık ve 1kapalı olarak kullanmanın sayıdaki baytları kaydedebileceğini fark ettim . TIO bağlantısı 4 x 2 piksel örnek "resim" içerir.

Çevrimiçi deneyin!


0

APL + WIN, 102 bayt

Görüntüde göründüğü gibi 24 bit tamsayı olarak 2d piksel matrisini ister

((⍴a)⍴,3 3⍴255*⍳3)×a←(3 1×⍴m)⍴∊⍉((1↓⍴m)/⍳↑⍴m)⊂n←(-+⌿n)⊖n←1 0↓0 75 135 180∘.≤,m←(1 3×⍴m)⍴,⍉(3⍴256)⊤,m←⎕

Çevrimiçi deneyin! Dyalog Classic'in izniyle

Dönüştürülen görüntünün 24 bit tamsayılarından oluşan 2d'lik bir matris çıkarır. Kodun çoğu, giriş ve çıktının biçimlendirmesini yönetiyor.

Örnek: Örnek piksellerden oluşan 2 x 2 resim çekin

Giriş:

2654895 10547300
2654895 10547300

Çıktı:.

0     0 16581375 255 65025        0
0 65025        0   0 65025 16581375
0     0 16581375 255 65025        0
0     0 16581375 255 65025        0
0 65025        0   0 65025 16581375
0     0 16581375 255 65025        0

0

Pas - 281 bayt

fn z(p:Vec<u8>,wh:[usize;2])->Vec<u8>{let mut o=vec![0;wh[0]*wh[1]*27];for m in 0..wh[0]{for n in 0..wh[1]{for i in 1..=3{for j in 0..3{o[m*9+n*wh[0]*27+j*wh[0]*9+i*2]=match p[18+m*3+n*wh[0]*3+3-i]{75..=134=>[0,1,0],135..=179=>[1,0,1],180..=255=>[1,1,1],_=>[0,0,0],}[j]*255;}}}}o}

Bu satır, meydan okumayı karşılayan bir işlevdir, ancak girdisi, görüntünün piksel olarak önceden ayrıştırılmış genişlik ve yüksekliğinin yanı sıra paulbourke.net'te açıklandığı gibi TGA dosya biçimindeki verilerdir . Çıktı için piksel verilerini bayt olarak giriş vektörü verisinin 9 katı büyüklüğünde bir vektörde döndürür.

use std::fs::File;use std::io::{Read,Write};fn main(){let mut p=vec![];let mut o=vec![0u8;18];File::open("i.tga").unwrap().read_to_end(&mut p).unwrap();let mut wh=[0;2];let h=|x|p[x] as usize;let g=|x|(3*x/256) as u8;for i in 0..2{wh[i]=h(12+i*2)+256*h(13+i*2);o[12+i*2]=g(wh[i]*256);o[13+i*2]=g(wh[i]);}let mut f=File::create("o.tga").unwrap();o[2]=2;o[16]=24;o.extend(z(p,wh));f.write(&o).unwrap();}

Bu ikinci satır, i.tga adında bir girdi dosyasını, herhangi bir harici kitaplık kullanmadan ilk satırdan z işlevini çağırarak o.tga adında bir çıktı dosyasına dönüştürebilen bir main () işlevidir. Genişlik / yüksekliğin ayrıştırılmasını, çıktı dosyası için bir başlık ve dosya okuma + yazma işlemlerini gerçekleştirir. Zorluk, toplam 683 için Dosya G / Ç gerektiriyorsa 402 bayt ekleyecektir. Test için yararlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.