नंबरों द्वारा पेंट (प्रोग्रामिंग का उपयोग करके, नंबरों का नहीं)


56

आपका कार्य एक प्रोग्राम बनाना है जो एक ब्लैक-एंड-व्हाइट उल्लिखित छवि लेता है (उदाहरण चित्र नीचे हैं) और इसे रंग से भरता है। यह आपके ऊपर है कि आप प्रत्येक क्षेत्र को किस प्रकार से विभाजित करते हैं और इसे भरने के लिए कौन सा रंग (आप एक आरएनजी का उपयोग भी कर सकते हैं)।

उदाहरण के लिए:

उदाहरण के लिए आउटपुट 1

जैसा कि आप देख सकते हैं कि जब मैं एमएस पेंट की बात करता हूं तो मैं स्पष्ट रूप से एक बेहतर कैलिबर का कलाकार हूं।


स्कोरिंग

यह एक लोकप्रियता प्रतियोगिता है, इसलिए सबसे शुद्ध वोटों के साथ जवाब जीत जाता है। मतदाताओं को जवाब देने के लिए प्रोत्साहित किया जाता है

  • इनपुट मानदंड: कोई भी छवि जिसमें सफेद / हल्के-भूरे रंग की पृष्ठभूमि और काले / गहरे-भूरे रंग की रूपरेखा होती है
  • कितनी अच्छी तरह से रंगाई की जाती है; ऊपर के विपरीत कुछ या कोई क्षेत्र सफेद नहीं है (जब तक कि आप स्पष्ट रूप से बादलों के लिए सफेद का उपयोग करने का इरादा नहीं रखते हैं)
  • कुछ वर्गों में उपयोग किए जाने वाले रंगों की अनुकूलनशीलता
  • विभिन्न छवियों की एक सीमा पर प्रणाली कितनी अच्छी तरह काम करती है (अलग-अलग विवरण की)
  • पोस्ट करें कि आपका कार्यक्रम प्रति चित्र कितने समय तक चलता है। हम कोड गोल्फ नहीं खेल सकते हैं, लेकिन कम, तेज और अधिक कुशल कोड को बेहतर माना जाना चाहिए
  • नई छवि को स्क्रीन पर या फ़ाइल में आउटपुट करना चाहिए (2MB से बड़ा नहीं है ताकि इसे उत्तर में दिखाया जा सके)
  • कृपया बताएं कि आपने उस छवि प्रकार के आउटपुट को क्यों चुना और अपने कोड के कामकाज को टिप्पणी / व्याख्या करें
  • संबंधित आकार के लिए उपयोग किए जाने वाले रंग की प्रयोज्यता (यथार्थवादी रंग योजना अर्थात घास हरे रंग की होती है, लकड़ी की बाड़ भूरे रंग की होती है)

    "मैं प्रत्येक क्षेत्र को बेतरतीब ढंग से रंग सकता हूं, लेकिन अगर मैं" बाड़ "की पहचान कर सकता हूं और इसे समान रूप से रंगीन बना सकता हूं, तो यह कुछ ऐसा है जो उत्थान के योग्य है।" - नाथनमेरिल

इस रूप में देखकर है एक लोकप्रियता प्रतियोगिता, आप भी वैकल्पिक द्वारा न्याय कर सकते हैं:

  • कुल मिलाकर अपील (छवि कितनी अच्छी दिखती है)
  • कलात्मक स्वभाव; यदि आप छायांकन या वाटर कलर स्टाइल रंगाई आदि में प्रोग्राम कर सकते हैं।

सामान्य तौर पर, उपवास कार्यक्रम और उच्चतम सार्वजनिक वोट जीतने के साथ उच्चतम गुणवत्ता की सबसे छोटी आउटपुट छवि (फ़ाइल आकार) होगी।

यदि आपके पास अन्य निर्णायक विनिर्देश हैं जो आपको लगता है कि उपयोग किया जाना चाहिए, तो कृपया उन्हें इस पोस्ट की टिप्पणियों में सुझाएं।


उदाहरण

मेरे पास कुछ भी नहीं है; सभी उदाहरण चित्र एक रचनात्मक कॉमन्स लाइसेंस के हैं।

उदाहरण 1 काले / सफेद में स्रोत: https://pixabay.com/ro/stejar-arbore-schi%C5%A3%C4%83-natura-303890/ उदाहरण 2 काले / सफेद में स्रोत: http://www.frectorphotos.biz/stockphoto/10630 उदाहरण 3 काले / सफेद में स्रोत: http: / /crystal-rose1981.deviantart.com/art/Dragon-Tattoo-Outline-167320011 उदाहरण 4 काले / सफेद में स्रोत: http://jaclynonacloudlines.deviantart.com/art/Gryphon-Lines-PF-273195317 उदाहरण 5 काले / सफेद में स्रोत: http://captaincyprus.deviantart.com / कला / ड्रैगन-आउटलाइन -331748686 उदाहरण 6 काले / सफेद में स्रोत: http://electric-meat.deviantart.com/art/A-Heroes-Farewell-280271639 उदाहरण 7 काले / सफेद में स्रोत: http : //movillefacepalmplz .deviantart.com/art/Background-The-Pumpkin -Farm के- गुड पुराने दिनों-342865938


संपादित करें: गैर-काले / सफेद पिक्सेल और कुछ चित्रों के कारण एंटी-एलियासिंग के कारण जो काले / सफेद के बजाय ग्रे हो सकते हैं, बोनस चुनौती के रूप में आप इससे निपटने का प्रयास कर सकते हैं। मेरी राय में यह काफी आसान होना चाहिए।


4
सभी के लिए: कृपया इसे "कला प्रतियोगिता" के रूप में कम / बंद न करें - इसमें और भी बहुत कुछ है
edc65

16
PPCG में आपका स्वागत है! मैं आपकी पहली पोस्ट के लिए साहस नहीं होने के लिए आपकी सराहना करता हूं और न केवल एक पॉप-कॉन चुनौती है, बल्कि इस सब के ऊपर एक कलात्मक चुनौती है। सौभाग्य, मैं आपको शुभकामनाएं देता हूं, और यदि आप मेरे चारों ओर चिपकते हैं तो मुझे लगता है कि आप यहां बहुत दूर जा रहे हैं।
AdmBorkBork

4
@OliverGriffin मैं समापन के खिलाफ मतदान कर रहा हूं और साथ ही, मैंने आपके लिए लिंक की गई छवियों में जोड़ा है। आप चाहें तो टिप्पणियों को हटा सकते हैं।
एडिसन क्रम्प

2
मुझे अंत में एक दृष्टिकोण मिला जो शायद अतिप्रवाह नहीं होगा, लेकिन अब यह धीरे-धीरे चल रहा है।
SuperJedi224

4
मैंने आपके प्रश्न को फिर से खोलने के लिए मतदान किया है और मेरे -1 को +1 में बदल दिया है। अच्छी नौकरी का संपादन और अतिरिक्त जानकारी जोड़ना। साथ ही, सामुदायिक आलोचना के लिए मैं आपकी सराहना करता हूं। PPCG में आपका स्वागत है! आशा हैं आप इसका आनंद ले।
जैच गेट्स

जवाबों:


30

स्पेक्ट्रल एयरब्रशिंग (पाइथन, पीआईएल, स्कैपी)

यह रंगीन बकवास का उत्पादन करने के लिए एक परिष्कृत गणितीय एल्गोरिथ्म का उपयोग करता है। एल्गोरिथ्म Google के पेजरैंक एल्गोरिदम से संबंधित है, लेकिन वेब पृष्ठों के बजाय पिक्सेल के लिए।

मैंने यह दृष्टिकोण लिया क्योंकि मुझे लगा कि बाढ़-भराव आधारित विधियों के विपरीत यह चिकन और पेड़ जैसी छवियों का सामना करने में सक्षम हो सकता है, जहां ऐसी आकृतियाँ हैं जो पूरी तरह से काली रेखाओं से घिरी नहीं हैं। जैसा कि आप देख सकते हैं, यह काम करता है, हालांकि यह आकाश के अलग-अलग हिस्सों में अलग-अलग रंगों में रंग जाता है

गणितीय रूप से दिमाग के लिए: जो यह कर रहा है वह अनिवार्य रूप से छवि में पिक्सेल की समीपता ग्राफ का निर्माण कर रहा है, फिर ग्राफ लैपेलियन के शीर्ष 25 eigenvectors का पता लगाना। (सिवाय इसके कि यह काफी नहीं है, क्योंकि हम डार्क पिक्सल्स को शामिल करते हैं, हम सिर्फ उनके कनेक्शन को कम वजन देते हैं। यह एंटीएलियासिंग से निपटने में मदद करता है, और सामान्य रूप से बेहतर परिणाम देने के लिए भी लगता है।) आइजनवेक्टरों को खोजने के बाद, यह बनाता है। आउटपुट छवि के RGB घटकों को बनाने के लिए, उनके व्युत्क्रम eigenvalues ​​द्वारा भारित, उनमें से यादृच्छिक रैखिक संयोजन।

अभिकलन समय के हितों में, यह सब करने से पहले छवि को छोटा किया जाता है, फिर फिर से ऊपर स्केल किया जाता है और फिर मूल छवि से गुणा किया जाता है। फिर भी, यह जल्दी से नहीं चलता है, मेरी मशीन पर लगभग 2 से 10 मिनट लगते हैं, इनपुट छवि के आधार पर, हालांकि किसी कारण से चिकन को 17 मिनट लग गए।

वास्तव में इस विचार को किसी उपयोगी ऐप में बदलना संभव हो सकता है, एक इंटरैक्टिव ऐप बनाकर जहां आप प्रत्येक ईजेनवेक्टर के रंग और तीव्रता को नियंत्रित कर सकते हैं। इस तरह आप उन लोगों को मिटा सकते हैं जो आकाश को अलग-अलग वर्गों में विभाजित करते हैं, और उन लोगों में फीका हो जाते हैं जो छवि की प्रासंगिक विशेषताओं को उठाते हैं। लेकिन मेरे पास खुद ऐसा करने की कोई योजना नहीं है :)

यहाँ आउटपुट चित्र हैं:

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

(यह कद्दू पर इतनी अच्छी तरह से काम नहीं करता था, इसलिए मैं उस एक को छोड़ देता हूं।)

और यहाँ कोड है:

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
यह वास्ताव में अच्छा है। शायद मेरे पसंदीदा में से एक। आपने एंटीएलियासिंग और खुले अंत क्षेत्रों को संभालने का एक उत्कृष्ट काम किया, और किसी ने आखिरकार लिंक में रंग दिया! (इसके लिए इंतजार कर रहे हैं :-P डेस्कटॉप पर सेट सहेजें ) मुझे आश्चर्य है कि मेरे पुराने अंग्रेजी शिक्षक ने एक स्थिर छवि के रूप में इसके बारे में क्या कहा होगा ... "यह उनके दिल के दो पक्षों को दर्शाता है, एक तरफ शांति है और पर है।" अन्य उस शांति को प्राप्त करने के लिए आवश्यक लड़ाई है ”। लीजेंड ऑफ ज़ेल्डा गेम्स के लिए मेरे प्यार के बारे में पर्याप्त ... यह वास्तव में शर्म की बात है कि इसमें इतना समय लगता है। परिणामी फाइलें कितनी बड़ी थीं? Ps प्यार चित्र 4 और 5
ऑलिवरग्रिफिन

2
@donbright एक 3 ग्रेडर जो ईजीनवेक्टरों को समझ सकता है कि वास्तव में एक बहुत उज्ज्वल बच्चा होगा - मुझे यकीन नहीं है कि मेरे लिए उस स्तर पर एल्गोरिथम की व्याख्या करना संभव है। लेकिन मैं किसी भी तरह से कोशिश करता हूं: कल्पना करें कि हम चित्र को धातु की कठोर शीट पर प्रिंट करते हैं। फिर हम ध्यान से सभी काली रेखाओं को काट देते हैं और उन्हें लोचदार की तरह कुछ अधिक लचीली चीज़ से बदल देते हैं। तो सफेद हिस्से धातु की प्लेट हैं और काले हिस्से लचीले कपड़े हैं। अगला हम स्ट्रिंग से हवा में पूरी चीज लटकाते हैं, इसलिए यह स्थानांतरित करने के लिए स्वतंत्र है। अब अगर हम धातु की प्लेटों को टैप करते हैं, तो वे कंपन करेंगे ...
नथानिएल

2
@donbright (जारी) ... यह निर्भर करता है कि आपने धातु की प्लेट को कैसे मारा, यह अलग-अलग तरीकों से कंपन करेगा। हो सकता है कि कभी-कभी धातु के हिस्सों में से केवल एक ही कंपन करेगा और अन्य नहीं, लेकिन अन्य बार (क्योंकि वे लोचदार से जुड़े होते हैं), एक प्लेट से टकराने से एक और एक हिलना शुरू हो जाएगा। कंपन के इन विभिन्न तरीकों को कंपन मोड कहा जाता है । यह कार्यक्रम इस धातु प्लेट के कुछ कंपन मोड का अनुकरण करता है, लेकिन ध्वनि उत्पन्न करने के बजाय, यह उनका उपयोग करता है कि किस रंग को आकर्षित करना है।
नथानिएल

2
@donbright धातु प्लेटों के कंपन की कल्पना करने के लिए आप यहां और भी देख सकते हैं ।
नथानिएल

2
@donbright (यह अधिक तकनीकी व्याख्या भी आपको थोड़ा सा खो सकती है, लेकिन यह स्पष्टीकरण काम करता है क्योंकि प्लेट के कंपन मोडल की गणना एक आइजेनेवीक्टर गणना का उपयोग करके भी की जाती है। हालांकि यह संभव है कि यह समान गणना नहीं है जो मेरा कोड करता है - मैं हूं वास्तव में यकीन नहीं)।
नथानिएल

25

पायथन 2 + पीआईएल भी, मेरी पहली रंग पुस्तक

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

मैंने कारपेटपाइथन के रूप में काफी कुछ किया, सिवाय इसके कि मैं इस क्षेत्र को 'ग्रेडिएंट्स' से भरता हूं, और एक अलग रंग चक्र का उपयोग करता हूं।

मेरी सबसे भव्य रंग: यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

मेरी मशीन पर गणना समय:

  • छवि 1 (चीनी ड्रैगन): वास्तविक 0m2.862s उपयोगकर्ता 0m2.801s sys 0m0.061s

  • चित्र 2 (gryffon): वास्तविक 0m0.991 उपयोगकर्ता 0m0.963 sys 0m0.029s

  • छवि 3 (गेंडा ड्रैगन): वास्तविक 0m2.260s उपयोगकर्ता 0m2.239 sys 0m0.021s


अच्छा ग्रेडिएंट्स! जब आप पहले एक लूप के लिए लूप के लिए एक लूप के अंदर चिपके रहते हैं तो पहले वाले के अंदर और कुछ नहीं होता है?
ओलिवरग्रिफिन

ज़रूर तुम करना ! यह कॉपी / पेस्ट मुद्दा था है ...
dieter

23

पायथन 2 और पीआईएल: साइकेडेलिक वर्ल्ड्स

मैंने साइकलिंग पैलेट से एक रंग के साथ प्रत्येक सफेद-ईश क्षेत्र को भरने के लिए एक सरल एल्गोरिथ्म का उपयोग किया है। परिणाम बहुत रंगीन है, लेकिन बहुत जीवनकाल नहीं है।

ध्यान दें कि इन चित्रों में "सफेद" भाग बहुत सफेद नहीं हैं। आपको ग्रे के रंगों के लिए भी परीक्षण करना होगा।

पायथन 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)

उदाहरण चित्र:

एक रंगीन ड्रैगन

एलएसडी पर कद्दू


3
डरावना हिस्सा यह है कि रंग वास्तव में काम करने लगते हैं। आपको प्रत्येक छवि में कितने समय के लिए रंग लेना चाहिए और फाइलें कितनी बड़ी थीं?
ओलिवरग्रिफिन

1
कार्यक्रम लगभग 2 सेकंड में प्रत्येक छवि को रंग देता है। आउटपुट छवि आयाम इनपुट फ़ाइलों के समान हैं। फ़ाइल का आकार ज्यादातर मूल से 10% से 40% छोटा है (शायद इसलिए कि अलग jpeg संपीड़न सेटिंग्स का उपयोग किया जाता है)।
लॉजिक नाइट

3
मैं पूरी तरह से प्रभावित हूँ कि कोड कितना छोटा है! मुझे यह भी पसंद है कि आप प्रभावी रूप से उपयोग करने के लिए उपलब्ध रंगों को कैसे सीमित करते हैं, इस प्रकार एक सेट फूस पर रखते हुए। मैं वास्तव में इसे पसंद करता हूं, यह एक ग्रंज देता है (क्या यह सही शब्द है? मैं एक कलाकार नहीं हूं) वाइब।
ओलीवरग्रिफिन

@ ऑलिवरग्राफिन, मुझे खुशी है कि आप इसे पसंद करेंगे। मैं उज्ज्वल या गहरे रंगों के बिना एक पैलेट के लिए लक्ष्य कर रहा था, लेकिन अभी भी कुछ विपरीत है। इस रंग श्रेणी के सबसे सुखद परिणाम थे।
लॉजिक नाइट

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

हम एचएसवी कलरस्पेस का उपयोग करते हैं और सफेद क्षेत्रों के बीच सापेक्ष आकार के आधार पर प्रत्येक क्षेत्रों का चयन करते हैं। सबसे बड़ा क्षेत्र नीला ( Hue = 0.7) होगा और सबसे छोटा क्षेत्र बैंगनी ( Hue = 0.8) होगा। इन दो आकारों के बीच के क्षेत्रों को श्रेणी में Hues दिया जाता है 0.7 -> 1=0 -> 0.8। रेंज पर ह्यू फ़ंक्शन के संबंध में रैखिक रूप से चुना गया है area^0.15। प्रत्येक गैर-काले पिक्सेल के लिए संतृप्ति और मान हमेशा 1 होता है।

एक छवि को रंगने में कम से कम 1 सेकंड का समय लगता है।

बंद क्षेत्रों के साथ 3 चित्र जहां एल्गोरिदम शालीनता से काम करता है:

अजगर

एक और ड्रैगन

शायद एक और अजगर

और शेष चित्र:

अजगर

एक और ड्रैगन

शायद एक और अजगर

इन चित्रों पर बड़े सफेद जुड़े क्षेत्र हैं जिन्हें आदर्श रूप से कई रंगों से रंगा जाना चाहिए (यह समस्या नैथनील के समाधान में अच्छी तरह से हल की गई थी ।


कुछ सुंदर रंग समन्वित परिणामों के लिए अच्छा और छोटा कोड! मुझे यह पसंद है कि कैसे आपने क्षेत्र का उपयोग करने के लिए रंग निर्धारित करने में मदद की। औसत छवि को संसाधित करने में कितना समय लगा और यह अधिक विस्तृत चित्रों में से कुछ पर काम क्यों नहीं किया? क्या क्षेत्र बहुत छोटे थे?
ओलीवरग्रिफिन

1
@OliverGriffin ने मेरी पोस्ट में अनुरक्षण किया और बाकी चित्र जोड़े।
रैंडमरा

7

पिलो के साथ पायथन 3

इस उत्तर में शामिल करने के लिए कोड थोड़ा लंबा है, लेकिन यहाँ इसका सार है

  1. इनपुट छवि को लें और, यदि इसका एक अल्फा चैनल है, तो इसे एक सफेद पृष्ठभूमि पर संयोजित करें। (कम से कम चिकन छवि के लिए आवश्यक है, क्योंकि वह पूरी छवि काली थी, केवल पारदर्शिता द्वारा प्रतिष्ठित थी, इसलिए केवल अल्फा को गिराना मददगार नहीं था।)
  2. परिणाम को greyscale में बदलें; हम संपीड़न या एंटी-अलियासिंग कलाकृतियों, या ग्रे-लाइन्स-जो हमें-बहुत-ग्रे नहीं हैं, हमें गड़बड़ करने के लिए नहीं चाहते हैं।
  3. परिणाम की एक द्वि-स्तरीय (काले और सफेद) प्रतिलिपि बनाएँ। भूरे रंग के रंगों को काले या सफेद में परिवर्तित किया जाता है जो सफेद और छवि में सबसे गहरे छाया के बीच एक विन्यास योग्य कटऑफ सीमा पर आधारित होता है।
  4. छवि के प्रत्येक सफेद क्षेत्र को बाढ़-भरें। रंगों को यादृच्छिक रूप से चुना जाता है, एक चयन करने योग्य पैलेट का उपयोग करके जो बाढ़-भरने के संचालन के लिए शुरुआती बिंदु का स्थान लेता है।
  5. अपने निकटतम पड़ोसी रंगों के साथ काली रेखाओं में भरें। यह हमें हर रंग के क्षेत्र को काले रंग की सीमा में रखने से विरोधी अलियासिंग को पुन: प्रस्तुत करने में मदद करता है।
  6. चरण 2 से ग्रेस्केल छवि लें और उससे एक अल्फा मास्क बनाएं: सबसे गहरा रंग पूरी तरह से अपारदर्शी है, सबसे हल्का रंग पूरी तरह से पारदर्शी है।
  7. इस अल्फा मास्क का उपयोग करके चरण 5 से रंगीन छवि पर ग्रेस्केल छवि को संकलित करें।

उन आखिरी कुछ चरणों, दुर्भाग्यवश, अभी भी हल्के "हलोस" को समाप्त नहीं किया है जो गहरे रंग के क्षेत्रों में दिखाई देते हैं, लेकिन उन्होंने कम से कम ध्यान देने योग्य अंतर किया है। छवि प्रसंस्करण मेरे अध्ययन का क्षेत्र कभी नहीं था, इसलिए सभी के लिए मुझे पता है कि मैं यहाँ क्या करने की कोशिश करने के लिए अधिक सफल और अधिक कुशल एल्गोरिदम हूं ... लेकिन अच्छी तरह से।

अब तक, चरण 4 के लिए केवल दो चयन करने योग्य पट्टियाँ हैं: एक विशुद्ध रूप से यादृच्छिक एक, और एक बहुत ही मोटा "प्राकृतिक" एक, जो ऊपरी कोनों को आसमानी रंग, निचले कोनों को घास के रंग, भूरा (लकड़ी या लकड़ी) निर्दिष्ट करने की कोशिश करता है। ) प्रत्येक पक्ष के मध्य में रंग, और केंद्र के नीचे विविध रंग। सफलता मिली है ... सीमित।


उपयोग:

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

नमूने:

paint_by_prog.py -t 0.7 Gryphon-Lines.png रंगीन ग्रीफॉन

paint_by_prog.py Dragon-Tattoo-Outline.jpg रंगीन कार्टोनी ड्रैगन

paint_by_prog.py -t 0.85 -p natural The-Pumpkin-Farm-of-Good-old-Days.jpg रंगीन खेत का दृश्य

paint_by_prog.py -t 0.7 Dragon-OutLine.jpg कलर्ड ग्रंज ड्रैगन

paint_by_prog.py stejar-arbore-schiţă-natura.png रंगीन पेड़, बहुत झंडा-सा दिख रहा है

चिकन बहुत अच्छा नहीं लगता है, और लिंक छवि के लिए मेरा सबसे हालिया परिणाम सबसे अच्छा नहीं है; एक जो कोड के पुराने संस्करण से आया था, वह काफी हद तक पीला था, और इसके बारे में एक दिलचस्प रेगिस्तान खिंचाव था ...


प्रदर्शन:

प्रत्येक छवि को डिफ़ॉल्ट सेटिंग्स के साथ संसाधित करने में कुछ सेकंड लगते हैं, जिसका अर्थ है कि एक निकटतम निकटतम पड़ोसी एल्गोरिथ्म का उपयोग चरण 5 के लिए किया जाता है। सही निकटतम-पड़ोसी काफी धीमा है, शायद आधा मिनट लग रहा है (मैंने वास्तव में इसे समयबद्ध नहीं किया है)।


पहली छवि शानदार दिखती है, खासकर कि भूरी आंख। बहुत बढ़िया। मैं आपको हरी घास, कद्दू के भूरे रंग के खेतों और बैंगनी बादलों की सराहना करता हूं।
ओलिवरग्रिफिन

3

जावा

अपनी पसंद के रंग से यादृच्छिक रंग चयन।

चेतावनी: वर्तमान में क्षेत्र का पता लगाना बहुत धीमा है, जब तक कि सफेद क्षेत्र असामान्य रूप से छोटे न हों।

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

दो इनपुट की आवश्यकता है: फ़ाइल नाम, और पैलेट आईडी। कुछ एंटीलियासिंग सुधार शामिल हैं, लेकिन पारदर्शी पिक्सल के लिए तर्क शामिल नहीं है।

निम्नलिखित पट्टियाँ वर्तमान में मान्यता प्राप्त हैं:

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)

परिणाम:

ड्रैगन, गेम बॉय पैलेट:

यहाँ छवि विवरण दर्ज करें

अन्य ड्रैगन, नीला + हरा रंग:

यहाँ छवि विवरण दर्ज करें

GOL अभी भी जीवन मोना लिसा ( इस कार्यक्रम द्वारा प्रदान की गई ), तिरंगा पैलेट:

यहाँ छवि विवरण दर्ज करें


अपने रंग अनुकूलनशीलता के लिए +1! :) अगर आप एंटीएलियासिंग मुद्दे को ठीक कर सकते हैं तो यह और भी अच्छा लगेगा। इन छवियों को आउटपुट करने में आपको कितना समय लगा?
ओलीवरग्रिफिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.