ব্ল্যাকহাট কোথায়?


27

চ্যালেঞ্জ

কোড লিখুন যা একটি এলোমেলো xkcd কমিক থেকে একটি প্যানেলের একটি চিত্র দেওয়া হয়েছে, যদি ব্ল্যাকহাট কমিকটিতে থাকে বা মিথ্যা না থাকলে সত্যবাদী মান দেয়।

ব্ল্যাকহাট কে?

ব্ল্যাকহাট হল এক্স কেসিডি কমিক্সের চরিত্রটিকে দেওয়া অনানুষ্ঠানিক নাম, যারা একটি কালো টুপি পরেছেন:

ব্ল্যাকহাটে এক্সকেইন এক্সপ্লেন পৃষ্ঠা থেকে নেওয়া

ব্ল্যাকহ্যাটের টুপি সর্বদা সরলতর, কালো এবং উপরের চিত্রের মতো দেখতে একই রকম।

অন্যান্য অক্ষরগুলিতেও টুপি এবং চুল থাকতে পারে তবে কারও কাছে এমন টুপি থাকবে না যা কালো এবং সোজা দিকযুক্ত।

ইনপুট

চিত্রটি যাইহোক ইনপুট হতে পারে আপনি ইচ্ছামত এটি চিত্রের পথ হোক বা এসটিডিএন এর মাধ্যমে বাইটগুলি। ইনপুট হিসাবে আপনার কোনও ইউআরএল নেওয়ার দরকার নেই।

বিধি

উত্তরের হার্ডকোডিং নিষিদ্ধ নয়, তবে এটি প্রশংসিত নয়।

উত্তর পেতে আপনাকে ইন্টারনেট অ্যাক্সেস করার অনুমতি নেই।

উদাহরণ

Https://xkcd.com থেকে সমস্ত চিত্র ছাঁটা হয়েছে

ব্ল্যাকহাট প্যানেলে রয়েছে (প্রত্যাবর্তন truthy)


ব্ল্যাকহাট প্যানেলে নেই (প্রত্যাবর্তন falsey)


টেস্ট ব্যাটারি

ব্ল্যাকহাটযুক্ত 20 টি চিত্র এখানে পাওয়া যাবে: https://beta-decay.github.io/blackhat.zip

ব্ল্যাকহ্যাট ধারণ করে না এমন 20 টি চিত্র এখানে পাওয়া যাবে: https://beta-decay.github.io/no_blackhat.zip

আপনি যদি আপনার প্রোগ্রামগুলি (রহস্য পরীক্ষার ক্ষেত্রে প্রশিক্ষণের জন্য) দিয়ে আরও চিত্র দেখতে চান তবে আপনি ব্ল্যাকহাটের সমস্ত উপস্থিতির একটি তালিকা এখানে পেতে পারেন: http://www.explainxkcd.com/wiki/index.php/ বিভাগ: Comics_featuring_Black_Hat

জয়লাভ

যে প্রোগ্রামটি সঠিকভাবে চিহ্নিত করে যে ব্ল্যাকহাট কমিকের মধ্যে রয়েছে কিনা বা সর্বাধিক চিত্রের বিজয়ীর জন্য নয়। আপনার শিরোনামে শতাংশ হিসাবে আপনার স্কোর অন্তর্ভুক্ত করা উচিত।

টাইব্রেকের ঘটনা ঘটলে বাঁধা প্রোগ্রামগুলিকে "রহস্য" চিত্র দেওয়া হবে (অর্থাত্ যেগুলি কেবলমাত্র আমি জানি)। যে কোডটি সবচেয়ে সঠিকভাবে টাইব্রেক জিতবে তা চিহ্নিত করে।

রহস্যের চিত্রগুলি স্কোরগুলির সাথে প্রকাশিত হবে।

দ্রষ্টব্য: দেখে মনে হচ্ছে তার জন্য র‌্যান্ডাল এর নাম হ্যাট গাই হতে পারে। আমি যদিও ব্ল্যাকহাট পছন্দ করি।


12
ম্যাথামেটিকার জন্য যদি কোনও বিল্ট-ইন থাকে তবে আমি অবাক হব না। ( রেফারেন্সের জন্য )
J. Sallé

5
একটি আলাদা টাই ব্রেকারের জন্য পরামর্শ: এখানে আলাদা না হওয়া চিত্রগুলির একটি পৃথক, ছোট সেট রয়েছে (5 সত্য ঘটনা এবং 5 টি মিথ্যা বলুন) এবং টাই ব্রেকারের বিজয়ী হ'ল এই অজানা চিত্রগুলিকে সর্বোত্তম করে তোলে। এটি নির্দিষ্ট জনের তুলনায় আরও জেনেরিক স্মার্ট সমাধান বনামকে উত্সাহিত করবে specific
সূন্দর - মনিকা

3
পুলিশ এবং আরআইএএ / এমপিএএর সাথে পরীক্ষার মামলাগুলি কেবল খারাপ। ভাল পরীক্ষার ব্যাটারি, @ বেটাডেসে।
সুন্দরের - মনিকা পুনরায় ইনস্টল করুন


1
@ নাইট 2 দুঃখিত! আমি কেবল সেখানে কোনও টাই করার পরিকল্পনা করেছিলাম। যদিও 100% এর উপর দুর্দান্ত কাজ!
বিটা ক্ষয়

উত্তর:


16

পিএইচপি (> = 7), 100% (40/40)

<?php

set_time_limit(0);

class BlackHat
{
    const ROTATION_RANGE = 45;

    private $image;
    private $currentImage;
    private $currentImageWidth;
    private $currentImageHeight;

    public function __construct($path)
    {
        $this->image = imagecreatefrompng($path);
    }

    public function hasBlackHat()
    {
        $angles = [0];

        for ($i = 1; $i <= self::ROTATION_RANGE; $i++) {
            $angles[] = $i;
            $angles[] = -$i;
        }

        foreach ($angles as $angle) {
            if ($angle == 0) {
                $this->currentImage = $this->image;
            } else {
                $this->currentImage = $this->rotate($angle);
            }

            $this->currentImageWidth = imagesx($this->currentImage);
            $this->currentImageHeight = imagesy($this->currentImage);

            if ($this->findBlackHat()) return true;
        }

        return false;
    }

    private function findBlackHat()
    {
        for ($y = 0; $y < $this->currentImageHeight; $y++) {
            for ($x = 0; $x < $this->currentImageWidth; $x++) {
                if ($this->isBlackish($x, $y) && $this->isHat($x, $y)) return true;
            }
        }

        return false;
    }

    private function isHat($x, $y)
    {
        $hatWidth = $this->getBlackishSequenceSize($x, $y, 'right');
        if ($hatWidth < 10) return false;

        $hatHeight = $this->getBlackishSequenceSize($x, $y, 'bottom');

        $hatLeftRim = $hatRightRim = 0;
        for (; ; $hatHeight--) {
            if ($hatHeight < 5) return false;

            $hatLeftRim = $this->getBlackishSequenceSize($x, $y + $hatHeight, 'left');
            if ($hatLeftRim < 3) continue;

            $hatRightRim = $this->getBlackishSequenceSize($x + $hatWidth, $y + $hatHeight, 'right');
            if ($hatRightRim < 2) $hatRightRim = $this->getBlackishSequenceSize($x + $hatWidth, $y + $hatHeight, 'right', 'isLessBlackish');
            if ($hatRightRim < 2) continue;

            break;
        }

        $ratio = $hatWidth / $hatHeight;
        if ($ratio < 2 || $ratio > 4.2) return false;

        $widthRatio = $hatWidth / ($hatLeftRim + $hatRightRim);
        if ($widthRatio < 0.83) return false;
        if ($hatHeight / $hatLeftRim < 1 || $hatHeight / $hatRightRim < 1) return false;

        $pointsScore = 0;
        if ($this->isSurroundedBy($x, $y, 3, true, true, false, false)) $pointsScore++;
        if ($this->isSurroundedBy($x + $hatWidth, $y, 3, true, false, false, true)) $pointsScore++;
        if ($this->isSurroundedBy($x, $y + $hatHeight, 3, false, false, true, false)) $pointsScore++;
        if ($this->isSurroundedBy($x + $hatWidth, $y + $hatHeight, 3, false, false, true, false)) $pointsScore++;
        if ($this->isSurroundedBy($x - $hatLeftRim, $y + $hatHeight, 3, true, true, true, false)) $pointsScore++;
        if ($this->isSurroundedBy($x + $hatWidth + $hatRightRim, $y + $hatHeight, 3, true, false, true, true)) $pointsScore++;
        if ($pointsScore < 3 || ($hatHeight >= 19 && $pointsScore < 4) || ($hatHeight >= 28 && $pointsScore < 5)) return false;

        $middleCheckSize = ($hatHeight >= 15 ? 3 : 2);
        if (!$this->isSurroundedBy($x + (int)($hatWidth / 2), $y, $middleCheckSize, true, null, null, null)) return false;
        if (!$this->isSurroundedBy($x + (int)($hatWidth / 2), $y + $hatHeight, $middleCheckSize, null, null, true, null)) {
            if (!$this->isSurroundedBy($x + (int)(($hatWidth / 4) * 3), $y + $hatHeight, $middleCheckSize, null, null, true, null)) return false;
        }
        if (!$this->isSurroundedBy($x, $y + (int)($hatHeight / 2), $middleCheckSize + 1, null, true, null, null)) return false;
        if (!$this->isSurroundedBy($x + $hatWidth, $y + (int)($hatHeight / 2), $middleCheckSize, null, null, null, true)) return false;

        $badBlacks = 0;
        for ($i = 1; $i <= 3; $i++) {
            if ($y - $i >= 0) {
                if ($this->isBlackish($x, $y - $i)) $badBlacks++;
            }

            if ($x - $i >= 0 && $y - $i >= 0) {
                if ($this->isBlackish($x - $i, $y - $i)) $badBlacks++;
            }
        }
        if ($badBlacks > 2) return false;

        $total = ($hatWidth + 1) * ($hatHeight + 1);
        $blacks = 0;
        for ($i = $x; $i <= $x + $hatWidth; $i++) {
            for ($j = $y; $j <= $y + $hatHeight; $j++) {
                $isBlack = $this->isBlackish($i, $j);
                if ($isBlack) $blacks++;
            }
        }

        if (($total / $blacks > 1.15)) return false;

        return true;
    }

    private function getColor($x, $y)
    {
        return imagecolorsforindex($this->currentImage, imagecolorat($this->currentImage, $x, $y));
    }

    private function isBlackish($x, $y)
    {
        $color = $this->getColor($x, $y);
        return ($color['red'] < 78 && $color['green'] < 78 && $color['blue'] < 78 && $color['alpha'] < 30);
    }

    private function isLessBlackish($x, $y)
    {
        $color = $this->getColor($x, $y);
        return ($color['red'] < 96 && $color['green'] < 96 && $color['blue'] < 96 && $color['alpha'] < 40);
    }

    private function getBlackishSequenceSize($x, $y, $direction, $fn = 'isBlackish')
    {
        $size = 0;

        if ($direction == 'right') {
            for ($x++; ; $x++) {
                if ($x >= $this->currentImageWidth) break;
                if (!$this->$fn($x, $y)) break;
                $size++;
            }
        } elseif ($direction == 'left') {
            for ($x--; ; $x--) {
                if ($x < 0) break;
                if (!$this->$fn($x, $y)) break;
                $size++;
            }
        } elseif ($direction == 'bottom') {
            for ($y++; ; $y++) {
                if ($y >= $this->currentImageHeight) break;
                if (!$this->$fn($x, $y)) break;
                $size++;
            }
        }

        return $size;
    }

    private function isSurroundedBy($x, $y, $size, $top = null, $left = null, $bottom = null, $right = null)
    {
        if ($top !== null) {
            $flag = false;
            for ($i = 1; $i <= $size; $i++) {
                if ($y - $i < 0) break;
                $isBlackish = $this->isBlackish($x, $y - $i);

                if (
                    ($top && !$isBlackish) ||
                    (!$top && $isBlackish)
                ) {
                    $flag = true;
                } elseif ($flag) {
                    return false;
                }
            }
            if (!$flag) return false;
        }

        if ($left !== null) {
            $flag = false;
            for ($i = 1; $i <= $size; $i++) {
                if ($x - $i < 0) break;
                $isBlackish = $this->isBlackish($x - $i, $y);

                if (
                    ($left && !$isBlackish) ||
                    (!$left && $isBlackish)
                ) {
                    $flag = true;
                } elseif ($flag) {
                    return false;
                }
            }
            if (!$flag) return false;
        }

        if ($bottom !== null) {
            $flag = false;
            for ($i = 1; $i <= $size; $i++) {
                if ($y + $i >= $this->currentImageHeight) break;
                $isBlackish = $this->isBlackish($x, $y + $i);

                if (
                    ($bottom && !$isBlackish) ||
                    (!$bottom && $isBlackish)
                ) {
                    $flag = true;
                } elseif ($flag) {
                    return false;
                }
            }
            if (!$flag) return false;
        }

        if ($right !== null) {
            $flag = false;
            for ($i = 1; $i <= $size; $i++) {
                if ($x + $i >= $this->currentImageWidth) break;
                $isBlackish = $this->isBlackish($x + $i, $y);

                if (
                    ($right && !$isBlackish) ||
                    (!$right && $isBlackish)
                ) {
                    $flag = true;
                } elseif ($flag) {
                    return false;
                }
            }
            if (!$flag) return false;
        }

        return true;
    }

    private function rotate($angle)
    {
        return imagerotate($this->image, $angle, imagecolorallocate($this->image, 255, 255, 255));
    }
}

$bh = new BlackHat($argv[1]);
echo $bh->hasBlackHat() ? 'true' : 'false';

এটি চালানোর জন্য:

php <filename> <image_path>

উদাহরণ:

php black_hat.php "/tmp/blackhat/1.PNG"

নোট

  • কালো টুপি পাওয়া গেলে "সত্য" এবং যদি এটি খুঁজে না পাওয়া যায় তবে "মিথ্যা" প্রিন্ট করে।
  • এটি পিএইচপি এর পূর্ববর্তী সংস্করণগুলিতেও কাজ করা উচিত তবে নিরাপদ থাকতে জিডি সহ পিএইচপি> = 7 ব্যবহার করুন ।
  • এই স্ক্রিপ্টটি আসলে টুপিটি সন্ধান করার চেষ্টা করে এবং এটি করে এটি চিত্রটি অনেক বার ঘুরতে পারে এবং প্রতিবার হাজার এবং হাজার হাজার পিক্সেল এবং ক্লু পরীক্ষা করে। সুতরাং চিত্রটি যত বড় হবে বা যত গা dark় পিক্সেল রয়েছে, স্ক্রিপ্টটি শেষ হতে আরও সময় লাগবে। যদিও বেশিরভাগ চিত্রের জন্য এটি কয়েক সেকেন্ড থেকে এক মিনিট সময় নেয়।
  • আমি এই স্ক্রিপ্টটি আরও প্রশিক্ষণ দিতে চাই তবে আমার এটি করার জন্য পর্যাপ্ত সময় নেই।
  • এই স্ক্রিপ্টটি গল্ফ করা হয়নি (আবার কারণ আমার কাছে পর্যাপ্ত সময় নেই) তবে টাইয়ের ক্ষেত্রে গল্ফ হওয়ার অনেক সম্ভাবনা রয়েছে।

সনাক্ত করা কালো টুপিগুলির কয়েকটি উদাহরণ:

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

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


অতিরিক্ত

এখানে পোস্ট করার আগে, আমি এই স্ক্রিপ্টটি আরও 15 টি চিত্রের, কালো টুপি সহ 10 টি এবং কালো টুপিবিহীন 5 টির বিপরীতে পরীক্ষা করেছি এবং এটি তাদের সকলের জন্যও সঠিক হয়েছে (100%)।

এখানে আমি ব্যবহার করেছি অতিরিক্ত পরীক্ষার চিত্রযুক্ত জিপ ফাইল: এক্সট্রা.জিপ

ইন extra/blackhatডিরেক্টরি, লাল লাইনের সনাক্তকরণ ফলাফল পাওয়া যায়। উদাহরণস্বরূপ extra/blackhat/1.pngপরীক্ষার চিত্র এবং extra/blackhat/1_r.pngএটির সনাক্তকরণের ফলাফল।


টাইব্রেক কোড গল্ফ নয়। পরিবর্তে, টাই বিরতি সমাধান না হওয়া পর্যন্ত প্রোগ্রামগুলিকে গোপন পরীক্ষার কেস খাওয়ানো হয়। তারপরে আমি ফলাফলটি বলব এবং পরীক্ষার কেসগুলি পোস্ট করব :)
বিটা ডিকায়

1
@ বেটাডে: স্পষ্টির জন্য ধন্যবাদ, এই বাক্যটি (টাইয়ের সাথে সংক্ষিপ্ততম জয়) প্রশ্নের আগের সংস্করণগুলি থেকে আমার মাথায় ছিল, তাই আমি ভাবছিলাম যে যদি কোনও গোপন পরীক্ষার ক্ষেত্রে টাই হয়, তবে সংক্ষিপ্ততম কোড জিতবে। আমার খারাপ!
রাত 2

7
আপনি কমপক্ষে সম্ভবত চিত্র প্রক্রিয়াকরণ ভাষার জন্যও পুরস্কার
জিতেছেন

@ আনুশ ওয়েল কমপক্ষে পিএইচপি imagerotateঅন্তর্নির্মিত হয়েছে, তাই ...
ব্যবহারকারী 202729

আমি পিএইচপি সম্পর্কে যা পছন্দ করি তা হ'ল এটি প্রায় কোনও কিছুর জন্য কিছু প্রাথমিক কার্যকারিতা রয়েছে। এটি এত বছরের জন্য জিডি বান্ডিল করেছে এবং জিডি আসলে চিত্রগুলির সাথে কাজ করার সর্বাধিক সাধারণ প্রয়োজনগুলি পূরণ করে। তবে আমি পিএইচপি সম্পর্কে যা পছন্দ করি তা হ'ল সর্বদা কিছু এক্সটেনশন / প্যাকেজ থাকে যা আপনাকে আরও দেয় (কারণ বিশাল সম্প্রদায় থাকার কারণে)। উদাহরণস্বরূপ পিএইচপি-র জন্য ওপেনসিভি এক্সটেনশন রয়েছে যা প্রকৃত চিত্র প্রসেসিংয়ের অনুমতি দেয়!
রাত 2

8

মতলব, 87,5%

function hat=is_blackhat_here2(filepath)

img_hsv = rgb2hsv(imread(filepath));
img_v = img_hsv(:,:,3);

bw = imdilate(imerode( ~im2bw(img_v), strel('disk', 4, 8)), strel('disk', 4, 8));
bw = bwlabel(bw, 8);
bw = imdilate(imerode(bw, strel('disk', 1, 4)), strel('disk', 1, 4));
bw = bwlabel(bw, 4);

region_stats = regionprops(logical(bw), 'all');
hat = false;
for i = 1 : numel(region_stats)
    if mean(img_v(region_stats(i).PixelIdxList)) < 0.15 ...
            && region_stats(i).Area > 30 ...
            && region_stats(i).Solidity > 0.88 ...
            && region_stats(i).Eccentricity > 0.6 ...
            && region_stats(i).Eccentricity < 1 ...
            && abs(region_stats(i).Orientation) < 75...
            && region_stats(i).MinorAxisLength / region_stats(i).MajorAxisLength < 0.5;
        hat = true;
        break;
    end
end

প্রার্থীদের অঞ্চলগুলির আকারে কিছু চেক যুক্ত করে পূর্ববর্তী সংস্করণটির বর্ধন করা।

এইচএটি সেটে শ্রেণিবিন্যাস ত্রুটি : চিত্রগুলি 4, 14, 15, 17

নন হ্যাট সেটে শ্রেণিবিন্যাস ত্রুটি : চিত্রগুলি 4

সংশোধিত শ্রেণিবদ্ধ চিত্রগুলির কয়েকটি উদাহরণ: এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

একটি ভুল শ্রেণীবদ্ধ চিত্রের উদাহরণ:

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

পুরানো সংস্করণ (77,5%)

function hat=is_blackhat_here(filepath)

img_hsv = rgb2hsv(imread(filepath));
img_v = img_hsv(:,:,3);
bw = imerode(~im2bw(img_v), strel('disk', 5, 8));

hat =  mean(img_v(bw)) < 0.04;

মেমোনিক দ্বারা প্রস্তাবিত সমাধানের মতো চিত্রের ক্ষয়ের ভিত্তিতে দৃষ্টিভঙ্গি, তবে এইচএসভি চিত্রের ভি চ্যানেলের উপর ভিত্তি করে। তদুপরি, নির্বাচিত অঞ্চলের চ্যানেলের গড় মানটি পরীক্ষা করা হয় (এর আকার নয়)।

এইচএটি সেটে শ্রেণিবিন্যাস ত্রুটি : চিত্র 4, 5, 10

নন হ্যাট সেটে শ্রেণিবদ্ধার ত্রুটি : চিত্র 4, 5, 6, 7, 13, 14


7

পাইথ , 62.5%

<214.O.n'z

স্টিডিনে একটি চিত্র ফাইলের ফাইলের নাম গ্রহণ করে। রিটার্নস Trueসব তার আরজিবি রঙ উপাদান গড় যদি 214. তার চেয়ে অনেক বেশী আপনি যে অধিকার পড়া আছেন: দৃশ্যত Blackhat ইমেজ নো Blackhat চিত্র বেশি উজ্জ্বল হতে থাকে।

(নিশ্চয়ই কেউ আরও ভাল করতে পারে - এটি !)


2
আমি উপলব্ধি না করা অবধি পাইথের শক্তিতে আশ্চর্য হয়েছি: ডি
বিটা ডেকে

এক মুহুর্তের জন্য আমি ভেবেছিলাম "যেহেতু পাইথ ব্ল্যাকহ্যাট চিত্রগুলি স্বীকৃতি দেওয়ার জন্য তৈরি করেছে"
লুইস ফিলিপ ডি জেসুস মুনোজ

2
62.5% 40 টির মধ্যে 25 টি চিত্র। একটি এলোমেলো অনুমানের প্রোগ্রাম (স্থির বীজ সহ, এরকম কিছু) এর সম্ভাবনা থাকে)i=2540(40i)2407.7%

6

পাইথন 2, 65% 72.5% 77.5% (= 31/40)

import cv2
import numpy as np
from scipy import misc

def blackhat(path):
    im = misc.imread(path)
    black = (im[:, :, 0] < 10) & (im[:, :, 1] < 10) & (im[:, :, 2] < 10)
    black = black.astype(np.ubyte)

    black = cv2.erode(black, np.ones((3, 3)), iterations=3)

    return 5 < np.sum(black) < 2000

এই পরিসংখ্যান যা আউট পিক্সেল কালো, তারপর দূরে ছোট সংলগ্ন টুকরা অবক্ষয় ঘটায়। অবশ্যই এখানে উন্নতির জন্য জায়গা।

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