Cat dengan Angka (menggunakan pemrograman, bukan angka)

56

Tugas Anda adalah membuat program yang mengambil gambar garis hitam-putih (contoh gambar di bawah) dan mengisinya dengan warna. Terserah Anda bagaimana Anda memisah-misahkan masing-masing wilayah dan warna yang mana untuk mengisinya (Anda bahkan bisa menggunakan RNG).

Sebagai contoh:

output misalnya 1

Seperti yang Anda lihat, saya jelas seorang seniman kaliber unggul dalam hal MS Paint.


Mencetak gol

Ini adalah kontes popularitas, jadi jawabannya dengan suara terbanyak menang. Pemilih didorong untuk menilai jawaban oleh

  • Kriteria input: gambar apa pun yang terdiri dari latar belakang putih / abu-abu terang dan garis hitam / abu-abu gelap
  • Seberapa baik pewarnaan dilakukan; artinya sedikit atau tidak ada area yang putih tidak seperti di atas (kecuali Anda jelas bermaksud menggunakan putih misalnya untuk awan)
  • Kustomisasi warna yang digunakan di bagian tertentu
  • Seberapa baik sistem bekerja pada serangkaian gambar yang berbeda (dengan detail yang bervariasi)
  • Posting berapa lama program Anda mengambil per gambar. Kami mungkin tidak bermain golf kode, tetapi kode yang lebih pendek, lebih cepat, dan lebih efisien harus dianggap lebih baik
  • Seharusnya menampilkan gambar baru ke layar atau ke file (tidak lebih dari 2MB sehingga dapat ditampilkan dalam jawaban)
  • Tolong beri alasan mengapa Anda memilih untuk menampilkan tipe gambar itu dan berkomentar / jelaskan cara kerja kode Anda
  • Penerapan warna yang digunakan untuk bentuk masing-masing terikat oleh (skema warna realistis yaitu rumput berwarna hijau, pagar kayu berwarna coklat dll.)

    "Aku bisa mewarnai setiap area secara acak, tetapi jika aku bisa mengidentifikasi" pagar "dan membuatnya berwarna sama, maka itu adalah sesuatu yang patut mendapat pujian." - NathanMerrill

Melihat ini adalah kontes popularitas, Anda juga dapat menilai secara opsional dengan:

  • Daya tarik keseluruhan (seberapa bagus gambar terlihat)
  • Bakat artistik; jika Anda dapat memprogram dalam pewarnaan atau pewarnaan gaya cat air dll.

Secara umum, gambar terkecil yang dihasilkan (ukuran file) dengan kualitas tertinggi, dengan program berpuasa dan suara publik tertinggi akan menang.

Jika Anda memiliki spesifikasi penilaian lain yang menurut Anda harus digunakan, harap rekomendasikan mereka di komentar posting ini.


Contohnya

Saya tidak punya apa apa; semua contoh gambar adalah lisensi creative commons.

contoh 1 dalam warna hitam / putih Sumber: https://pixabay.com/ro/stejar-arbore-schi%C5%A3%C4%83-natura-303890/ Contoh 2 dalam warna hitam / putih Sumber: http://www.freestockphotos.biz/stockphoto/10665 Contoh 3 dalam warna hitam / putih Sumber: http: / /crystal-rose1981.deviantart.com/art/Dragon-Tattoo-Outline-167320011 Contoh 4 dalam warna hitam / putih Sumber: http://jaclynonacloudlines.deviantart.com/art/Gryphon-Lines-PF-273195317 Contoh 5 dalam warna hitam / putih Sumber: http://captaincyprus.deviantart.com / art / Dragon-OutLine-331748686 Contoh 6 dalam warna hitam / putih Sumber: http://electric-meat.deviantart.com/art/A-Heroes-Farewell-280271639 Contoh 7 dalam warna hitam / putih Sumber: http://movillefacepalmplz.deviantart.com/art/Background-The-Pumpkin -Pertanian-of-Good-old-Days-342865938


EDIT: Karena anti-aliasing pada garis-garis yang menyebabkan piksel non-hitam / putih dan beberapa gambar yang mungkin mengandung abu-abu, bukan hitam / putih, sebagai tantangan bonus Anda dapat mencoba untuk mengatasinya. Seharusnya menurut saya cukup mudah.

OliverGriffin
sumber
4
Untuk semua orang: tolong jangan downvote / tutup ini sebagai "kontes seni" - ada lebih dari itu
edc65
16
Selamat datang di PPCG! Saya memuji Anda karena memiliki keberanian untuk tidak hanya memiliki posting pertama Anda menjadi tantangan, dan tidak hanya tantangan pop-con, tetapi tantangan artistik di atas semua itu. Semoga beruntung, saya berharap yang terbaik, dan jika Anda bertahan saya pikir Anda akan pergi jauh ke sini.
AdmBorkBork
4
@OliverGriffin Saya memberikan suara menentang penutupan dan juga, saya telah menambahkan dalam gambar yang Anda tautkan untuk Anda. Anda dapat menghapus komentar, jika mau.
Addison Crump
2
Saya akhirnya menemukan pendekatan yang mungkin tidak akan menumpuk, tetapi sekarang ini berjalan agak lambat.
SuperJedi224
4
Saya telah memilih untuk membuka kembali pertanyaan Anda dan telah mengubah -1 saya menjadi +1. Pengeditan pekerjaan yang baik dan menambahkan informasi tambahan. Juga, saya memuji Anda karena sangat menerima kritik komunitas. Selamat datang di PPCG! Berharap kamu menikmatinya.
Zach Gates

Jawaban:

30

Airbrushing spektral (Python, PIL, Scipy)

Ini menggunakan algoritma matematika yang canggih untuk menghasilkan omong kosong penuh warna. Algoritma ini terkait dengan algoritma PageRank Google, tetapi untuk piksel, bukan halaman web.

Saya mengambil pendekatan ini karena saya berpikir bahwa tidak seperti metode berbasis pengisian banjir mungkin dapat mengatasi gambar seperti ayam dan pohon, di mana ada bentuk yang tidak sepenuhnya tertutup oleh garis hitam. Seperti yang dapat Anda lihat, ini berfungsi, meskipun cenderung berwarna di berbagai bagian langit dengan warna berbeda

Untuk yang berpikiran matematis: apa yang dilakukannya pada dasarnya adalah membangun grafik kedekatan dari piksel sementara dalam gambar, kemudian menemukan 25 vektor eigen teratas dari grafik Laplacian. (Kecuali itu tidak sepenuhnya seperti itu, karena kami memang menyertakan piksel gelap, kami hanya memberi koneksi lebih berat. Ini membantu dalam berurusan dengan antialiasing, dan juga tampaknya memberikan hasil yang lebih baik secara umum.) Setelah menemukan vektor eigen, ia menciptakan sebuah kombinasi linear acak dari mereka, ditimbang oleh nilai eigen terbalik mereka, untuk membentuk komponen RGB dari gambar output.

Untuk kepentingan waktu komputasi, gambar diperkecil sebelum melakukan semua ini, kemudian ditingkatkan kembali dan kemudian dikalikan dengan gambar asli. Namun, itu tidak berjalan cepat, membutuhkan waktu antara 2 dan 10 menit pada mesin saya, tergantung pada gambar input, meskipun untuk beberapa alasan ayam butuh 17 menit.

Sebenarnya mungkin untuk mengubah ide ini menjadi sesuatu yang berguna, dengan membuat aplikasi interaktif di mana Anda dapat mengontrol warna dan intensitas masing-masing vektor eigen. Dengan begitu Anda bisa memudar yang membagi langit menjadi beberapa bagian yang berbeda, dan memudar pada yang mengambil fitur yang relevan dari gambar. Tapi saya tidak punya rencana untuk melakukan ini sendiri :)

Berikut adalah gambar output:

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

(Itu tidak bekerja dengan baik pada labu, jadi saya menghilangkan yang itu.)

Dan ini kodenya:

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))
Nathaniel
sumber
4
Ini SANGAT keren. Mungkin salah satu favorit saya sejauh ini. Anda melakukan pekerjaan yang sangat baik dalam menangani antialiasing dan area terbuka, dan seseorang akhirnya memberi warna pada Tautan! (Telah menunggu untuk itu :-P save set ke desktop ) Saya bertanya-tanya apa yang akan dikatakan guru bahasa Inggris saya yang lama tentang hal itu sebagai gambar statis ... "Ini menunjukkan dua sisi hatinya, satu sisi ada kedamaian dan pada lain ada pertempuran yang diperlukan untuk mendapatkan kedamaian itu ". Cukup tentang cintaku pada game Legend of Zelda ... Ini benar-benar memalukan karena butuh waktu begitu lama. Seberapa besar file yang dihasilkan? Ps Love images 4 & 5
OliverGriffin
2
@donbright seorang siswa kelas 3 yang bisa memahami vektor eigen akan menjadi anak yang sangat cerdas - saya tidak yakin itu mungkin bagi saya untuk menjelaskan algoritma pada tingkat itu. Tapi biar saya coba: bayangkan kita mencetak gambar ke lembaran logam yang kaku. Lalu kami dengan hati-hati memotong semua garis hitam dan menggantinya dengan sesuatu yang jauh lebih fleksibel, seperti elastis. Jadi bagian putih adalah pelat logam dan bagian hitam adalah kain yang fleksibel. Selanjutnya kita menggantung semuanya di udara dari tali, jadi bebas bergerak. Sekarang jika kita menekan pelat logam, mereka akan bergetar ...
Nathaniel
2
@donbright (lanjutan) ... Tergantung pada bagaimana Anda menekan pelat logam, itu akan bergetar dengan berbagai cara. Mungkin kadang-kadang satu saja bagian logam akan bergetar dan bukan yang lain, tetapi di waktu lain (karena mereka terhubung dengan elastis), memukul satu lempeng akan memulai yang lain bergerak juga. Cara bergetar yang berbeda ini disebut mode getaran . Program ini mensimulasikan beberapa mode getaran pelat logam ini, tetapi alih-alih menghasilkan suara, program ini menggunakannya untuk menentukan warna yang akan dibuat.
Nathaniel
2
@donbright Anda juga dapat melihat di sini untuk mengetahui lebih lanjut tentang memvisualisasikan getaran pelat logam.
Nathaniel
2
@donbright (penjelasan yang lebih teknis ini mungkin juga sedikit kehilangan Anda, tetapi penjelasan ini berfungsi karena mode getaran pelat juga dihitung menggunakan perhitungan vektor eigen. Meskipun mungkin tidak sepenuhnya sama dengan perhitungan yang dilakukan oleh kode saya - saya tidak begitu yakin.)
Nathaniel
25

Python 2 + PIL juga, buku mewarnai pertama saya

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

Saya melakukan hal yang sama seperti yang dilakukan CarpetPython, kecuali bahwa saya mengisi wilayah dengan 'gradien', dan menggunakan siklus warna yang berbeda.

Pewarnaan saya yang paling indah: masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Waktu komputasi pada mesin saya:

  • gambar 1 (naga cina): nyata 0m2.862 pengguna 0m2.801s sys 0m0.061s

  • gambar 2 (gryffon): nyata 0m0.991 pengguna 0m0.963s sys 0m0.029s

  • gambar 3 (naga unicornish): nyata 0m2.260 pengguna 0m2.239s sys 0m0.021s

pelaku diet
sumber
Gradien bagus! Ketika Anda menempelkan for for loop di dalam for for loop dengan tidak ada yang lain di dalam yang pertama Anda tidak perlu indentasi lebih lanjut?
OliverGriffin
tentu kamu lakukan! itu masalah copy / paste ...
pelaku diet
23

Python 2 dan PIL: Dunia Psychedelic

Saya telah menggunakan algoritma sederhana untuk mengisi setiap area white-ish dengan warna dari palet bersepeda. Hasilnya sangat berwarna-warni, tetapi tidak seperti aslinya.

Perhatikan bahwa bagian "putih" dalam gambar ini tidak terlalu putih. Anda juga perlu menguji nuansa abu-abu.

Kode dalam Python 2.7:

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)

Contoh gambar:

Naga berwarna-warni

Labu pada LSD

Ksatria Logika
sumber
3
Bagian yang menakutkan adalah bahwa warna-warna itu tampaknya bekerja. Berapa lama waktu yang Anda butuhkan untuk mewarnai pada setiap gambar dan seberapa besar file-file itu?
OliverGriffin
1
Program ini mewarnai setiap gambar dalam waktu sekitar 2 detik. Dimensi gambar output sama dengan file input. Ukuran file sebagian besar 10% hingga 40% lebih kecil dari aslinya (mungkin karena pengaturan kompresi jpeg yang berbeda digunakan).
Logic Knight
3
Saya benar-benar terkesan melihat betapa pendek kodenya! Saya juga suka bagaimana Anda secara efektif membatasi warna yang tersedia untuk digunakan, sehingga menjaga palet tetap. Aku benar-benar benar-benar menyukainya, itu semacam memberi grunge (apakah itu kata yang tepat? Aku bukan seorang seniman) getaran.
OliverGriffin
@ OliverGriffin, saya senang Anda menyukainya. Saya mengincar palet tanpa warna-warna cerah atau gelap, tetapi masih memiliki beberapa kontras. Kisaran warna ini tampaknya memiliki hasil yang paling menyenangkan.
Logic Knight
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);

Kami menggunakan ruang warna HSV dan memilih masing-masing wilayah Hue berdasarkan ukuran relatifnya antara wilayah putih. Wilayah terbesar akan berwarna biru ( Hue = 0.7) dan wilayah terkecil akan berwarna ungu ( Hue = 0.8). Daerah antara dua ukuran ini diberi Rona dalam kisaran 0.7 -> 1=0 -> 0.8. Hue pada kisaran dipilih secara linear sehubungan dengan fungsi area^0.15. Saturasi dan Nilai selalu 1 untuk setiap piksel yang bukan hitam.

Dibutuhkan kurang dari 1 detik untuk mewarnai gambar.

3 gambar dengan daerah tertutup tempat algoritma bekerja dengan baik:

naga

naga lain

mungkin naga lain

Dan sisa gambar:

naga

naga lain

mungkin naga lain

Pada gambar-gambar ini ada daerah terhubung putih besar yang idealnya diwarnai dengan beberapa warna (masalah ini diselesaikan dengan baik dalam solusi Nathaniel .

randomra
sumber
Kode bagus dan pendek untuk beberapa hasil terkoordinasi warna yang cantik! Saya suka bagaimana Anda menggunakan area untuk membantu menentukan rona. Berapa lama waktu yang dibutuhkan untuk memproses gambar rata-rata dan mengapa tidak bekerja pada beberapa gambar yang lebih rinci? Apakah area terlalu kecil?
OliverGriffin
1
@OliverGriffin Menjawab dalam posting saya dan menambahkan sisa gambar.
randomra
7

Python 3 dengan Bantal

Kode ini agak panjang untuk dimasukkan dalam jawaban ini, tetapi inilah intinya .

  1. Ambil gambar input dan, jika memiliki saluran alfa, gabungkan ke latar belakang putih. (Diperlukan setidaknya untuk gambar ayam, karena seluruh gambar itu hitam, hanya dibedakan oleh transparansi, jadi menjatuhkan alpha saja tidak membantu.)
  2. Ubah hasilnya menjadi skala abu-abu; kita tidak ingin kompresi atau artefak anti-aliasing, atau garis abu-abu-yang-tidak-cukup-abu-abu, mengacaukan kita.
  3. Buat salinan dua tingkat hasil (hitam dan putih). Nuansa abu-abu dikonversi menjadi hitam atau putih berdasarkan ambang batas batas yang dapat dikonfigurasi antara putih dan warna paling gelap pada gambar.
  4. Isi banjir setiap bagian putih gambar. Warna dipilih secara acak, menggunakan palet yang dapat dipilih yang memperhitungkan lokasi titik awal untuk operasi pengisian banjir.
  5. Isi garis hitam dengan warna tetangga-tetangga terdekat. Ini membantu kami memperkenalkan kembali anti-aliasing, dengan menjaga setiap wilayah berwarna agar tidak dibatasi oleh jaggy black.
  6. Ambil gambar skala abu-abu dari langkah 2 dan buat topeng alfa darinya: warna paling gelap sepenuhnya buram, warna paling terang sepenuhnya transparan.
  7. Kompositkan gambar skala abu-abu ke gambar berwarna dari langkah 5 menggunakan masker alpha ini.

Sayangnya, beberapa langkah terakhir itu masih belum menghilangkan "lingkaran cahaya" yang terlihat di daerah yang berwarna lebih gelap, tetapi setidaknya mereka telah membuat perbedaan yang nyata. Pemrosesan gambar tidak pernah menjadi bidang studi saya, jadi untuk semua yang saya tahu ada algoritma yang lebih sukses dan lebih efisien untuk melakukan apa yang saya coba lakukan di sini ... tapi oh well.

Sejauh ini, hanya ada dua palet yang dapat dipilih untuk langkah 4: yang murni acak, dan yang "kasar" yang sangat kasar, yang mencoba untuk menetapkan warna langit ke sudut atas, warna rumput ke sudut bawah, coklat (batu atau kayu ) warna di tengah setiap sisi, dan beragam warna di tengah. Keberhasilan telah ... terbatas.


Pemakaian:

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

Sampel:

paint_by_prog.py -t 0.7 Gryphon-Lines.png Gryphon berwarna

paint_by_prog.py Dragon-Tattoo-Outline.jpg Naga kartun berwarna

paint_by_prog.py -t 0.85 -p natural The-Pumpkin-Farm-of-Good-old-Days.jpg Adegan pertanian berwarna

paint_by_prog.py -t 0.7 Dragon-OutLine.jpg Naga grunge berwarna

paint_by_prog.py stejar-arbore-schiţă-natura.png Pohon berwarna, tampak sangat seperti bendera

Ayamnya tidak terlihat sangat bagus, dan hasil terbaru saya untuk gambar Tautan bukan yang terbaik; kode yang berasal dari versi kode sebelumnya sebagian besar berwarna kuning pucat, dan memiliki getaran padang pasir yang menarik tentang itu ...


Kinerja:

Setiap gambar membutuhkan beberapa detik untuk diproses dengan pengaturan default, yang berarti algoritma tetangga terdekat terdekat digunakan untuk langkah 5. Benar tetangga terdekat jauh lebih lambat, mungkin sekitar setengah menit (saya belum benar-benar menghitung waktunya).

Tim Pederick
sumber
Gambar pertama terlihat fantastis, terutama mata cokelat itu. Kerja bagus. Saya juga memuji Anda karena mendapatkan rumput hijau, ladang labu berwarna cokelat dan awan ungu.
OliverGriffin
3

Jawa

Pilihan warna acak dari palet pilihan Anda.

Peringatan: Wilayah menemukan saat ini sangat lambat, kecuali wilayah putih luar biasa kecil.

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

Membutuhkan dua input: nama file, dan ID palet. Termasuk beberapa koreksi antialiasing, tetapi tidak termasuk logika untuk piksel transparan.

Palet berikut saat ini diakui:

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)

Hasil:

Naga, palet Game Boy:

masukkan deskripsi gambar di sini

Naga lainnya, palet biru + hijau:

masukkan deskripsi gambar di sini

GOL still life mona lisa (seperti yang diberikan oleh program ini ), palet triwarna:

masukkan deskripsi gambar di sini

SuperJedi224
sumber
+1 untuk penyesuaian warna Anda! :) jika Anda dapat memperbaiki masalah antialiasing ini akan terlihat lebih baik. Berapa lama Anda untuk menampilkan gambar-gambar ini?
OliverGriffin