Vẽ theo số (sử dụng lập trình, không phải số)


56

Nhiệm vụ của bạn là tạo ra một chương trình lấy hình ảnh viền đen trắng (ví dụ hình ảnh bên dưới) và tô màu nó bằng màu. Tùy thuộc vào cách bạn phân chia từng khu vực và màu nào sẽ lấp đầy (thậm chí bạn có thể sử dụng RNG).

Ví dụ:

đầu ra cho ví dụ 1

Như bạn có thể thấy tôi rõ ràng là một nghệ sĩ có tầm cỡ vượt trội khi nói đến MS Paint.


Chấm điểm

Đây là một cuộc thi phổ biến, vì vậy câu trả lời có nhiều lượt bình chọn nhất sẽ thắng. Cử tri được khuyến khích đánh giá câu trả lời bằng cách

  • Tiêu chí đầu vào: bất kỳ hình ảnh nào bao gồm nền trắng / xám nhạt và viền ngoài màu đen / xám đen
  • Làm thế nào tốt màu được thực hiện; có nghĩa là ít hoặc không có khu vực nào có màu trắng không giống như trên (trừ khi bạn rõ ràng có ý định sử dụng màu trắng, ví dụ như cho các đám mây)
  • Khả năng tùy biến của màu sắc được sử dụng trong các phần nhất định
  • Hệ thống hoạt động tốt như thế nào trên một loạt các hình ảnh khác nhau (chi tiết khác nhau)
  • Đăng bao lâu chương trình của bạn mất trên mỗi hình ảnh. Chúng tôi có thể không chơi golf mã, nhưng mã ngắn hơn, nhanh hơn và hiệu quả hơn nên được coi là tốt hơn
  • Nên xuất hình ảnh mới lên màn hình hoặc vào một tệp (không lớn hơn 2MB để có thể hiển thị trong câu trả lời)
  • Vui lòng giải thích lý do tại sao bạn chọn xuất ra loại hình ảnh đó và nhận xét / giải thích hoạt động của mã của bạn
  • Khả năng ứng dụng của màu sắc được sử dụng cho hình dạng tương ứng mà nó bị ràng buộc bởi (bảng màu thực tế tức là cỏ có màu xanh lá cây, hàng rào gỗ có màu nâu, v.v.)

    "Tôi có thể tô màu ngẫu nhiên cho từng khu vực, nhưng nếu tôi có thể xác định" hàng rào "và làm cho nó có màu tương tự, thì đó là thứ đáng được nâng cấp." - NathanMerrill

Xem như đây một cuộc thi phổ biến, bạn cũng có thể tùy ý đánh giá bằng cách:

  • Tổng thể hấp dẫn (hình ảnh trông đẹp như thế nào)
  • Sự tinh tế nghệ thuật; nếu bạn có thể lập trình trong tô màu hoặc tô màu theo phong cách màu nước, v.v.

Nói chung, hình ảnh xuất ra nhỏ nhất (kích thước tệp) có chất lượng cao nhất, với chương trình được nhịn ăn và phiếu bầu công khai cao nhất sẽ giành chiến thắng.

Nếu bạn có các thông số kỹ thuật đánh giá khác mà bạn nghĩ nên sử dụng, vui lòng giới thiệu chúng trong các nhận xét của bài đăng này.


Ví dụ

Tôi không sở hữu gì cả; tất cả các hình ảnh ví dụ là của một giấy phép commons sáng tạo.

ví dụ 1 màu đen / trắng Nguồn: https://pixabay.com/ro/stejar-arbore-schi%C5%A3%C4%83-natura-303890/ ví dụ 2 màu đen / trắng Nguồn: http : //www.freví dụ 3 màu đen / trắng Breedphotos.biz/stockphoto/10665 Nguồn: http: / /crystal-rose1981.deviantart.com/art/Dragon-Tattoo-Outline-167320011 ví dụ 4 màu đen / trắng Nguồn: http://jaclynonacloudlines.deviantart.com/art/Gryphon-Lines-PF-273195317 ví dụ 5 màu đen / trắng Nguồn: http://captaincyprus.deviantart.com / art / Dragon-OutLine-331748686 ví dụ 6 màu đen / trắng Nguồn: http ví dụ 7 màu đen / trắng : // Electrical-meat.deviantart.com/art/A-Heroes-Farewell-280271639 Nguồn: http://movillefacepalmplz.deviantart.com/art/Background-The-Pumpkin -Farm-of-Good-old-Days-342865938


EDIT: Do khử răng cưa trên các dòng gây ra các pixel không đen / trắng và một số hình ảnh có thể chứa màu xám thay vì đen / trắng, như một thách thức bổ sung mà bạn có thể cố gắng xử lý. Nó nên đủ dễ dàng theo ý kiến ​​của tôi.


4
Đối với mọi người: xin đừng downvote / đóng cái này như một "cuộc thi nghệ thuật" - có nhiều thứ hơn thế
edc65

16
Chào mừng đến với PPCG! Tôi hoan nghênh bạn vì đã can đảm không chỉ có bài đăng đầu tiên của bạn là một thử thách, và không chỉ là một thử thách pop-con, mà còn là một thử thách nghệ thuật trên tất cả. Chúc may mắn, tôi chúc bạn những điều tốt đẹp nhất, và nếu bạn đi xung quanh tôi nghĩ bạn sẽ đi xa đến đây.
admBorkBork

4
@OliverGriffin Tôi đang bỏ phiếu chống lại việc đóng cửa và đồng thời, tôi đã thêm vào những hình ảnh bạn liên kết với bạn. Bạn có thể loại bỏ các ý kiến, nếu bạn muốn.
Addison Crump

2
Cuối cùng tôi đã tìm thấy một cách tiếp cận có thể sẽ không chồng tràn, nhưng bây giờ nó đang chạy chậm.
SuperJedi224

4
Tôi đã bỏ phiếu để mở lại câu hỏi của bạn và đã thay đổi -1 của tôi thành +1. Chỉnh sửa công việc tốt và thêm thông tin bổ sung. Ngoài ra, tôi hoan nghênh bạn rất dễ chấp nhận những lời chỉ trích của cộng đồng. Chào mừng đến với PPCG! Hy vọng là bạn sẽ thích nó.
Zach Gates

Câu trả lời:


30

Bàn chải không khí quang phổ (Python, PIL, scipy)

Điều này sử dụng một thuật toán toán học tinh vi để tạo ra những thứ vô nghĩa đầy màu sắc. Thuật toán có liên quan đến thuật toán PageRank của Google, nhưng đối với pixel thay vì các trang web.

Tôi đã thực hiện phương pháp này bởi vì tôi nghĩ rằng không giống như các phương pháp dựa vào lũ lụt, nó có thể có khả năng đối phó với các hình ảnh như con gà và cái cây, nơi có những hình dạng không hoàn toàn bị bao quanh bởi các đường màu đen. Như bạn có thể thấy, nó là một loại công trình, mặc dù nó cũng có xu hướng tô màu ở các phần khác nhau của bầu trời với các màu khác nhau

Đối với những người có đầu óc toán học: những gì nó làm về cơ bản là xây dựng biểu đồ kề của các pixel trong ảnh, sau đó tìm ra 25 hàm riêng của đồ thị Laplacian. (Ngoại trừ nó không hoàn toàn như vậy, vì chúng tôi bao gồm các pixel tối, chúng tôi chỉ cung cấp cho các kết nối của chúng trọng lượng thấp hơn. Điều này giúp xử lý khử răng cưa và dường như cũng cho kết quả tốt hơn nói chung.) sự kết hợp tuyến tính ngẫu nhiên của chúng, được cân bằng bởi các giá trị riêng nghịch đảo của chúng, để tạo thành các thành phần RGB của hình ảnh đầu ra.

Theo lợi ích của thời gian tính toán, hình ảnh được thu nhỏ lại trước khi thực hiện tất cả điều này, sau đó thu nhỏ lại một lần nữa và sau đó nhân với hình ảnh gốc. Tuy nhiên, nó không chạy nhanh, mất khoảng 2 đến 10 phút trên máy của tôi, tùy thuộc vào hình ảnh đầu vào, mặc dù vì một số lý do, con gà mất 17 phút.

Thực sự có thể biến ý tưởng này thành một thứ hữu ích, bằng cách tạo ra một ứng dụng tương tác nơi bạn có thể kiểm soát màu sắc và cường độ của từng người bản địa. Bằng cách đó, bạn có thể làm mờ dần những phần chia bầu trời thành các phần khác nhau và mờ dần trong những phần thu nhận các đặc điểm có liên quan của hình ảnh. Nhưng tôi không có kế hoạch để làm điều này bản thân mình :)

Dưới đây là hình ảnh đầu ra:

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

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

(Nó không hoạt động tốt trên những quả bí ngô, vì vậy tôi bỏ qua cái đó.)

Và đây là mã:

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
Đây là thực sự mát mẻ. Có lẽ là một trong những yêu thích của tôi cho đến nay. Bạn đã làm một công việc tuyệt vời để xử lý khử răng cưa và các khu vực kết thúc mở, và cuối cùng ai đó đã tô màu trong Link! (Đang chờ đợi điều đó :-P save set to desktop ) Tôi tự hỏi giáo viên tiếng Anh cũ của tôi sẽ nói gì về điều đó như một hình ảnh tĩnh ... "Nó cho thấy hai mặt của trái tim anh, một bên là sự bình yên và ở bên khác là chiến đấu cần thiết để có được hòa bình đó ". Đủ về tình yêu của tôi dành cho các trò chơi Legend of Zelda ... Thật xấu hổ khi phải mất quá nhiều thời gian. Làm thế nào lớn là các tập tin kết quả? Hình ảnh tình yêu của Ps 4 & 5
OliverGriffin

2
@donbright một học sinh lớp 3 có thể hiểu người bản địa thực sự sẽ là một đứa trẻ rất thông minh - Tôi không chắc là tôi có thể giải thích thuật toán ở cấp độ đó. Nhưng hãy để tôi thử dù thế nào đi nữa: hãy tưởng tượng rằng chúng ta in hình lên một tấm kim loại cứng. Sau đó, chúng tôi cẩn thận cắt bỏ tất cả các đường màu đen và thay thế chúng bằng một cái gì đó linh hoạt hơn nhiều, như đàn hồi. Vì vậy, phần màu trắng là tấm kim loại và phần màu đen là vải linh hoạt. Tiếp theo, chúng tôi treo toàn bộ thứ trong không khí từ chuỗi, để nó tự do di chuyển. Bây giờ nếu chúng ta chạm vào các tấm kim loại, chúng sẽ rung ...
Nathaniel

2
@donbright (tiếp theo) ... Tùy thuộc vào cách bạn chạm vào tấm kim loại, nó sẽ rung theo các cách khác nhau. Có thể đôi khi chỉ một trong những bộ phận kim loại sẽ rung động chứ không phải những bộ phận khác, nhưng những lần khác (vì chúng được kết nối bằng dây thun), nhấn một tấm sẽ bắt đầu một bộ phận khác di chuyển. Những cách rung khác nhau được gọi là chế độ rung . Chương trình này mô phỏng một số chế độ rung của tấm kim loại này, nhưng thay vì tạo ra âm thanh, nó sử dụng chúng để tìm ra màu nào sẽ vẽ.
Nathaniel

2
@donbright Bạn cũng có thể xem ở đây để biết thêm về hình ảnh rung động của các tấm kim loại.
Nathaniel

2
@donbright (giải thích kỹ thuật nhiều hơn này cũng có thể làm bạn mất một chút, nhưng giải thích này hoạt động vì các chế độ rung của một tấm cũng được tính toán bằng cách sử dụng phép tính eigenvector. không thực sự chắc chắn.)
Nathaniel

25

Python 2 + PIL cũng vậy, cuốn sách tô màu đầu tiên của tôi

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

Tôi đã làm hoàn toàn giống như RugPython đã làm, ngoại trừ việc tôi lấp đầy khu vực bằng 'độ dốc' và sử dụng một chu kỳ màu khác nhau.

Màu sắc tuyệt vời nhất của tôi: nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Thời gian tính toán trên máy của tôi:

  • hình ảnh 1 (rồng Trung Quốc): thực 0m2.862s người dùng 0m2.801s sys 0m0.061s

  • hình ảnh 2 (gryffon): người dùng thực 0m0.991s 0m0.963s sys 0m0.029s

  • hình ảnh 3 (rồng kỳ lân): người dùng thực 0m2.260s 0m2.239s sys 0m0.021s


Độ dốc tốt đẹp! Khi bạn gắn một vòng lặp for bên trong một vòng lặp for mà không có gì khác bên trong vòng lặp đầu tiên, bạn không cần phải thụt lề thêm?
OliverGriffin

chắc chắn rằng bạn làm ! đó là vấn đề sao chép / dán ...
ăn kiêng

23

Python 2 và PIL: Thế giới ảo giác

Tôi đã sử dụng một thuật toán đơn giản để lấp đầy từng khu vực màu trắng với màu từ bảng màu đi xe đạp. Kết quả là rất nhiều màu sắc, nhưng không giống như thật.

Lưu ý rằng các phần "trắng" trong những hình ảnh này không phải là rất trắng. Bạn sẽ cần phải kiểm tra các sắc thái của màu xám quá.

Mã trong 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)

Ví dụ hình ảnh:

Một con rồng đầy màu sắc

Bí ngô trên LSD


3
Phần đáng sợ là màu sắc thực sự có vẻ hoạt động. Bạn mất bao lâu để tô màu trong mỗi hình ảnh và các tệp lớn như thế nào?
OliverGriffin

1
Chương trình tô màu mỗi hình ảnh trong khoảng 2 giây. Kích thước hình ảnh đầu ra giống như các tập tin đầu vào. Kích thước tệp chủ yếu nhỏ hơn 10% đến 40% so với bản gốc (có thể do các cài đặt nén jpeg khác nhau được sử dụng).
Hiệp sĩ logic

3
Tôi hoàn toàn ấn tượng về độ ngắn của mã! Tôi cũng thích cách bạn giới hạn hiệu quả các màu có sẵn để sử dụng, do đó giữ cho một pallet đặt. Tôi thực sự thực sự thích nó, nó giống như một từ grunge (đó có phải là từ đúng không? Tôi không phải là một nghệ sĩ) rung cảm.
OliverGriffin

@OliverGriffin, tôi rất vui vì bạn thích nó. Tôi đã nhắm đến một bảng màu không có màu sáng hoặc tối, nhưng vẫn có một số tương phản. Phạm vi màu này dường như có kết quả làm hài lòng nhất.
Hiệp sĩ logic

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

Chúng tôi sử dụng không gian màu HSV và chọn từng vùng Huế dựa trên kích thước tương đối giữa các vùng màu trắng. Vùng lớn nhất sẽ có màu xanh lam ( Hue = 0.7) và vùng nhỏ nhất sẽ có màu tím ( Hue = 0.8). Các khu vực giữa hai kích thước này được đưa ra màu sắc trong phạm vi 0.7 -> 1=0 -> 0.8. Hue trên phạm vi được chọn tuyến tính đối với chức năng area^0.15. Độ bão hòa và Giá trị luôn là 1 cho mỗi pixel không phải màu đen.

Phải mất ít hơn 1 giây để tô màu một hình ảnh.

3 hình ảnh với các vùng kín nơi thuật toán hoạt động tốt:

rồng

một con rồng khác

có thể là một con rồng khác

Và phần còn lại của hình ảnh:

rồng

một con rồng khác

có thể là một con rồng khác

Trên những hình ảnh này có các vùng kết nối lớn màu trắng nên được tô màu lý tưởng bằng nhiều màu (vấn đề này đã được giải quyết độc đáo trong giải pháp của Nathaniel .


Mã đẹp và ngắn cho một số kết quả phối hợp màu sắc đẹp! Tôi thích cách bạn sử dụng khu vực để giúp xác định màu sắc. Mất bao lâu để xử lý hình ảnh trung bình và tại sao nó không hoạt động trên một số hình ảnh chi tiết hơn? Là những khu vực quá nhỏ?
OliverGriffin

1
@OliverGriffin Anwered trong bài viết của tôi và thêm phần còn lại của hình ảnh.
ngẫu nhiên

7

Python 3 với gối

Mã này hơi dài để đưa vào câu trả lời này, nhưng đây là ý chính của nó .

  1. Lấy hình ảnh đầu vào và, nếu nó có kênh alpha, hãy ghép nó lên nền trắng. (Ít nhất là cần thiết cho hình ảnh con gà, bởi vì toàn bộ hình ảnh đó là màu đen, chỉ được phân biệt bằng độ trong suốt, vì vậy chỉ cần bỏ alpha là không hữu ích.)
  2. Chuyển đổi kết quả sang thang độ xám; chúng tôi không muốn các tạo tác nén hoặc chống răng cưa, hoặc các đường màu xám không phải là màu xám, làm chúng tôi rối tung lên.
  3. Tạo một bản sao hai cấp (đen và trắng) của kết quả. Các sắc thái của màu xám được chuyển đổi thành màu đen hoặc trắng dựa trên ngưỡng cắt có thể định cấu hình giữa màu trắng và màu tối nhất trong ảnh.
  4. Lấp đầy - lấp đầy mọi vùng trắng của hình ảnh. Màu sắc được chọn ngẫu nhiên, sử dụng bảng màu có thể chọn có tính đến vị trí của điểm bắt đầu cho hoạt động lấp đầy lũ.
  5. Điền vào các dòng màu đen với màu lân cận gần nhất của chúng. Điều này giúp chúng tôi giới thiệu lại khử răng cưa, bằng cách giữ cho mọi vùng màu không bị viền trong màu đen lởm chởm.
  6. Lấy hình ảnh thang độ xám từ bước 2 và tạo mặt nạ alpha từ nó: màu tối nhất hoàn toàn mờ đục, màu sáng nhất hoàn toàn trong suốt.
  7. Kết hợp hình ảnh thang độ xám lên hình ảnh màu từ bước 5 bằng mặt nạ alpha này.

Thật không may, vài bước cuối cùng, vẫn chưa loại bỏ được "halos" nhẹ hơn có thể nhìn thấy ở các vùng màu tối hơn, nhưng ít nhất chúng đã tạo ra sự khác biệt rõ rệt. Xử lý hình ảnh chưa bao giờ là lĩnh vực nghiên cứu của tôi, vì vậy đối với tất cả tôi biết có nhiều thuật toán thành công hơn và hiệu quả hơn để làm những gì tôi đã cố gắng làm ở đây ... nhưng tốt.

Cho đến nay, chỉ có hai bảng màu có thể lựa chọn cho bước 4: một bảng màu hoàn toàn ngẫu nhiên và một bảng màu "tự nhiên" rất thô, cố gắng gán màu trời cho các góc trên, màu cỏ cho các góc dưới, màu nâu (đá hoặc gỗ ) màu sắc ở giữa mỗi bên, và màu sắc đa dạng xuống trung tâm. Thành công đã ... hạn chế.


Sử dụng:

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

Mẫu:

paint_by_prog.py -t 0.7 Gryphon-Lines.png Gryphon màu

paint_by_prog.py Dragon-Tattoo-Outline.jpg Rồng hoạt hình màu

paint_by_prog.py -t 0.85 -p natural The-Pumpkin-Farm-of-Good-old-Days.jpg Cảnh trang trại màu

paint_by_prog.py -t 0.7 Dragon-OutLine.jpg Rồng grunge màu

paint_by_prog.py stejar-arbore-schiţă-natura.png Cây màu, trông rất giống cờ

Con gà trông không được tốt lắm và kết quả gần đây nhất của tôi cho hình ảnh Liên kết không phải là tốt nhất; một phiên bản từ phiên bản trước đó của mã chủ yếu có màu vàng nhạt và có một sự rung cảm sa mạc thú vị về nó ...


Hiệu suất:

Mỗi hình ảnh mất vài giây để xử lý các cài đặt mặc định, điều đó có nghĩa là thuật toán lân cận gần nhất được sử dụng cho bước 5. Hàng xóm gần nhất thực sự chậm hơn đáng kể, có thể mất nửa phút (tôi thực sự không hẹn giờ).


Hình ảnh đầu tiên trông tuyệt vời, đặc biệt là đôi mắt nâu. Làm tốt lắm. Tôi cũng hoan nghênh bạn khi nhận được cỏ xanh, những cánh đồng bí ngô màu nâu và những đám mây màu tím.
OliverGriffin

3

Java

Lựa chọn màu sắc ngẫu nhiên từ sự lựa chọn của bạn của pallet.

Cảnh báo: Việc tìm kiếm khu vực hiện đang rất chậm, trừ khi các khu vực màu trắng nhỏ bất thường.

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

Yêu cầu hai đầu vào: tên tệp và ID bảng màu. Bao gồm một số hiệu chỉnh khử răng cưa, nhưng không bao gồm logic cho các pixel trong suốt.

Các bảng màu sau đây hiện đang được công nhận:

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)

Các kết quả:

Bảng màu rồng, Game Boy:

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

Bảng màu rồng, xanh dương + xanh lục khác:

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

GOL still life mona lisa (như được hiển thị bởi chương trình này ), bảng màu ba màu:

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


+1 cho khả năng tùy chỉnh màu sắc của bạn! :) nếu bạn có thể khắc phục vấn đề khử răng cưa thì điều này sẽ còn tốt hơn nữa. Bạn mất bao lâu để xuất ra những hình ảnh này?
OliverGriffin
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.