পিএইচপি (> = 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
এটির সনাক্তকরণের ফলাফল।