লাইন ব্যবহার করে একটি চিত্র পুনরুত্পাদন করুন


31

এমন একটি প্রোগ্রাম লিখুন যা সত্য রঙের আরজিবি চিত্র I , এল আঁকার জন্য সর্বাধিক সংখ্যক রেখা এবং প্রতিটি লাইনের সর্বনিম্ন মি এবং সর্বাধিক এম দৈর্ঘ্যের অন্তর্ভুক্ত থাকে Write আমার মতো যতটা সম্ভব দেখতে দেখতে একটি ছবি O আউটপুট করুন এবং এল বা তার চেয়ে কম সরল রেখা ব্যবহার করে আঁকা , এর সবগুলি মি এবং এম এর মধ্যে ইউক্যালিডিয়ান দৈর্ঘ্য রয়েছে ।

প্রতিটি লাইনে একটি একরঙা হতে হবে, সীমার উভয় এন্ড পয়েন্ট আছে হে , এবং ব্যবহার আকৃষ্ট করা Bresenham এর লাইন অ্যালগরিদম (যা অধিকাংশ গ্রাফিক্স লাইব্রেরি ইতিমধ্যে আপনার জন্য কি করতে হবে)। পৃথক লাইনগুলি কেবল 1 পিক্সেল পুরু হতে পারে।

সমস্ত লাইন এমনকি দৈর্ঘ্যের দৈর্ঘ্যেও কমপক্ষে একটি পিক্সেল নেওয়া উচিত। একে অপরের উপরে লাইনগুলি আঁকতে পারে।

কোনো লাইন অঙ্কন আগে আপনি পটভূমিতে আরম্ভ পারে হে কোনো কঠিন রঙ (যে উপর নির্ভর করে হতে পারে আমি )।

বিস্তারিত

  • হে হিসাবে একই মাত্রা থাকা উচিত আমি
  • এল সর্বদা একটি নন-নেটিভ পূর্ণসংখ্যা হবে। এটি আই এর চেয়েও বড় হতে পারে ।
  • এম এবং এম হ'ল এম > = মি সহ নন-নেগেটিভ ফ্লোটিং পয়েন্ট সংখ্যা । দুটি পিক্সেলের মধ্যে দূরত্ব হ'ল তাদের কেন্দ্রগুলির মধ্যে ইউক্লিডিয়ান দূরত্ব। যদি এই দূরত্বটি মিটার থেকে কম বা এম এর চেয়ে বেশি হয় তবে those পিক্সেলের মধ্যে একটি লাইন অনুমোদিত নয়।
  • লাইনগুলি অ্যান্টিঅ্যালিয়াস করা উচিত নয়।
  • অস্বচ্ছতা এবং আলফা ব্যবহার করা উচিত নয়।
  • আপনার প্রোগ্রামটি এক মিলিয়ন পিক্সেলের চেয়ে কম এল এবং 10,000 এর চেয়ে কম এল এর চিত্রগুলিতে একটি শালীন আধুনিক কম্পিউটারে চালাতে এক ঘণ্টার বেশি সময় নেওয়া উচিত নয় ।

চিত্র পরীক্ষা করুন

আপনি অবশ্যই আপনার সবচেয়ে সঠিক বা আকর্ষণীয় আউটপুট চিত্র (যা আমি ঘটবে যখন আশা দেখানো উচিত এল 5% এবং পিক্সেলের সংখ্যা 25% মধ্যে আমি , আর মি এবং এম প্রায় তির্যক আকার এক দশমাংশ হয়)।

এখানে কয়েকটি পরীক্ষামূলক চিত্র দেওয়া হয়েছে (মূলগুলির জন্য ক্লিক করুন) আপনি নিজের পোস্টও করতে পারেন।

মোনালিসা জলপ্রপাত Nighthawks তারকাময় রাত গোল্ডেন গেট ব্রিজ

সহজ চিত্রগুলি:

পেনরোজ সিঁড়িমোবিয়াস ফালা হিলবার্ট কার্ভ

এটি একটি জনপ্রিয়তা প্রতিযোগিতা। সর্বাধিক ভোটগ্রহণ জমা জিতেছে।

নোট

  • আই এর মোট পিক্সেলের শতকরা হারের সাথে সাথে একটি নিখুঁত মান থেকে এলকে উত্সাহিত করা সহায়ক হতে পারে be যেমন একই জিনিস হতে যেমন হবে যদি একটি 8 দ্বারা 8 পিক্সেল ইমেজ ছিল। অনুরূপ কিছু কাজ করা যেতে পারে মি এবং এম । এটি প্রয়োজন হয় না।>>> imageliner I=img.png L=50% m=10 M=20>>> imageliner I=img.png L=32 m=10 M=20img.png
  • যেহেতু লাইনগুলি সীমার বাইরে যেতে পারে না, তাই দীর্ঘতম লাইনগুলি হবে I এর তির্যক দৈর্ঘ্য । এর চেয়ে এম উচ্চতর হওয়া কিছু ভাঙা উচিত নয়।
  • স্বাভাবিকভাবেই, যদি মি 0 এবং এল চেয়ে মহান বা পিক্সেল সংখ্যার সমান আমি , হে অভিন্ন হতে পারে আমি প্রতিটি পিক্সেল অবস্থানে দৈর্ঘ্য হল 0 "লাইন" না থাকার। এই আচরণের প্রয়োজন হয় না।
  • যুক্তিযুক্তভাবে, রঙের পুনরুত্পাদন করার চেয়ে আমি আকৃতির পুনরুত্পাদন করা আরও গুরুত্বপূর্ণ। আপনি প্রান্ত সনাক্তকরণ সন্ধান করতে চাইতে পারেন ।

স্পষ্ট করার জন্য: সিম্পলসিভির মতো লাইব্রেরি কি অনুমোদিত? এবং উত্তরগুলির এম = 0 এবং এল = ক্ষেত্র সহ আমি, এল, মি, এবং এম এর জন্য কোনও পছন্দ থাকতে পারে?
যৌক্তিক

@ এপিকুইজডম হ্যাঁ, সমস্ত গ্রন্থাগারকে (ইতিমধ্যে বিশেষত এই কাজটি করা জিনিসগুলি বাদে) অনুমতি দেওয়া হয়েছে। কী-পয়েন্টগুলি ব্যবহার করুন, প্রান্ত সনাক্তকরণ, যাই হোক না কেন নির্দ্বিধায় ব্যবহার করুন। আপনার অ্যালগরিদমে আই , এল , এম , এম এর যে কোনও বৈধ পছন্দগুলির জন্য কাজ করা উচিত , এতে এম = 0 এবং এল = অঞ্চল অন্তর্ভুক্ত রয়েছে । (অবশ্যই, আপনার অ্যালগরিদমটি প্যারামিটারগুলির নির্দিষ্ট টিউনগুলির জন্য আরও ভাল লাগতে পারে
ক্যালভিনের

তাহলে, উদাহরণস্বরূপ, এই নির্দিষ্ট গ্রন্থাগারের অ্যালগরিদমটি একটি অবৈধ উত্তর হিসাবে বিবেচিত হবে?
যুক্তিযুক্ত

@ পেপুইজডম আসলে আমি এটি এবং অন্যান্য অনুরূপ জিনিসগুলিকে অনুমতি দেব। দেখে মনে হচ্ছে এটি আপনার দেওয়া রেখাগুলির বাইরে কোনও চিত্র তৈরি করতে এখনও কিছু চতুর টুইট করছে aking
ক্যালভিনের শখ

1
লাইনগুলি কি 1 এর বেধ হওয়া দরকার?
অদিতসু

উত্তর:


21

সি ++ - কিছুটা এলোমেলো লাইন এবং তারপরে কিছু

প্রথমে কিছু এলোমেলো লাইন

অ্যালগরিদমের প্রথম ধাপটি এলোমেলোভাবে রেখাগুলি উত্পন্ন করে, লক্ষ্য চিত্রের সাথে এটির পাশাপাশি গড়ে পিক্সেলগুলি নেয় এবং তারপরে গণনা করা হয় যে আমরা নতুন পংক্তিটি আঁকলে সমস্ত পিক্সেলের rgb স্থানের দূরত্বের সংক্ষিপ্ত বর্গটি কম হবে কিনা (এবং কেবল এটি আঁকুন, যদি তা হয়)। এর জন্য নতুন লাইনের রঙটি -15 / + 15 এলোমেলো সংযোজন সহ আরজিবি মানের চ্যানেল অনুসারে গড় হিসাবে বেছে নেওয়া হয়েছে।

আমি যে জিনিসগুলি লক্ষ্য করেছি এবং প্রয়োগকে প্রভাবিত করেছি:

  • প্রাথমিক রঙটি সম্পূর্ণ চিত্রের গড়। এটি সাদা করার সময় যেমন মজাদার প্রভাবগুলির বিরুদ্ধে লড়াই করতে পারে এবং অঞ্চলটি কালো হয়, তবে ইতিমধ্যে একটি উজ্জ্বল সবুজ রেখা হিসাবে কিছু ভাল দেখা যায়, কারণ এটি ইতিমধ্যে সাদা রঙের চেয়ে কালো কাছাকাছি।
  • লাইনটির জন্য খাঁটি গড় রঙ নেওয়া এতটা ভাল নয় কারণ এটি পরবর্তী লাইনে ওভাররাইট করে হাইলাইট উত্পন্ন করতে অক্ষম হয়ে পড়ে। কিছুটা এলোমেলো বিচ্যুতিটি কিছুটা সহায়তা করে, তবে আপনি যদি তারার রাতে দেখেন তবে অনেক জায়গায় স্থানীয় বৈসাদৃশ্য বেশি থাকলে এটি ব্যর্থ হয়।

আমি কয়েকটি নম্বর নিয়ে পরীক্ষা নিরীক্ষা করছিলাম এবং বেছে বেছে L=0.3*pixel_count(I)বামে m=10এবং M=50। এটা চমৎকার ফল প্রায় শুরু হবে 0.25করতে 0.26লাইন সংখ্যার জন্য, কিন্তু আমি 0.3 বেছে নেওয়া হয়েছে সঠিক বিবরণের জন্য আরও জায়গা আছে।

পূর্ণ আকারের সোনার গেট চিত্রের জন্য, এর ফলে 235929 লাইনগুলি আঁকা যায় (যার জন্য এটি এখানে পুরো 13 সেকেন্ড সময় নিয়েছিল)। নোট করুন যে এখানে সমস্ত চিত্র হ্রাস আকারে প্রদর্শিত হবে এবং সম্পূর্ণ রেজোলিউশনটি দেখার জন্য আপনাকে সেগুলি একটি নতুন ট্যাবে খুলতে হবে / ডাউনলোড করতে হবে।

অযোগ্যদের মুছুন

পরবর্তী পদক্ষেপটি ব্যয়বহুল (235 কে লাইনের জন্য এটি প্রায় এক ঘন্টা সময় নিয়েছিল, তবে এটি "1 মেগাপিক্সেলের 10k লাইনের জন্য এক ঘন্টা" সময়ের প্রয়োজনের মধ্যে ভাল হওয়া উচিত) তবে এটি কিছুটা অবাক করার মতোও। আমি পূর্ববর্তী সমস্ত আঁকা লাইনগুলি দিয়ে যাচ্ছি এবং চিত্রগুলি আরও ভাল করে না এমনগুলি সরিয়ে ফেলছি। এটি আমাকে এই রানে কেবল 97347 লাইন দিয়ে রেখেছিল যা নিম্নলিখিত চিত্র উত্পাদন করে:

বেশিরভাগ পার্থক্য চিহ্নিত করার জন্য আপনার সম্ভবত একটি উপযুক্ত চিত্র দর্শকের মধ্যে তাদের ডাউনলোড এবং তুলনা করতে হবে।

এবং আবার শুরু

এখন আমার কাছে প্রচুর লাইন রয়েছে যা আমি আবারও আঁকতে পারি মোট আবার 235929। বেশি কিছু বলার নেই, তাই এখানে চিত্রটি রয়েছে:

এখানে চিত্র বর্ণনা লিখুন

সংক্ষিপ্ত বিশ্লেষণ

পুরো প্রক্রিয়াটি অস্পষ্ট ফিল্টারের মতো কাজ করে যা স্থানীয় বিপরীতে এবং বস্তুর আকারের সংবেদনশীল। তবে লাইনগুলি কোথায় আঁকা হয়েছে তাও আকর্ষণীয়, সুতরাং প্রোগ্রামগুলি এগুলিও রেকর্ড করে (প্রতিটি লাইনের জন্য পিক্সেলের রঙ এক ধাপ সাদা হয়ে যাবে, শেষে বৈসাদৃশ্যটি সর্বাধিক করা হবে)। উপরে বর্ণিত তিনটি বর্ণের সাথে এখানে সম্পর্কিত are

অ্যানিমেশন

এবং যেহেতু আমরা সকলেই অ্যানিমেশন পছন্দ করি, তাই ছোট সোনার গেট চিত্রের জন্য পুরো প্রক্রিয়াটির কয়েকটি অ্যানিমেটেড জিআইএফ দেওয়া আছে। নোট করুন যে জিআইএফ ফর্ম্যাটের কারণে উল্লেখযোগ্য দুরত্ব রয়েছে (এবং যেহেতু সত্য রঙের অ্যানিমেশন ফাইল ফর্ম্যাট এবং ব্রাউজার নির্মাতারা তাদের উদ্বোধনের বিরুদ্ধে যুদ্ধে রয়েছে, সত্য রঙের অ্যানিমেশনগুলির জন্য কোনও স্ট্যান্ডার্ড ফর্ম্যাট নেই, অন্যথায় আমি একটি .mng বা অনুরূপ যোগ করতে পারতাম )।

আরো কিছু

অনুরোধ অনুসারে, এখানে অন্যান্য চিত্রের কিছু ফলাফল দেওয়া হয়েছে (এগুলি পুনরায় না ফেলে দেওয়ার জন্য আপনাকে আবার এগুলি একটি নতুন ট্যাবে খোলার প্রয়োজন হতে পারে)

ভবিষ্যতের চিন্তাভাবনা

কোডটি নিয়ে চারপাশে খেলে কিছু আকর্ষণীয় বৈচিত্র পাওয়া যায়।

  • গড়ের উপর ভিত্তি করে এলোমেলোভাবে লাইনের রং বেছে নিন। আপনার দুটি চক্রেরও বেশি প্রয়োজন হতে পারে।
  • পেস্টবিনের কোডটিতে জিনগত অ্যালগরিদমের কিছু ধারণা রয়েছে তবে চিত্রটি ইতিমধ্যে এতটাই ভাল যে এটি অনেক বেশি প্রজন্ম নিয়েছে এবং এই কোডটি "এক ঘন্টা" নিয়মের সাথে মানানসইভাবেও ধীর slow
  • মুছে ফেলা / পুনরায় রঙ করা, বা এমনকি দুটি ...
  • যেখানে লাইনগুলি মুছে ফেলা যায় তার সীমা পরিবর্তন করুন (উদাঃ "অবশ্যই চিত্রটিকে আরও ভালভাবে তৈরি করা উচিত")

কোড

এটি কেবলমাত্র দুটি প্রধান দরকারী ফাংশন, পুরো কোডটি এখানে ফিট করে না এবং এটি http://ideone.com/Z2P6L তে পাওয়া যাবে

bmpক্লাস rawএবং raw_lineফাংশন একটি বস্তু যে বিন্যাস বিএমপি লেখা যাবে যথাক্রমে এক্সেস পিক্সেল এবং লাইন না (এটা শুধু কিছু হ্যাক প্রায় মিথ্যা ছিল এবং আমি ভেবেছিলাম যে এই কিছুটা কোনো লাইব্রেরি থেকে স্বাধীন করে তোলে)।

ইনপুট ফাইলের ফর্ম্যাটটি পিপিএম

std::pair<bmp,std::vector<line>>  paint_useful( const bmp& orig, bmp& clone, std::vector<line>& retlines, bmp& layer, const std::string& outprefix, size_t x, size_t y )
{
        const size_t pixels = (x*y);
        const size_t lines = 0.3*pixels;
//      const size_t lines = 10000;

//      const size_t start_accurate_color = lines/4;

        std::random_device rnd;

        std::uniform_int_distribution<size_t> distx(0,x-1);
        std::uniform_int_distribution<size_t> disty(0,y-1);
        std::uniform_int_distribution<size_t> col(-15,15);
        std::uniform_int_distribution<size_t> acol(0,255);

        const ssize_t m = 1*1;
        const ssize_t M = 50*50;

        retlines.reserve( lines );

        for (size_t i = retlines.size(); i < lines; ++i)
        {
                size_t x0;
                size_t x1;

                size_t y0;
                size_t y1;

                size_t dist = 0;
                do
                {
                        x0 = distx(rnd);
                        x1 = distx(rnd);

                        y0 = disty(rnd);
                        y1 = disty(rnd);

                        dist = distance(x0,x1,y0,y1);
                }
                while( dist > M || dist < m );

                std::vector<std::pair<int32_t,int32_t>> points = clone.raw_line_pixels(x0,y0,x1,y1);

                ssize_t r = 0;
                ssize_t g = 0;
                ssize_t b = 0;

                for (size_t i = 0; i < points.size(); ++i)
                {
                        r += orig.raw(points[i].first,points[i].second).r;
                        g += orig.raw(points[i].first,points[i].second).g;
                        b += orig.raw(points[i].first,points[i].second).b;
                }

                r += col(rnd);
                g += col(rnd);
                b += col(rnd);

                r /= points.size();
                g /= points.size();
                b /= points.size();

                r %= 255;
                g %= 255;
                b %= 255;

                r = std::max(ssize_t(0),r);
                g = std::max(ssize_t(0),g);
                b = std::max(ssize_t(0),b);

//              r = acol(rnd);
//              g = acol(rnd);
//              b = acol(rnd);

//              if( i > start_accurate_color )
                {
                        ssize_t dp = 0; // accumulated distance of new color to original
                        ssize_t dn = 0; // accumulated distance of current reproduced to original
                        for (size_t i = 0; i < points.size(); ++i)
                        {
                                dp += rgb_distance(
                                                                                orig.raw(points[i].first,points[i].second).r,r,
                                                                                orig.raw(points[i].first,points[i].second).g,g,
                                                                                orig.raw(points[i].first,points[i].second).b,b
                                                                        );

                                dn += rgb_distance(
                                                                                clone.raw(points[i].first,points[i].second).r,orig.raw(points[i].first,points[i].second).r,
                                                                                clone.raw(points[i].first,points[i].second).g,orig.raw(points[i].first,points[i].second).g,
                                                                                clone.raw(points[i].first,points[i].second).b,orig.raw(points[i].first,points[i].second).b
                                                                        );

                        }

                        if( dp > dn ) // the distance to original is bigger, use the new one
                        {
                                --i;
                                continue;
                        }
                        // also abandon if already too bad
//                      if( dp > 100000 )
//                      {
//                              --i;
//                              continue;
//                      }
                }

                layer.raw_line_add(x0,y0,x1,y1,{1u,1u,1u});
                clone.raw_line(x0,y0,x1,y1,{(uint32_t)r,(uint32_t)g,(uint32_t)b});
                retlines.push_back({ (int)x0,(int)y0,(int)x1,(int)y1,(int)r,(int)g,(int)b});

                static time_t last = 0;
                time_t now = time(0);
                if( i % (lines/100) == 0 )
                {
                        std::ostringstream fn;
                        fn << outprefix + "perc_" << std::setw(3) << std::setfill('0') << (i/(lines/100)) << ".bmp"; 
                        clone.write(fn.str());
                        bmp lc(layer);
                        lc.max_contrast_all();
                        lc.write(outprefix + "layer_" + fn.str());
                }

                if( (now-last) > 10 )
                {
                        last = now;
                        static int st = 0;
                        std::ostringstream fn;
                        fn << outprefix + "inter_" << std::setw(8) << std::setfill('0') << i << ".bmp";
                        clone.write(fn.str());

                        ++st;
                }
        }
        clone.write(outprefix + "clone.bmp");
        return { clone, retlines };
}


void erase_bad( std::vector<line>& lines, const bmp& orig )
{
        ssize_t current_score = evaluate(lines,orig);

        std::vector<line> newlines(lines);

        uint32_t deactivated = 0;
        std::cout << "current_score = " << current_score << "\n";
        for (size_t i = 0; i < newlines.size(); ++i)
        {
                newlines[i].active = false;
                ssize_t score = evaluate(newlines,orig);
                if( score > current_score )
                {
                        newlines[i].active = true;
                }
                else
                {
                        current_score = score;
                        ++deactivated;
                }
                if( i % 1000 == 0 )
                {
                        std::ostringstream fn;
                        fn << "erase_" << std::setw(6) << std::setfill('0') << i << ".bmp";
                        bmp tmp(orig);
                        paint(newlines,tmp);
                        tmp.write(fn.str());
                        paint_layers(newlines,tmp);
                        tmp.max_contrast_all();
                        tmp.write("layers_" + fn.str());
                        std::cout << "\r i = " << i << std::flush;
                }
        }
        std::cout << "\n";
        std::cout << "current_score = " << current_score << "\n";
        std::cout << "deactivated = " << deactivated << "\n";


        bmp tmp(orig);

        paint(newlines,tmp);
        tmp.write("newlines.bmp");
        lines.clear();
        for (size_t i = 0; i < newlines.size(); ++i)
        {
                if( newlines[i].is_active() )
                {
                        lines.push_back(newlines[i]);
                }
        }
}

+1, সত্যিই খুব সুন্দর। অন্যান্য পরীক্ষার চিত্রগুলির জন্য আপনার কি ফলাফল আছে?
নাথানিয়েল

1
@ নাথানিয়েল: আমি কিছু যোগ করেছি। "সরল" চিত্রগুলি বিনোদনের জন্য কারণ বিনোদন প্রায় পিক্সেল নিখুঁত।
প্লাজমাএইচ

17

জাভা - এলোমেলো লাইন

একটি খুব প্রাথমিক সমাধান যা এলোমেলো রেখাগুলি অঙ্কন করে এবং তাদের জন্য উত্সের চিত্রের গড় রঙ গণনা করে। পটভূমি রঙ উত্স গড় রঙে সেট করা আছে।

এল = 5000, মি = 10, এম = 50

এখানে চিত্র বর্ণনা লিখুন

এল = 10000, মি = 10, এম = 50

এখানে চিত্র বর্ণনা লিখুন

সম্পাদনা

আমি একটি জেনেটিক অ্যালগরিদম যুক্ত করেছি যা জনসংখ্যার রেখা পরিচালনা করে। প্রতিটি প্রজন্মের মধ্যে আমরা কেবল 50% সেরা লাইন রাখি, অন্যগুলিকে ফেলে রাখি এবং এলোমেলোভাবে নতুন তৈরি করি। লাইনগুলি রাখার মানদণ্ডগুলি হ'ল:

  • উত্স চিত্রের রঙগুলির সাথে তাদের দূরত্ব কম
  • অন্যান্য লাইনের সাথে ছেদ সংখ্যার সংখ্যা (আরও কম ভাল)
  • তাদের দৈর্ঘ্য (আরও ভালতর)
  • নিকটতম প্রতিবেশীর সাথে তাদের কোণ (আরও কম ভাল)

আমার দুর্দান্ত হতাশার জন্য, অ্যালগরিদমটি চিত্রের মানের উন্নতি করতে পারে বলে মনে হয় না :-( শুধু লাইনগুলি আরও সমান্তরাল হয়ে উঠছে।

প্রথম প্রজন্ম (5000 লাইন)

এখানে চিত্র বর্ণনা লিখুন

দশম প্রজন্ম (5000 লাইন)

এখানে চিত্র বর্ণনা লিখুন

প্যারামিটার নিয়ে খেলছে

এখানে চিত্র বর্ণনা লিখুনএখানে চিত্র বর্ণনা লিখুনএখানে চিত্র বর্ণনা লিখুন

package line;

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;

import snake.Image;

public class Lines {

    private final static int NB_LINES = 5000;
    private final static int MIN_LENGTH = 10;
    private final static int MAX_LENGTH = 50;

    public static void main(String[] args) throws IOException {     
        BufferedImage src = ImageIO.read(Image.class.getClassLoader().getResourceAsStream("joconde.png"));
        BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);


        int [] bgColor = {0, 0, 0};
        int avgRed = 0, avgGreen = 0, avgBlue = 0, count = 0;
        for (int y = 0; y < src.getHeight(); y++) {
            for (int x = 0; x < src.getWidth(); x++) {
                int colsrc = src.getRGB(x, y);
                avgRed += colsrc & 255;
                avgGreen += (colsrc >> 8) & 255;
                avgBlue += (colsrc >> 16) & 255;
                count++;
            }
        }

        bgColor[0] = avgBlue/count; bgColor[1] = avgGreen/count; bgColor[2] = avgRed/count;
        for (int y = 0; y < src.getHeight(); y++) {
            for (int x = 0; x < src.getWidth(); x++) {
                dest.getRaster().setPixel(x, y, bgColor);
            }
        }
        List<List<Point>> lines = new ArrayList<List<Point>>();
        Random rand = new Random();
        for (int i = 0; i < NB_LINES; i++) {
            int length = rand.nextInt(MAX_LENGTH - MIN_LENGTH) + MIN_LENGTH;
            double ang = rand.nextDouble() * Math.PI;
            int lx = (int)(Math.cos(ang) * length); // can be negative or positive
            int ly = (int)(Math.sin(ang) * length); // positive only
            int sx = rand.nextInt(dest.getWidth() -1 - Math.abs(lx));
            int sy = rand.nextInt(dest.getHeight() - 1- Math.abs(ly));
            List<Point> line;
            if (lx > 0) {
                line = line(sx, sy, sx+lx, sy+ly);
            } else {
                line = line(sx+Math.abs(lx), sy, sx, sy+ly);
            }
            lines.add(line);    
        }

        // render the picture
        int [] color = {0, 0, 0};
        for (List<Point> line : lines) {

            avgRed = 0; avgGreen = 0; avgBlue = 0;
            count = 0;
            for (Point p : line) {
                int colsrc = src.getRGB(p.x, p.y);
                avgRed += colsrc & 255;
                avgGreen += (colsrc >> 8) & 255;
                avgBlue += (colsrc >> 16) & 255;
                count++;
            }
            avgRed /= count; avgGreen /= count; avgBlue /= count;
            color[0] = avgBlue; color[1] = avgGreen; color[2] = avgRed;
            for (Point p : line) {
                dest.getRaster().setPixel(p.x, p.y, color);
            }

        }
        ImageIO.write(dest, "png", new File("a0.png"));

    }

    private static List<Point> line(int x0, int y0, int x1, int y1) {
        List<Point> points = new ArrayList<Point>();
        int deltax = x1 - x0;
        int deltay = y1 - y0;
        int tmp;
        double error = 0;       
        double deltaerr = 0;
        if (Math.abs(deltax) >= Math.abs(deltay)) {
            if (x0 > x1) { // swap the 2 points
                tmp = x0; x0 = x1; x1 = tmp;
                tmp = y0; y0 = y1; y1 = tmp;
                deltax = - deltax; deltay = -deltay;
            }
            deltaerr = Math.abs (((double)deltay) / deltax); 
            int y = y0;
            for (int x = x0; x <= x1; x++) {
                points.add(new Point(x, y));
                error += deltaerr;
                if (error >= 0.5) {
                    if (y0 < y1) y++; else y--;
                    error -= 1.0;
                }
            }
        } else {
            if (y0 > y1) { // swap the 2 points
                tmp = x0; x0 = x1; x1 = tmp;
                tmp = y0; y0 = y1; y1 = tmp;
                deltax = - deltax; deltay = -deltay;
            }
            deltaerr = Math.abs (((double)deltax) / deltay);   // Assume deltay != 0 (line is not horizontal),
            int x = x0;
            for (int y = y0; y <= y1; y++) {
                points.add(new Point(x, y));
                error += deltaerr;
                if (error >= 0.5) {
                    if (x0 < x1) x++; else x--;
                    error -= 1.0;
                }
            }
        }
        return points;
    }
}

অবশেষে কেউ উত্তর দিয়েছে: ডি আমি আরও উদাহরণ দেখতে পছন্দ করব।
ক্যালভিনের

@ ক্যালভিন শিওর এই মুহুর্তে আমি জনসংখ্যার রেখাকে ধরে রেখে অ্যালগরিদমকে উন্নত করার কাজ করছি, এবং যেমন ২০% খারাপকে মুছে ফেলা এবং নতুনগুলি পুনরায় জেনারেট করা (একরকম জেনেটিক অ্যালগরিদম)
আরনাড

আমার মনে এ জাতীয় কিছু ছিল, তবে এটি লেখার সময় নেই। জেনেটিক আলগের অপেক্ষায় রইলাম। ফলাফল :)
অদিতসু

সম্ভবত আপনি আরও ছোট কোণ মাপদণ্ড সরাতে চান? কেন রেখেছিলে? মূল চিত্রটি দেখতে দুর্দান্ত দেখাচ্ছে যদিও রেখাগুলিতে ছোট ছেদ কোণ নেই।
জাস্টহেল্ফ

পুনঃটুইট আমি চিত্রকর ব্রাশ অনুকরণের প্রয়াসে কোণ মাপদণ্ড যুক্ত করেছি।
Arnaud

9

সি - সরল রেখা

সি তে একটি প্রাথমিক পদ্ধতির যা পিপিএম ফাইলগুলিতে কাজ করে। অ্যালগরিদম সমস্ত পিক্সেল পূরণ করার জন্য অনুকূল লাইন দৈর্ঘ্যের সাথে উল্লম্ব রেখা স্থাপন করার চেষ্টা করে। ব্যাকগ্রাউন্ড রঙ এবং লাইন রংগুলি মূল চিত্রের (প্রতিটি রঙের চ্যানেলের মধ্যম) গড় মূল্য হিসাবে গণনা করা হয়:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define SIGN(x) ((x > 0) ? 1 : (x < 0) ? -1 : 0)
#define MIN(x, y) ((x > y) ? y : x)
#define MAX(x, y) ((x > y) ? x : y)

typedef struct {
    size_t width;
    size_t height;

    unsigned char *r;
    unsigned char *g;
    unsigned char *b;
} image;

typedef struct {
    unsigned char r;
    unsigned char g;
    unsigned char b;
} color;

void init_image(image *data, size_t width, size_t height) {
    data->width = width;
    data->height = height;
    data->r = malloc(sizeof(data->r) * data->width * data->height);
    data->g = malloc(sizeof(data->g) * data->width * data->height);
    data->b = malloc(sizeof(data->b) * data->width * data->height);
}

#define BUFFER_LEN 1024
int load_image(const char *filename, image* data) {
    FILE *f = fopen(filename, "r");
    char buffer[BUFFER_LEN];          /* read buffer */
    size_t max_value;
    size_t i;
    fgets(buffer, BUFFER_LEN, f);
    if (strncmp(buffer, "P3", 2) != 0) {
        printf("File begins with %s instead of P3\n", buffer);
        return 0;
    }

    fscanf(f, "%u", &data->width);
    fscanf(f, "%u", &data->height);
    fscanf(f, "%u", &max_value);
    assert(max_value==255);

    init_image(data, data->width, data->height);

    for (i = 0; i < data->width * data->height; i++) {
        fscanf(f, "%hhu", &(data->r[i]));
        fscanf(f, "%hhu", &(data->g[i]));
        fscanf(f, "%hhu", &(data->b[i]));
    }
    fclose(f);

    printf("Read %zux%zu pixels from %s.\n", data->width, data->height, filename);
}

int write_image(const char *filename, image *data) {
    FILE *f = fopen(filename, "w");
    size_t i;
    fprintf(f, "P3\n%zu %zu\n255\n", data->width, data->height);
    for (i = 0; i < data->width * data->height; i++) {
        fprintf(f, "%hhu %hhu %hhu ", data->r[i], data->g[i], data->b[i]);
    }
    fclose(f);
}

unsigned char average(unsigned char *data, size_t data_len) {
    size_t i;
    size_t j;
    size_t hist[256];

    for (i = 0; i < 256; i++) hist[i] = 0;
    for (i = 0; i < data_len; i++) hist[data[i]]++;
    j = 0;
    for (i = 0; i < 256; i++) {
        j += hist[i];
        if (j >= data_len / 2) return i;
    }
    return 255;
}

void set_pixel(image *data, size_t x, size_t y, unsigned char r, unsigned char g, unsigned char b) {
    data->r[x + data->width * y] = r;
    data->g[x + data->width * y] = g;
    data->b[x + data->width * y] = b;
}

color get_pixel(image *data, size_t x, size_t y) {
    color ret;
    ret.r = data->r[x + data->width * y];
    ret.g = data->g[x + data->width * y];
    ret.b = data->b[x + data->width * y];
    return ret;
}

void fill(image *data, unsigned char r, unsigned char g, unsigned char b) {
    size_t i;
    for (i = 0; i < data->width * data->height; i++) {
        data->r[i] = r;
        data->g[i] = g;
        data->b[i] = b;
    }
}

void line(image *data, size_t x1, size_t y1, size_t x2, size_t y2, unsigned char r, unsigned char g, unsigned char b) {
    size_t x, y, t, pdx, pdy, ddx, ddy, es, el;
    int dx, dy, incx, incy, err;

    dx=x2-x1;
    dy=y2-y1;
    incx=SIGN(dx);
    incy=SIGN(dy);
    if(dx<0) dx=-dx;
    if(dy<0) dy=-dy;
    if (dx>dy) {
        pdx=incx;
        pdy=0;
        ddx=incx;
        ddy=incy;
        es=dy;
        el=dx;
    } else {
        pdx=0;
        pdy=incy;
        ddx=incx;
        ddy=incy;
        es=dx;
        el=dy;
    }
    x=x1;
    y=y1;
    err=el/2;
    set_pixel(data, x, y, r, g, b);

    for(t=0; t<el; t++) {
        err -= es;
        if(err<0) {
            err+=el;
            x+=ddx;
            y+=ddy;
        } else {
            x+=pdx;
            y+=pdy;
        }
        set_pixel(data, x, y, r, g, b);
    }
}

color average_line(image *data, size_t x1, size_t y1, size_t x2, size_t y2) {
    size_t x, y, t, pdx, pdy, ddx, ddy, es, el;
    int dx, dy, incx, incy, err;
    color ret;
    color px;
    size_t i;
    size_t j;
    size_t hist_r[256];
    size_t hist_g[256];
    size_t hist_b[256];
    size_t data_len = 0;

    for (i = 0; i < 256; i++) {
        hist_r[i] = 0;
        hist_g[i] = 0;
        hist_b[i] = 0;
    }

    dx=x2-x1;
    dy=y2-y1;
    incx=SIGN(dx);
    incy=SIGN(dy);
    if(dx<0) dx=-dx;
    if(dy<0) dy=-dy;
    if (dx>dy) {
        pdx=incx;
        pdy=0;
        ddx=incx;
        ddy=incy;
        es=dy;
        el=dx;
    } else {
        pdx=0;
        pdy=incy;
        ddx=incx;
        ddy=incy;
        es=dx;
        el=dy;
    }
    x=x1;
    y=y1;
    err=el/2;
    px = get_pixel(data, x, y);
    hist_r[px.r]++;
    hist_g[px.g]++;
    hist_b[px.b]++;
    data_len++;

    for(t=0; t<el; t++) {
        err -= es;
        if(err<0) {
            err+=el;
            x+=ddx;
            y+=ddy;
        } else {
            x+=pdx;
            y+=pdy;
        }
        px = get_pixel(data, x, y);
        hist_r[px.r]++;
        hist_g[px.g]++;
        hist_b[px.b]++;
        data_len++;
    }

    j = 0;
    for (i = 0; i < 256; i++) {
        j += hist_r[i];
        if (j >= data_len / 2) {
            ret.r = i;
            break;
        }
    }
    j = 0;
    for (i = 0; i < 256; i++) {
        j += hist_g[i];
        if (j >= data_len / 2) {
            ret.g = i;
            break;
        }
    }
    j = 0;
    for (i = 0; i < 256; i++) {
        j += hist_b[i];
        if (j >= data_len / 2) {
            ret.b = i;
            break;
        }
    }
    return ret;
}


void lines(image *source, image *dest, size_t L, float m, float M) {
    size_t i, j;
    float dx;
    float mx, my;
    float mm = MAX(MIN(source->width * source->height / L, M), m);
    unsigned char av_r = average(source->r, source->width * source->height);
    unsigned char av_g = average(source->g, source->width * source->height);
    unsigned char av_b = average(source->b, source->width * source->height);
    fill(dest, av_r, av_g, av_b);
    dx = (float)source->width / L;
    mx = 0;
    my = mm / 2;
    for (i = 0; i < L; i++) {
        color avg;
        mx += dx;
        my += (source->height - mm) / 8;
        if (my + mm / 2 > source->height) {
            my = mm / 2 + ((size_t)(my + mm / 2) % (size_t)(source->height - mm));
        }
        avg = average_line(source, mx, my - mm / 2, mx, my + mm / 2);
        line(dest, mx, my - mm / 2, mx, my + mm / 2, avg.r, avg.g, avg.b);
    }
}

int main(int argc, char *argv[]) {
    image source;
    image dest;
    size_t L;
    float m;
    float M;

    load_image(argv[1], &source);
    L = atol(argv[2]);
    m = atof(argv[3]);
    M = atof(argv[4]);

    init_image(&dest, source.width, source.height);
    lines(&source, &dest, L, m, M);


    write_image(argv[5], &dest);
}

এল = 5000, মি = 10, এম = 50

এল = 5000, মি = 10, এম = 50

এল = 5000, মি = 10, এম = 50

এল = 5000, মি = 10, এম = 50

এল = 100000, মি = 10, এম = 50

এখানে চিত্র বর্ণনা লিখুন


6

পাইথন 3-ভিত্তিতে "কিছুটা এলোমেলো লাইন এবং তার পরে কিছু" বন্ধুত্বপূর্ণ প্রান্ত সনাক্তকরণ।

কোডটি তাত্ত্বিকভাবে চিরতরে চলতে পারে (তাই আমি এটি মজাদার জন্য রাতারাতি চালাতে পারি) তবে এটি এর অগ্রগতি রেকর্ড করে, তাই সমস্ত চিত্র 1-10 মিনিটের চিহ্ন থেকে নেওয়া হয়।

এটি প্রথমে চিত্রটি পড়ে, এবং তারপরে সমস্ত প্রান্তের কোণ খুঁজে পেতে, লাইনগুলি অন্য কোনও রঙের দিকে ত্রুটিযুক্ত না হয় তা নিশ্চিত করার জন্য স্বতন্ত্র প্রান্ত সনাক্তকরণ ব্যবহার করে। একবার (দৈর্ঘ্যমালা, দৈর্ঘ্যম্যাক্স) এর মধ্যে এলোমেলো দৈর্ঘ্যের একটি লাইন সেট হয়ে গেলে, এটি সামগ্রিক চিত্রটিতে অবদান রাখে কিনা তা পরীক্ষা করে। যখন ছোট লাইনগুলি আরও ভাল হয়, আমি 10-50 থেকে রেখার দৈর্ঘ্য সেট করি।

from random import randint, uniform
import json
from PIL import Image, ImageDraw, ImageFilter
import math
k=(-1,0,1,-2,0,2,-1,0,1)
k1=(-1,-2,-1,0,0,0,1,2,1)
population=[]
lengthmin=10
lengthmax=50
number_lines=10**8
im=Image.open('0.png')
[x1,y1]=im.size
dx=0
class drawer():
    def __init__(self,genome,score,filename):
        self.genome=genome
        self.score=score
        self.filename=filename
    def initpoint(self,g1):
        g2=self.genome
        im=Image.open('0.png')
        im1=im.filter(ImageFilter.Kernel((3,3),k,1,128))
        im2=im.filter(ImageFilter.Kernel((3,3),k1,1,128))
        im1=im1.filter(ImageFilter.GaussianBlur(radius=4))
        im2=im2.filter(ImageFilter.GaussianBlur(radius=4))
        for x in range(0,number_lines):
            if(x%10**4==0):
                print(x*100/number_lines)
                self.save()
                g1.save('1.png')
            (x,y)=(randint(0,x1-1),randint(0,y1-1))
            w=im1.getpixel((x,y))[0]-128
            z=im2.getpixel((x,y))[0]-128
            w=int(w)
            z=int(z)
            W=(w**2+z**2)**0.5
            if(W!=0):
                w=(w/W)*randint(lengthmin,lengthmax)
                z=(z/W)*randint(lengthmin,lengthmax)
                (w,z)=(z,w)
                (a,b)=(x+w,y+z)
                a=int(a)
                b=int(b)
                x=int(x)
                y=int(y)
                if(a>=x1):
                    a=x1-1
                if(b>=y1):
                    b=y1-1
                if(a<0):
                    a=0
                if(b<0):
                    b=0
                if(x>=x1):
                    x=x1-1
                if(y>=y1):
                    y=y1-1
                if(x<0):
                    x=0
                if(y<0):
                    y=0
                C=[0,0,0]
                D=0
                E=0
                F=0
                G=0
                W=((x-a)**2+(y-b)**2)**0.5
                if(W!=0):
                    for Z in range(0,int(W)):
                        w=(Z/W)
                        (c,d)=((w*x+(1-w)*a),(w*y+(1-w)*b))
                        c=int(c)
                        d=int(d)
                        C[0]+=im.getpixel((c,d))[0]
                        C[1]+=im.getpixel((c,d))[1]
                        C[2]+=im.getpixel((c,d))[2]
                    C[0]/=W
                    C[1]/=W
                    C[2]/=W
                    C[0]=int(C[0])
                    C[1]=int(C[1])
                    C[2]=int(C[2])
                    for Z in range(0,int(W)):
                        w=(Z/W)
                        (c,d)=((w*x+(1-w)*a),(w*y+(1-w)*b))
                        c=int(c)
                        d=int(d)
                        E=0
                        D=0
                        D+=(g1.getpixel((c,d))[0]-im.getpixel((c,d))[0])**2
                        D+=(g1.getpixel((c,d))[1]-im.getpixel((c,d))[1])**2
                        D+=(g1.getpixel((c,d))[2]-im.getpixel((c,d))[2])**2
                        F+=D**0.5
                        E+=(im.getpixel((c,d))[0]-C[0])**2
                        E+=(im.getpixel((c,d))[1]-C[1])**2
                        E+=(im.getpixel((c,d))[2]-C[2])**2
                        G+=E**0.5
                    #print((G/W,F/W))
                    if(G<F):
                        for Z in range(0,int(W)):
                            w=(Z/W)
                            (c,d)=((w*x+(1-w)*a),(w*y+(1-w)*b))
                            c=int(c)
                            d=int(d)
                            g1.putpixel((c,d),(int(C[0]),int(C[1]),int(C[2])))
                        g2.append((x,y,a,b,int(C[0]%256),int(C[1]%256),int(C[2]%256)))
        return(g1)
    def import_file(self):
        with open(self.filename, 'r') as infile:
            self.genome=json.loads(infile.read())
        print(len(self.genome))
    def save(self):
        with open(self.filename, 'w') as outfile:
            data = json.dumps(self.genome)
            outfile.write(data)
population.append(drawer([],0,'0.txt'))
G=0
g1=Image.new('RGB',(x1,y1),'black')
g1=population[0].initpoint(g1)
g1.save('1.png')

আমেরিকান গথিক

Escher

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.