कंप्यूटर जेनरेटेड वॉल पेंट


48

मेरे कमरे में दीवारों पर पेंट एक यादृच्छिक, लगभग भग्न की तरह, 3-आयामी बनावट है:

छवि ए

इस चुनौती में आप एक प्रोग्राम लिखेंगे, जो रैंडम इमेज बनाता है, जो ऐसा लगता है कि वे मेरी दीवारों का हिस्सा हो सकते हैं।

नीचे मैंने अपनी दीवारों पर विभिन्न स्थानों के 10 चित्र एकत्र किए हैं। सभी में लगभग समान प्रकाश व्यवस्था है और सभी को दीवार से एक फुट दूर कैमरे के साथ लिया गया था। सीमाएं समान रूप से उन्हें 2048 तक 2048 पिक्सेल बनाने के लिए क्रॉप किया गया था, फिर उन्हें 512 से 512 तक बढ़ाया गया। ऊपर की छवि छवि ए है।

ये केवल थंबनेल हैं, पूर्ण आकार में देखने के लिए चित्र पर क्लिक करें!

A: B: C: D: E:छवि ए छवि बी छवि सी छवि डी छवि ई

एफ: जी: एच: आई: जे:छवि एफ छवि जी छवि एच छवि I छवि जे

आपका कार्य एक प्रोग्राम लिखना है जो एक यादृच्छिक बीज के रूप में 1 से 2 16 तक सकारात्मक पूर्णांक में लेता है , और प्रत्येक मान के लिए एक अलग छवि उत्पन्न करता है जो दिखता है कि यह मेरी दीवार की "ग्यारहवीं छवि" हो सकती है। अगर कोई मेरी 10 छवियों को देख रहा है और आप में से कुछ भी यह नहीं बता सकते हैं कि कौन से कंप्यूटर उत्पन्न हुए हैं तो आपने बहुत अच्छा किया है!

कृपया अपनी उत्पन्न छवियों में से कुछ दिखाओ ताकि दर्शकों को कोड चलाने के बिना उन्हें देख सकें।

मुझे एहसास है कि मेरी छवियों में प्रकाश तीव्रता या रंग में पूरी तरह से समान नहीं है। मुझे इसके लिए खेद है लेकिन बेहतर प्रकाश व्यवस्था के उपकरण के बिना मैं यह सबसे अच्छा कर सकता हूं। आपकी छवियों को परिवर्तनीय प्रकाश व्यवस्था की आवश्यकता नहीं है (हालांकि वे कर सकते हैं)। बनावट पर ध्यान केंद्रित करने के लिए अधिक महत्वपूर्ण बात है।

विवरण

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

स्कोरिंग

यह एक लोकप्रियता प्रतियोगिता है इसलिए सबसे ज्यादा वोट पाने वाली उत्तर जीत है।


पेरलीनोइस + ट्रंकेशन + शेडिंग
ऑक्टोपस

21
मैं दीवार चित्र नहीं बना सकता, इसलिए इसके बजाय एक कॉमिक है !
Sp3000

8
@ Sp3000 कमोबेश यह कैसे हुआ। हालाँकि अगर मैं देख रहा हूँ कि मैंने शायद अपनी छत चुन ली है , जो काम भी कर सकती है ...
केल्विन के शौक

जवाबों:


65

GLSL (+ जावास्क्रिप्ट + वेबजीएल)

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

लाइव डेमो | गिटहब भंडार

कैसे इस्तेमाल करे

एक नई यादृच्छिक छवि के लिए पृष्ठ पुनः लोड करें। यदि आप किसी विशेष बीज को खिलाना चाहते हैं, तो अपने ब्राउज़र का कंसोल खोलें और कॉल करें drawScreen(seed)। कंसोल को लोड पर उपयोग किए गए बीज को प्रदर्शित करना चाहिए।

मैंने वास्तव में बहुत सारे प्लेटफार्मों पर इसका परीक्षण नहीं किया है, इसलिए मुझे बताएं कि क्या यह आपके लिए काम नहीं करता है। बेशक, आपके ब्राउज़र को WebGL का समर्थन करने की आवश्यकता है। त्रुटियों को या तो कॉलम में बाईं ओर प्रदर्शित किया जाता है, या ब्राउज़र के कंसोल में (त्रुटि के प्रकार के आधार पर)।

नई: अब आप "चल प्रकाश स्रोत" चेकबॉक्स पर टिक करके दीवारों को थोड़ा सा जीवन में ला सकते हैं।

ये क्या जादू है?

मुझे अपने GitHub खाते के आसपास यह WebGL बॉयलरप्लेट कोड तैरता हुआ मिला है , जिसका उपयोग मैं अब और फिर WebGL में कुछ 2D ग्राफिक्स चीजों को जल्दी से प्रोटोटाइप करने के लिए करता हूं। कुछ छायादार जादू के साथ, हम इसे थोड़ा 3 डी भी बना सकते हैं, इसलिए मैंने सोचा कि कुछ अच्छा प्रभाव प्राप्त करने का सबसे तेज़ तरीका है। अधिकांश सेटअप उस बॉयलरप्लेट कोड से है, और मैं विचार कर रहा हूं कि इस सबमिशन के लिए एक लाइब्रेरी है और इसे इस पोस्ट में शामिल नहीं करेंगे। यदि आप रुचि रखते हैं, तो GitHub (और उस फ़ोल्डर में अन्य फ़ाइलों) पर main.js पर एक नज़र डालें ।

सभी जावास्क्रिप्ट करता है एक WebGL संदर्भ स्थापित करने के लिए, shader के लिए एक समान रूप से बीज को स्टोर करें और फिर पूरे संदर्भ में एक ही क्वाड प्रस्तुत करें। वर्टेक्स शेडर एक साधारण पैशाच शेडर है, इसलिए सभी मैजिक फ्रैगमेंट शैडर में होता है। इसलिए मैंने इसे GLSL सबमिशन कहा है।

कोड का सबसे बड़ा हिस्सा वास्तव में सिंप्लेक्स शोर उत्पन्न करने के लिए है, जो मुझे गीथहब पर मिला । इसलिए मैं नीचे दिए कोड कोड को छोड़ रहा हूं। महत्वपूर्ण हिस्सा है, यह एक फ़ंक्शन को परिभाषित करता है snoise(vec2 coords)जो बनावट या सरणी लुकअप का उपयोग किए बिना सिम्प्लेक्स शोर लौटाता है। यह बिल्कुल भी बीज नहीं है, इसलिए अलग-अलग शोर होने की चाल यह है कि बीज को देखने के लिए यह निर्धारित करने में बीज का उपयोग करना है।

तो यहाँ जाता है:

#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable

uniform float uSeed;
uniform vec2 uLightPos;

varying vec4 vColor;
varying vec4 vPos;

/* ... functions to define snoise(vec2 v) ... */

float tanh(float x)
{
    return (exp(x)-exp(-x))/(exp(x)+exp(-x));
}

void main() {
    float seed = uSeed * 1.61803398875;
    // Light position based on seed passed in from JavaScript.
    vec3 light = vec3(uLightPos, 2.5);
    float x = vPos.x;
    float y = vPos.y;

    // Add a handful of octaves of simplex noise
    float noise = 0.0;
    for ( int i=4; i>0; i-- )
    {
        float oct = pow(2.0,float(i));
        noise += snoise(vec2(mod(seed,13.0)+x*oct,mod(seed*seed,11.0)+y*oct))/oct*4.0;
    }
    // Level off the noise with tanh
    noise = tanh(noise*noise)*2.0;
    // Add two smaller octaves to the top for extra graininess
    noise += sqrt(abs(noise))*snoise(vec2(mod(seed,13.0)+x*32.0,mod(seed*seed,11.0)+y*32.0))/32.0*3.0;
    noise += sqrt(abs(noise))*snoise(vec2(mod(seed,13.0)+x*64.0,mod(seed*seed,11.0)+y*64.0))/64.0*3.0;

    // And now, the lighting
    float dhdx = dFdx(noise);
    float dhdy = dFdy(noise);
    vec3 N = normalize(vec3(-dhdx, -dhdy, 1.0)); // surface normal
    vec3 L = normalize(light - vec3(vPos.x, vPos.y, 0.0)); // direction towards light source
    vec3 V = vec3(0.0, 0.0, 1.0); // direction towards viewpoint (straight up)
    float Rs = dot(2.0*N*dot(N,L) - L, V); // reflection coefficient of specular light, this is actually the dot product of V and and the direction of reflected light
    float k = 1.0; // specular exponent

    vec4 specularColor = vec4(0.4*pow(Rs,k));
    vec4 diffuseColor = vec4(0.508/4.0, 0.457/4.0, 0.417/4.0, 1.0)*dot(N,L);
    vec4 ambientColor = vec4(0.414/3.0, 0.379/3.0, 0.344/3.0, 1.0);

    gl_FragColor = specularColor + diffuseColor + ambientColor;
    gl_FragColor.a = 1.0;
}

बस। मैं कल कुछ और स्पष्टीकरण जोड़ सकता हूं, लेकिन मूल विचार यह है:

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

17
यह दीवार की तुलना में अधिक यथार्थवादी है: ओ
क्वेंटिन

1
कुछ और "नसें" / "सांप" / "कीड़े" इस चित्र को "दीवार" के लिए अधिक उपयुक्त बनाते हैं। लेकिन फिर भी अच्छा लगा।
नोवा

33

गणितज्ञ स्पैकलिंग

नीचे दिया गया ऐप एक बेतरतीब छवि के साथ धब्बेदार होता है। "नया पैच" पर क्लिक करने से काम करने के लिए एक नई यादृच्छिक छवि उत्पन्न होती है, और फिर वर्तमान सेटिंग्स के अनुसार प्रभाव लागू होता है। प्रभाव तेल चित्रकला, गाऊसी फ़िल्टर, पोस्टरीकरण और एम्बॉसिंग हैं। प्रत्येक प्रभाव को स्वतंत्र रूप से ट्विक किया जा सकता है। यादृच्छिक संख्या जनरेटर के लिए बीज 1 से 2 ^ 16 तक कोई भी पूर्णांक हो सकता है।

अद्यतन : गाऊसी फ़िल्टर, जो किनारों को नरम करता है, अब लागू किया गया अंतिम छवि प्रभाव है। इस संशोधन के साथ, पोस्टराइजेशन प्रभाव की अब आवश्यकता नहीं थी और इस प्रकार हटा दिया गया।

Manipulate[
 GaussianFilter[ImageEffect[ImageEffect[r, {"OilPainting", o}], {"Embossing", e, 1.8}], g],
 Button["new patch", (SeedRandom[seed] r = RandomImage[1, {400, 400}])], 
 {{o, 15, "oil painting"}, 1, 20, 1, ContinuousAction -> False, Appearance -> "Labeled"}, 
 {{e, 1.64, "embossing"}, 0, 5, ContinuousAction -> False, Appearance -> "Labeled"},
 {{g, 5, "Gaussian filter"}, 1, 12, 1, ContinuousAction -> False, Appearance -> "Labeled"},
 {{seed, 1}, 1, 2^16, 1, ContinuousAction -> False, Appearance -> "Labeled"}, 
 Initialization :> (SeedRandom[seed]; r = RandomImage[1, {400, 400}])]

अंतिम परिणाम


व्याख्या

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

चलो कुछ छवि प्रभावों को देखते हैं, एक बार में।

एक आरंभिक छवि बनाएं।

 r = RandomImage[1, {200, 200}]

यादृच्छिक छवि


लीना हमें दिखाएगी कि कैसे प्रत्येक छवि प्रभाव एक जीवन जैसी तस्वीर को बदल देता है।

Lena = ExampleData[{"TestImage", "Lena"}]

लीना


एक तेल चित्रकला प्रभाव लीना पर लागू होता है।

ImageEffect[Lena, {"OilPainting", 8}]

लीना तेल

एक तेल चित्रकला प्रभाव हमारी यादृच्छिक छवि पर लागू होता है। प्रभाव तेज (8 के बजाय 16) था।

 r1 = ImageEffect[r, {"OilPainting", 16}]

तेल


एक गाऊसी फ़िल्टर प्रभाव लीना पर लागू होता है (लीना के तेल चित्रकला प्रभाव संस्करण के लिए नहीं)। त्रिज्या 10 पिक्सेल है। (अंतिम संस्करण में, इस प्रविष्टि के शीर्ष पर, गाऊसीफिल्टर को अंतिम प्रभाव के रूप में लागू किया जाता है।)

 GaussianFilter[Lena, 10]

लीना गाऊसी


कुछ हद तक गॉसियन फ़िल्टर प्रभाव r1 पर लागू होता है। त्रिज्या 5 पिक्सेल है।

 r2 = GaussianFilter[r1, 5]

गॉस


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

 ImageEffect[Lena, {"Posterization", 2}]

लीना पोस्टर


आर 2 के लिए एक पोस्टराइजेशन प्रभाव लागू किया गया।

r3 = ImageEffect[r2, {"Posterization", 4}]

posterize


लीना को गले लगाना

 ImageEffect[Lena, {"Embossing", 1.2, 1.8}]

लीना एम्बॉसिंग


एम्बॉसिंग आर 3 इमेज प्रोसेसिंग को पूरा करता है। यह ओपी की छत की तरह कुछ देखने का इरादा है।

 ceilingSample = ImageEffect[r3, {"Embossing", 1.2, 1.8}]

उभारदार नक्क़ाशी करना


जिज्ञासु के लिए, यहाँ लीना को उसी छवि प्रभाव के साथ लागू किया गया है।

lena4


... लीना छवि प्राप्त करने के लिए एक अंतर्निहित है? जबरदस्त हंसी।
user253751

7
हाँ। छवि प्रसंस्करण परीक्षणों के लिए उपयोग किए जाने वाले गणितज्ञों में लगभग 30 अंतर्निहित चित्र हैं।
डेविड जेएन

एक मामूली संशोधन के साथ, एक RandomIntegerबीज खिला सकता है , जिससे एक विशेष आउटपुट की गारंटी मिलती है। या क्या आप कुछ और मतलब रखते हैं, जैसे कि शुरुआती, गैर-रैंडम छवि जिसमें प्रभाव लागू होते हैं?
डेविड जेएन

1
यह अब 1 से 2 ^ 16 तक एक बीज को स्वीकार करता है।
डेविड जेएन

1
+1 क्योंकि Lena will show us how each image effect transforms a life-like pictureमैंने LOL बनाया। अजीब बात है, अंतिम लीना छवि में एज़्टेक या इंका का सामना करना पड़ रहा है, एक हेडड्रेस पहने हुए और एक टहनी को रोते हुए मानो यह एक बंदूक थी।
स्तर नदी सेंट

13

पीओवी रे

बहुत सारी गोल्फिंग क्षमता, साथ चलते हैं povray /RENDER wall.pov -h512 -w512 -K234543 यहाँ छवि विवरण दर्ज करें

पहले यह एक यादृच्छिक बनावट बनाता है, लेकिन वहां रुकने के बजाय यह कैमरे के फ्लैश से रेडियल छाया को और अधिक यथार्थवादी बनाने के लिए बनावट को 3 डी-ऊंचाई के क्षेत्र में बदल देता है। और अच्छे उपाय के लिए यह शीर्ष पर छोटे धक्कों की एक और बनावट जोड़ता है।
यादृच्छिक बीज को हार्डकोड करने के अलावा एकमात्र तरीका clockएनिमेशन के लिए चर का उपयोग करना है , इसे -K{number}ध्वज के साथ पारित किया जाता है

#default{ finish{ ambient 0.1 diffuse 0.9 }} 

camera {location y look_at 0 right x}
light_source {5*y color 1}

#declare R1 = seed (clock); // <= change this

#declare HF_Function  =
 function{
   pigment{
     crackle turbulence 0.6
     color_map{
       [0.00, color 0.01]
       [0.10, color 0.05]
       [0.30, color 0.20]
       [0.50, color 0.31]
       [0.70, color 0.28]
       [1.00, color 0.26]
     }// end color_map
    scale <0.25,0.005,0.25>*0.7 
    translate <500*rand(R1),0,500*rand(R1)>
   } // end pigment
 } // end function

height_field{
  function  512, 512
  { HF_Function(x,0,y).gray * .04 }
  smooth 
  texture { pigment{ color rgb<0.6,0.55,0.5>}
            normal { bumps 0.1 scale 0.005}
            finish { phong .1 phong_size 400}
          } // end of texture  
  translate< -0.5,0.0,-0.5>
}

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