Sayılarla Boya (programlama kullanarak, sayıları değil)


56

Göreviniz siyah beyaz anahatlı bir görüntü alan (aşağıdaki örnek resimlerdir) ve onu renkle dolduran bir program oluşturmaktır. Her bir bölgeyi nasıl ayırdığınız ve hangi rengiyle doldurmanız gerektiği size bağlıdır (bir RNG bile kullanabilirsiniz).

Örneğin:

örneğin 1 çıktı

Gördüğünüz gibi MS Paint söz konusu olduğunda açıkça üstün bir kalibre sanatçısıyım.


puanlama

Bu bir popülerlik yarışmasıdır, bu nedenle en net oyları içeren cevap kazanır. Seçmenlerin cevaplarını yargılamaya teşvik etmesi

  • Giriş kriteri: beyaz / açık gri arkaplan ve siyah / koyu gri anahatlardan oluşan herhangi bir görüntü
  • Renklendirme ne kadar iyi yapılır; yani az veya hiç alan yukarıdakilerin aksine beyazdır (örneğin, bulutlar için beyaz kullanmayı düşünmüyorsanız)
  • Belirli bölümlerde kullanılan renklerin özelleştirilebilirliği
  • Sistem bir dizi farklı görüntüde ne kadar iyi çalışır (değişken ayrıntıda)
  • Programınızın resim başına ne kadar sürdüğünü kaydedin. Kod golf oynamak olmayabilir, ancak daha kısa, daha hızlı ve daha verimli kod daha iyi olarak kabul edilmelidir.
  • Yeni görüntüyü ekrana veya bir dosyaya vermelidir (cevapta gösterilebilmesi için 2 MB'den büyük olmamalıdır)
  • Lütfen neden bu görüntü türüne çıktı seçtiğinizi doğrulayın ve kodunuzun işleyişini yorumlayın / açıklayın.
  • Kullanılan rengin uygulanabilir olduğu şekle uygulanabilirliği (gerçekçi renk şeması yani çimler yeşil, ahşap çitler kahverengi vb.)

    “Her bir alanı rastgele renklendirebilirim, ancak“ çit ”i tanımlayıp benzer şekilde renkli hale getirebilirsem, bu daha çok hak eden bir şey.” - NathanMerrill

Bunun bir popülerlik yarışması olduğunu görünce , isteğe bağlı olarak aşağıdakilerle karar verebilirsiniz:

  • Genel itiraz (görüntünün ne kadar iyi göründüğü)
  • Sanatsal yetenek; Gölgelendirme veya suluboya tarzında boyama vb.

Genel olarak, oruçlu program ve en yüksek oylama ile en yüksek kalitede en düşük çıktılı görüntü (dosya boyutu) kazanacaktır.

Kullanılması gerektiğini düşündüğünüz başka yargılayıcı şartnameleriniz varsa, lütfen bunları bu yayının yorumlarında önerin.


Örnekler

Hiçbir şeye sahip değilim; Tüm örnek resimler, yaratıcı bir ortak kullanım lisansına aittir.

örnek 1 siyah / beyaz Kaynak: https://pixabay.com/ro/stejar-arbore-schi%C5%A3%C4%83-natura-303890/ örnek 2 siyah / beyaz Kaynak: http://www.freestockphotos.biz/stockphoto/10665 Örnek 3 siyah / beyaz Kaynak: http: http: / /crystal-rose1981.deviantart.com/art/Dragon-Tattoo-Outline-167320011 Örnek 4 siyah / beyaz Kaynak: http://jaclynonacloudlines.deviantart.com/art/Gryphon-Lines-PF-273195317 Örnek 5 siyah / beyaz Kaynak: http://captaincyprus.deviantart.com / art / Dragon-OutLine-331748686 Örnek 6 siyah / beyaz Kaynak: http://electric-meat.deviantart.com/art/A-Heroes-Farewell-280271639 Örnek 7 siyah / beyaz Kaynak: http://movillefacepalmplz.deviantart.com/art/Background-The-Pumpkin -Çiftlik-of-the Good-eski-Gün-342865938


EDIT: Siyah / beyaz olmayan piksellere ve siyah / beyaz yerine gri içerebilecek bazı görüntülere neden olan çizgilerdeki kenar yumuşatma nedeniyle, bununla başa çıkmak için bir bonus meydan okuması yapabilirsiniz. Bence bu yeterince kolay olmalı.


4
Herkese: Lütfen bunu bir "sanat yarışması" olarak düşürmeyin / kapatmayın - daha fazlası var
edc65

16
PPCG'ye Hoşgeldiniz! Sadece ilk gönderinizin bir meydan okuma olmasını değil, yalnızca bir pop-con meydan okumasını değil, hepsinden öte sanatsal bir meydan okumayı da cesaretlendirdiğiniz için sizi alkışlıyorum. İyi şanslar, sana en iyisini diliyorum, ve etrafta dolaşırsan, çok uzaklara gideceğini düşünüyorum.
AdmBorkBork

4
@OliverGriffin Kapanmaya karşı oy kullanıyorum ve ayrıca sizin için bağladığınız resimleri ekledim. İsterseniz yorumları kaldırabilirsiniz.
Addison Crump,

2
Sonunda muhtemelen taşma olmayacak bir yaklaşım buldum, ancak şimdi yavaş yavaş çalışıyor.
SuperJedi224,

4
Sorunuzu yeniden açmak için oy kullandım ve -1'i +1 olarak değiştirdim. İyi iş düzenleme ve ek bilgi ekleme. Ayrıca, topluluk eleştirisine bu kadar açık davrandığınız için sizi alkışlıyorum. PPCG'ye Hoşgeldiniz! Umarım tadını çıkarırsın.
Zach Gates,

Yanıtlar:


30

Spektral airbrushing (Python, PIL, scipy)

Bu renkli saçmalık üretmek için sofistike bir matematik algoritması kullanır. Algoritma Google’ın PageRank algoritmasıyla ilgilidir, ancak web sayfaları yerine pikseller için geçerlidir.

Bu yaklaşımı aldım, çünkü taşkın dolgu temelli yöntemlerin aksine, tamamen siyah çizgilerle kaplı olmayan şekillerin olduğu tavuk ve ağaç gibi görüntülerle başa çıkabileceğini düşündüm. Gördüğünüz gibi, bir tür eserler, aynı zamanda gökyüzünün farklı bölgelerinde farklı renklerde renklenme eğilimindedir.

Matematiksel düşünceye göre: Yaptığı şey aslında görüntüdeki süre piksellerinin bitişik grafiğini oluşturmak ve ardından Laplacian grafiğinin ilk 25 özvektörünü bulmak. (Oldukça değil, çünkü karanlık pikselleri içeriyoruz, bağlantılarını sadece daha düşük bir ağırlıkla veriyoruz. Çıktı görüntüsünün RGB bileşenlerini oluşturmak için ters özdeğerleriyle ağırlıklandırılmış rasgele doğrusal bir kombinasyon.

Hesaplama zamanının menfaatlerinde, tüm bunları yapmadan önce görüntü küçültülür, daha sonra tekrar büyütülür ve sonra orijinal görüntü ile çarpılır. Yine de, hızlı bir şekilde çalışmıyor, giriş görüntüsüne bağlı olarak makinemde yaklaşık 2 ila 10 dakika sürüyor, ancak nedense tavuk 17 dakika sürdü.

Her bir özvektörün rengini ve yoğunluğunu kontrol edebileceğiniz etkileşimli bir uygulama yaparak bu fikri yararlı bir şeye dönüştürmek aslında mümkün olabilir. Bu şekilde, gökyüzünü farklı bölümlere ayıranları yok edebilir ve görüntünün alakalı özelliklerini yakalayanları solabilirsiniz. Ama bunu kendim yapacak bir planım yok :)

İşte çıktı görüntüleri:

görüntü tanımını buraya girin

görüntü tanımını buraya girin

görüntü tanımını buraya girin

görüntü tanımını buraya girin

görüntü tanımını buraya girin

(Balkabaklarında o kadar iyi çalışmadı, bu yüzden bunu ihmal ediyorum.)

Ve işte kod:

import sys
from PIL import Image
import numpy as np
import scipy.sparse as sp
import scipy.sparse.linalg as spl
import os
import time

start_time = time.time()

filename = sys.argv[1]
img = Image.open(filename)
orig_w, orig_h = img.size

# convert to monochrome and remove any alpha channel
# (quite a few of the inputs are transparent pngs)
img = img.convert('LA')
pix = img.load()
for x in range(orig_w):
    for y in range(orig_h):
        l, a = pix[x,y]
        l = (255-a) + a*l/255
        a = 255
        pix[x,y] = l,a
img = img.convert('L')

orig_img = img.copy()

# resize to 300 pixels wide - you can get better results by increasing this,
# but it takes ages to run
orig_w, orig_h = img.size
print "original size:", str(orig_w)+ ', ' + str(orig_h)
new_w = 300
img = img.resize((new_w, orig_h*new_w/orig_w), Image.ANTIALIAS)

pix = img.load()
w, h = img.size
print "resizing to", str(w)+', '+str(h)

def coords_to_index(x, y):
    return x*h+y

def index_to_coords(i):
    return (int(i/h), i%h)

print "creating matrix"

A = sp.lil_matrix((w*h,w*h))

def setlink(p1x, p1y, p2x, p2y):
    i = coords_to_index(p1x,p1y)
    j = coords_to_index(p2x,p2y)
    ci = pix[p1x,p1y]/255.
    cj = pix[p2x,p2y]/255.
    if ci*cj > 0.9:
        c = 1
    else:
        c =  0.01
    A[i,j] = c
    return c

for x in range(w):
    for y in range(h):
        d = 0.
        if x>0:
            d += setlink(x,y,x-1,y)
        if x<w-1:
            d += setlink(x,y,x+1,y)
        if y>0:
            d += setlink(x,y,x,y-1)
        if y<h-1:
            d += setlink(x,y,x,y+1)
        i = coords_to_index(x,y)
        A[i,i] = -d

A = A.tocsr()

# the greater this number, the more details it will pick up on. But it increases
# execution time, and after a while increasing it won't make much difference
n_eigs = 25

print "finding eigenvectors (this may take a while)"
L, V = spl.eigsh(A, k=n_eigs, tol=1e-12, which='LA')

print "found eigenvalues", L

out = Image.new("RGB", (w, h), "white")
out_pix = out.load()

print "painting picutre"

V = np.real(V)
n = np.size(V,0)
R = np.zeros(n)
G = np.zeros(n)
B = np.zeros(n)

for k in range(n_eigs-1):
    weight = 1./L[k]
    R = R + V[:,k]*np.random.randn()*weight
    G = G + V[:,k]*np.random.randn()*weight
    B = B + V[:,k]*np.random.randn()*weight

R -= np.min(R)
G -= np.min(G)
B -= np.min(B)
R /= np.max(R)
G /= np.max(G)
B /= np.max(B)

for x in range(w):
    for y in range(h):
        i = coords_to_index(x,y)
        r = R[i]
        g = G[i]
        b = B[i]
        pixval = tuple(int(v*256) for v in (r,g,b))
        out_pix[x,y] = pixval

out = out.resize((orig_w, orig_h), Image.ANTIALIAS)
out_pix = out.load()
orig_pix = orig_img.load()

for x in range(orig_w):
    for y in range(orig_h):
        r,g,b = out_pix[x,y]
        i = orig_pix[x,y]/255.
        out_pix[x,y] = tuple(int(v*i) for v in (r,g,b))

fname, extension = os.path.splitext(filename)
out.save('out_' + fname + '.png')

print("completed in %s seconds" % (time.time() - start_time))

4
Bu gerçekten havalı. Muhtemelen şimdiye kadar favorilerimden biri. Antialiasing ve açık uçlu alanlarla başa çıkmak için mükemmel bir iş çıkardın ve sonunda Link'de renkli biri çıktı! (Bunu bekliyordum: - P masaüstüne kaydetme kaydedildi ) Eski İngilizce öğretmenimin bu konuda statik bir görüntü olarak ne söyleyeceğini merak ediyorum ... "Kalbinin iki tarafını gösterir, bir tarafta huzur var ve diğerinde bu barışı sağlamak için gerekli mücadele var ". Zelda oyunlarının efsanesine olan aşkım hakkında yeterince ... Bu çok uzun sürmesi çok yazık. Ortaya çıkan dosyalar ne kadar büyüktü? Ps Love görüntüleri 4 & 5
OliverGriffin

2
@donbright özvektörleri anlayabilen bir üçüncü sınıf öğrencisi gerçekten çok parlak bir çocuk olurdu - algoritmayı bu seviyede açıklamanın benim için mümkün olduğundan emin değilim. Ama yine de deneyeyim: Resmi sert bir metal kağıda bastırdığımızı hayal edin. Sonra tüm siyah çizgileri dikkatlice kesiyoruz ve onları elastik gibi çok daha esnek bir şeyle değiştiriyoruz. Böylece beyaz kısımlar metal plakalar ve siyah kısımlar esnek kumaştır. Ardından her şeyi ipte havaya asıyoruz, bu yüzden hareket etmek serbest. Şimdi metal plakalara dokunursak titreşecekler ...
Nathaniel

2
@ donbright (devam) ... Metal plakalara nasıl çarptığınıza bağlı olarak, farklı şekillerde titrer. Belki de bazen metal parçalardan sadece biri titreşir, diğerlerini titreştirir, ancak diğer zamanlarda (elastik ile bağlandıkları için), bir plakaya vurmak diğerine de hareket etmeye başlar. Bu farklı titreşim yollarına titreşim modları denir . Bu program, bu metal plakanın bazı titreşim modlarını simüle eder, ancak ses üretmek yerine, hangi rengin çizileceğini bulmak için bunları kullanır.
Nathaniel,

2
@donbright Ayrıca metal plakaların titreşimlerini görselleştirmek hakkında daha fazla bilgi için burada görebilirsiniz .
Nathaniel,

2
@donbright (bu daha teknik açıklama da sizi biraz kaybedebilir, ancak bu açıklama çalışıyor, çünkü bir plakanın titreşim modları bir özvektör hesaplaması kullanılarak da hesaplanıyor. pek emin değilim.)
Nathaniel,

25

Python 2 + PIL de ilk boyama kitabım

import sys, random
from PIL import Image

def is_whitish(color):
    return sum(color)>500

def get_zone(image, point, mask):
    pixels = image.load()
    w, h = image.size
    s = [point]
    while s:
        x, y = current = s.pop()
        mask[current] = 255
        yield current
        s+=[(i,j) for (i,j) in [(x,y-1),(x,y+1),(x-1,y),(x+1,y)] if 0<=i<w and 0<=j<h and mask[i,j]==0 and is_whitish(pixels[i,j])]

def get_zones(image):
    pixels = I.load()
    mask = Image.new('1',image.size).load()
    w,h = image.size
    for y in range(h):
        for x in range(w):
            p = x,y
            if mask[p]==0 and is_whitish(pixels[p]):
                yield get_zone(image, p, mask)



def apply_gradient(image, mincolor, maxcolor, points):
    minx = min([x for x,y in points])
    maxx = max([x for x,y in points])
    miny = min([y for x,y in points])
    maxy = max([y for x,y in points])
    if minx == maxx or miny==maxy:
        return
    diffx, diffy = (maxx - minx), (maxy-miny)
    stepr = (maxcolor[0] - mincolor[0] * 1.0) / diffy
    stepg = (maxcolor[1] - mincolor[1] * 1.0) / diffy
    stepb = (maxcolor[2] - mincolor[2] * 1.0) / diffy
    r,g,b = mincolor
    w, h = (abs(diffx+1),abs(diffy+1))
    tmp = Image.new('RGB', (w,h))
    tmppixels = tmp.load()
    for y in range(h):
        for x in range(w):
            tmppixels[x,y] = int(r), int(g), int(b)
        r+=stepr; g+=stepg; b+=stepb
    pixels = image.load()
    minx, miny = abs(minx), abs(miny)
    for x,y in points:
        try:
        pixels[x,y] = tmppixels[x-minx, y-miny]
    except Exception, e:
            pass

def colors_seq():
   yield (0,255,255)
   c = [(255,0,0),(0,255,0),(0,0,139)]
   i=0
   while True:i%=len(c);yield c[i];i+=1

def colorize(image):
    out = image.copy()
        COLORS = colors_seq()
    counter = 0
    for z in get_zones(image):
        c1 = COLORS.next()
        c2 = (0,0,0) if counter == 0 else (255,255,255)
        if counter % 2 == 1:
            c2, c1 = c1, c2
        apply_gradient(out, c1, c2, list(z))
        counter +=1
    return out

if __name__ == '__main__':
    I = Image.open(sys.argv[-1]).convert('RGB')
    colorize(I).show()

Bölgeyi 'degradelerle' doldurmam ve farklı bir renk döngüsü kullanmam dışında, CarpetPython'un yaptığı gibi yaptım.

En muhteşem renklendirmelerim: görüntü tanımını buraya girin görüntü tanımını buraya girin görüntü tanımını buraya girin

Makinemde hesaplama süreleri:

  • görüntü 1 (çince ejderha): gerçek 0m2.862s kullanıcı 0m2.801s sys 0m0.061s

  • görüntü 2 (gryffon): gerçek 0m0.991s kullanıcı 0m0.963s sys 0m0.029s

  • görüntü 3 (tek boynuzlu at ejderha): gerçek 0m2.260s kullanıcı 0m2.239s sys 0m0.021s


Güzel degradeler! Bir for döngüsüne bir for döngüsüne yapıştırdığınızda, ilkinde başka hiçbir şey olmayan bir for döngüsüne daha fazla girintiniz olması gerekmez mi?
OliverGriffin

Tabii ki yapıyorsun! kopyala / yapıştır sorunu oldu ...
dieter

23

Python 2 ve PIL: Psychedelic Dünyalar

Her beyaz-ish alanını bir bisiklet paletinden bir renkle doldurmak için basit bir algoritma kullandım. Sonuç çok renkli, ama çok gerçekçi değil.

Bu resimlerdeki "beyaz" kısımların çok beyaz olmadığını unutmayın. Gri tonlarını da test etmeniz gerekir.

Python 2.7'deki Kod:

import sys
from PIL import Image

WHITE = 200 * 3
cs = [60, 90, 120, 150, 180]
palette = [(199,199,199)] + [(R,G,B) for R in cs for G in cs for B in cs]

def fill(p, color):
    perim = {p}
    while perim:
        p = perim.pop()
        pix[p] = color
        x,y = p
        for u,v in [(x+dx, y+dy) for dx,dy in [(-1,0), (1,0), (0,1), (0,-1)]]:
            if 0 <= u < W and 0 <= v < H and sum(pix[(u,v)]) >= WHITE:
                perim.add((u,v))

for fname in sys.argv[1:]:
    print 'Processing', fname
    im = Image.open(fname)
    W,H = im.size
    pix = im.load()
    colornum = 0
    for y in range(H):
        for x in range(W):
            if sum(pix[(x,y)]) >= WHITE:
                thiscolor = palette[colornum % len(palette)]
                fill((x,y), thiscolor)
                colornum += 1
    im.save('out_' + fname)

Örnek resimler:

Renkli bir ejderha

LSD üzerinde kabaklar


3
Korkutucu kısmı renklerin gerçekten işe yaramış görünmesi. Her resimde renklendirmeniz ne kadar sürdü ve dosyalar ne kadar büyüktü?
OliverGriffin

1
Program her görüntüyü yaklaşık 2 saniye içerisinde renklendirir. Çıktı görüntü boyutları giriş dosyaları ile aynıdır. Dosya boyutları orijinallerden% 10 ila% 40 daha küçüktür (muhtemelen farklı jpeg sıkıştırma ayarları kullanıldığından).
Mantık Şövalye

3
Kodun ne kadar kısa olduğu konusunda çok etkilendim! Ayrıca kullanılabilecek renkleri etkin bir şekilde nasıl sınırlandırdığınızı ve böylece belirli bir palete bağlı kalmayı da seviyorum. Aslında bundan gerçekten hoşlanıyorum, bir tür grunge veriyor (bu doğru kelime mi? Ben bir sanatçı değilim) vibe.
OliverGriffin

@GirentGriffin, Beğendiğinize sevindim. Parlak ya da koyu renkleri olmayan, ancak yine de kontrastı olan bir paleti hedefliyordum. Bu renk yelpazesi en hoş sonuçlara sahip görünüyordu.
Mantık Şövalye

11

Matlab

function [output_image] = m3(input_file_name)
a=imread(input_file_name);
b=im2bw(a,0.85);
c=bwlabel(b);
h=vision.BlobAnalysis;
h.MaximumCount=10000;
ar=power(double(step(h,b)),0.15);
ar=[ar(1:max(max(c))),0];
f=cat(3,mod((ar(c+(c==0))-min(ar(1:end-1)))/ ...
    (max(ar(1:end-1))-min(ar(1:end-1)))*0.9+0.8,1),c*0+1,c*0+1);
g=hsv2rgb(f);
output_image=g.*cat(3,c~=0,c~=0,c~=0);

HSV renk uzayını kullanıyoruz ve beyaz bölgeleri arasındaki göreceli büyüklüğüne göre her bölgeyi Hue seçiyoruz. En büyük bölge mavi olacaktır ( Hue = 0.7) ve en küçük bölge menekşe olacaktır ( Hue = 0.8). Bu iki boyut arasındaki bölgelere aralıktaki Tonlar verilmiştir 0.7 -> 1=0 -> 0.8. Aralıktaki Ton, fonksiyona göre doğrusal olarak seçilir area^0.15. Her siyah olmayan piksel için Doygunluk ve Değer her zaman 1'dir.

Bir resmi renklendirmek 1 saniyeden az sürer.

Algoritmanın düzgün çalıştığı kapalı bölgelere sahip 3 resim:

Ejderha

başka bir ejderha

belki başka bir ejderha

Ve görüntülerin geri kalanı:

Ejderha

başka bir ejderha

belki başka bir ejderha

Bu görüntülerde ideal olarak birden fazla renkle renklendirilmesi gereken büyük beyaz bağlantılı bölgeler var (bu sorun Nathaniel'in çözümünde güzel bir şekilde çözüldü .


Bazı güzel renk koordineli sonuçlar için güzel ve kısa kod! Alanı, tonu belirlemeye yardımcı olmak için kullanma şeklinizi seviyorum. Ortalama görüntünün işlenmesi ne kadar sürdü ve neden daha ayrıntılı görüntülerin bazılarında işe yaramadı? Alanlar çok mu küçüktü?
OliverGriffin

1
@OliverGriffin Yazımda cevap verdi ve resimlerin geri kalanını ekledi.
Rastgele

7

Yastık ile Python 3

Kod bu cevaba eklemek için biraz uzun, ama işte bunun özü .

  1. Giriş görüntüsünü alın ve alfa kanalı varsa, beyaz bir arka plan üzerinde birleştirin. (En azından tavuk görüntüsü için gereklidir, çünkü görüntünün tamamı siyah olduğundan, yalnızca saydamlıkla ayırt edilir, bu nedenle alfa'yı düşürmek yardımcı olmazdı.)
  2. Sonucu gri tonlamaya dönüştürün; Sıkıştırma ya da kenar yumuşatma eserleri ya da tamamen gri olmayan gri çizgiler bizi karıştırmak istemiyoruz.
  3. Sonucun iki seviyeli (siyah beyaz) bir kopyasını oluşturun. Gri tonları, görüntüdeki beyaz ve en koyu gölge arasındaki yapılandırılabilir bir eşik eşiğine dayanarak siyah veya beyaza dönüştürülür.
  4. Resmin her beyaz bölgesini suyla doldurun. Sel doldurma işlemi için başlangıç ​​noktasının yerini hesaba katan seçilebilir bir palet kullanılarak renkler rastgele seçilir.
  5. Siyah çizgileri en yakın komşu renkleriyle doldurun. Bu, her renkli bölgenin sivri siyahla çevrelenmesini önleyerek, kenar yumuşatmayı yeniden eklememize yardımcı olur.
  6. Gri tonlamalı resmi 2. adımdan çekin ve bundan bir alfa maskesi yapın: en koyu renk tamamen opaktır, en açık renk tamamen saydamdır.
  7. Bu alfa maskesini kullanarak, 5. adımdaki gri tonlamalı görüntüyü renkli görüntünün üzerine birleştirin.

Bu son birkaç adım, ne yazık ki, daha koyu renkli bölgelerde görülen daha hafif "haleleri" ortadan kaldırmadı, ancak en azından gözle görülür bir fark yarattılar. Görüntü işleme asla çalışma alanım olmadı, bu yüzden bildiğim kadarıyla burada yapmaya çalıştığım şeyi yapmak için daha başarılı ve daha verimli algoritmalar var ... ama ah peki.

Şimdiye kadar, adım 4 için sadece iki seçilebilir palet var: tamamen rastgele bir tane ve gök rengini üst köşelere, çimen renklerini alt köşelere, kahverengi (kayalar veya ahşap) atamaya çalışan çok kaba bir "doğal" olan ) Her bir tarafın ortasındaki renkler ve ortada çeşitli renkler bulunur. Başarı sınırlı kaldı.


Kullanımı:

usage: paint_by_prog.py [-h] [-p PALETTE] [-t THRESHOLD] [-f | -F] [-d]
                        FILE [FILE ...]

Paint one or more line-art images.

positional arguments:
  FILE                  one or more image filenames

optional arguments:
  -h, --help            show this help message and exit
  -p PALETTE, --palette PALETTE
                        a palette from which to choose colours; one of
                        "random" (the default) or "natural"
  -t THRESHOLD, --threshold THRESHOLD
                        the lightness threshold between outlines and paintable
                        areas (a proportion from 0 to 1)
  -f, --proper-fill     fill under black lines with proper nearest-neighbour
                        searching (slow)
  -F, ---no-proper-fill
                        fill under black lines with approximate nearest-
                        neighbour searching (fast)
  -d, --debug           output debugging information

Örnekler:

paint_by_prog.py -t 0.7 Gryphon-Lines.png Renkli gryphon

paint_by_prog.py Dragon-Tattoo-Outline.jpg Renkli çizgi ejderha

paint_by_prog.py -t 0.85 -p natural The-Pumpkin-Farm-of-Good-old-Days.jpg Renkli çiftlik sahne

paint_by_prog.py -t 0.7 Dragon-OutLine.jpg Renkli grunge ejderha

paint_by_prog.py stejar-arbore-schiţă-natura.png Renkli ağaç, çok bayrağa benziyor

Tavuk pek iyi gözükmüyor ve Link imajı için en son sonucum en iyisi değil; Kodun daha eski bir versiyonundan gelen, büyük ölçüde soluk sarı renkte, ve ilginç bir çöl havası vardı.


Verim:

Her görüntünün varsayılan ayarlarla işlemesi birkaç saniye sürer; bu, adım 5 için yaklaşık en yakın komşu algoritmasının kullanıldığı anlamına gelir. En yakın gerçek komşu, oldukça yarım, belki de yarım dakika sürüyor (aslında zamanlamadım).


İlk görüntü fantastik görünüyor, özellikle de o kahverengi göz. Aferin. Ayrıca yeşil çim, kahverengi balkabağı tarlaları ve mor bulutlardan dolayı sizi alkışlıyorum.
OliverGriffin,

3

Java

Seçtiğiniz palet arasından rastgele renk seçimi.

Uyarı: Bölge, beyaz bölgeler alışılmadık derecede küçük olmadıkça, şu anda çok yavaş bulunur.

import java.awt.Color;
import java.awt.image.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.function.Supplier;

import javax.imageio.ImageIO;


public class Colorer{
    public static boolean isProbablyWhite(int x,int y){
        Color c=new Color(image.getRGB(x, y));
        if(c.getRed()<240)return false;
        if(c.getBlue()<240)return false;
        if(c.getGreen()<240)return false;
        return true;
    }
    static class Point{
        int x,y;
        public boolean equals(Object o){
            if(o instanceof Point){
                Point p=(Point)o;
                return x==p.x&&y==p.y;
            }
            return false;
        }
        public Point(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
    static BufferedImage image;
    static int W,H;
    public static void check(Point p,List<Point>l1,List<Point>l2,List<Point>l3){
        if(!isProbablyWhite(p.x,p.y))return;
        if(l1.contains(p))return;
        if(l2.contains(p))return;
        if(l3.contains(p))return;
        l1.add(p);
    }
    public static void process(int x,int y,Color c){
        List<Point>plist=new LinkedList<>();
        int rgb=c.getRGB();
        plist.add(new Point(x,y));
        List<Point>l3=new LinkedList<>();
        int k=0;
        for(int i=0;i<W*H;i++){
            System.out.println(k=l3.size());
            List<Point>l2=new LinkedList<>();
            for(Point p:plist){
                int x1=p.x;
                int y1=p.y;
                if(x1>0){
                    check(new Point(x1-1,y1),l2,plist,l3);
                }
                if(y1>0){
                    check(new Point(x1,y1-1),l2,plist,l3);
                }
                if(x1<W-1){
                    check(new Point(x1+1,y1),l2,plist,l3);
                }
                if(y1<H-1){
                    check(new Point(x1,y1+1),l2,plist,l3);
                }
            }
            while(!plist.isEmpty()){
                l3.add(plist.remove(0));
            }
            if(l3.size()==k)break;
            plist=l2;
        }
        plist=l3;
        for(Point p:plist){
            image.setRGB(p.x,p.y,rgb);
        }
    }
    public static void main(String[]args) throws Exception{
        Random rand=new Random();
        List<Supplier<Color>>colgen=new ArrayList<>();
        colgen.add(()->{return new Color(rand.nextInt(20),50+rand.nextInt(200),70+rand.nextInt(180));});
        colgen.add(()->{return new Color(rand.nextInt(20),rand.nextInt(40),70+rand.nextInt(180));});
        colgen.add(()->{return new Color(150+rand.nextInt(90),10+rand.nextInt(120),rand.nextInt(5));});
        colgen.add(()->{int r=rand.nextInt(200);return new Color(r,r,r);});
        colgen.add(()->{return Arrays.asList(new Color(255,0,0),new Color(0,255,0),new Color(0,0,255)).get(rand.nextInt(3));});
        colgen.add(()->{return Arrays.asList(new Color(156,189,15),new Color(140,173,15),new Color(48,98,48),new Color(15,56,15)).get(rand.nextInt(4));});
        Scanner in=new Scanner(System.in);
        image=ImageIO.read(new File(in.nextLine()));
        final Supplier<Color>sup=colgen.get(in.nextInt());
        W=image.getWidth();
        H=image.getHeight();
        for(int x=0;x<W;x++){
            for(int y=0;y<H;y++){
                if(isProbablyWhite(x,y))process(x,y,sup.get());
            }
        }
        ImageIO.write(image,"png",new File("out.png"));
    }
}

İki giriş gerektirir: dosya adı ve palet kimliği. Bazı zehirlenme önleyici düzeltmeleri içerir, ancak saydam pikseller için mantık içermez.

Aşağıdaki paletler şu anda tanınmaktadır:

0: Blue and greeen
1: Blue
2: Red
3: Greyscale
4: Three-color Red, Green, and Blue
5: Classic Game Boy pallette (four shades of green)

Sonuçlar:

Ejderha, Game Boy paleti:

görüntü tanımını buraya girin

Diğer ejderha, mavi + yeşil palet:

görüntü tanımını buraya girin

GOL natürmort mona lisa ( bu program tarafından render edildiği gibi ), üç renkli palet:

görüntü tanımını buraya girin


Renk özelleştirilebilirlik için +1! :) Antialiasing sorununu çözebilseydiniz bu daha iyi olurdu. Bu görüntüleri basmanız ne kadar sürdü?
OliverGriffin
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.