php पीएचपी का इस्तेमाल करते हुए छवि समानता की तुलना कैसे करें, परिमाण पर रोटेशन?




image-processing similarity (4)

मैं नीचे छवियों के बीच समानता की तुलना करना चाहता हूं मेरी आवश्यकताओं के मुताबिक मैं इन सभी छवियों को समान रूप से पहचानना चाहता हूं, क्योंकि इससे एक ही रंग, एक ही क्लिप आर्ट का उपयोग किया गया है। इन चित्रों में एकमात्र अंतर रोटेशन, स्केल और क्लिप आर्ट की नियुक्ति है। चूंकि सभी 3 टी-शर्ट ने एक ही रंग और क्लिप आर्ट का उपयोग किया है, मैं सभी 3 छवियों को समान रूप से पहचानना चाहता हूं। मैंने hackerfactor.com में वर्णित विधि को बाहर करने का प्रयास किया । लेकिन यह मेरी आवश्यकताओं के अनुसार मुझे सही परिणाम नहीं देता है इन सभी छवियों को समान रूप से कैसे पहचाना जाए? क्या आपके पास कोई सुझाव है? क्रिप्या मेरि सहायता करे।

नीचे की छवियों को ऊपर की छवियों से भिन्न माना जाना चाहिए। (हालांकि, टीशर्ट्स का एक ही रंग है, क्लिप आर्ट्स अलग-अलग हैं। अंतिम टी-शर्ट ऊपर से भिन्न है, क्योंकि इसमें एक ही क्लिप आर्ट का इस्तेमाल होता है, लेकिन दो बार।)


गीथहब में स्थानांतरित

क्योंकि यह सवाल काफी दिलचस्प है, मैंने पूरी बात को गिटहब में ले जाया था, जहां आप वर्तमान कार्यान्वयन पा सकते हैं: ImageCompare

मूल उत्तर

मैंने एक बहुत सरल दृष्टिकोण बनाया है, आईजीजी का आकार बदलकर और आकार की छवियों के औसत रंग की तुलना करना।

$binEqual = [
    file_get_contents('http://i.stack.imgur.com/D8ct1.png'),
    file_get_contents('http://i.stack.imgur.com/xNZt1.png'),
    file_get_contents('http://i.stack.imgur.com/kjGjm.png')
];

$binDiff = [
    file_get_contents('http://i.stack.imgur.com/WIOHs.png'),
    file_get_contents('http://i.stack.imgur.com/ljoBT.png'),
    file_get_contents('http://i.stack.imgur.com/qEKSK.png')
];


function getAvgColor($bin, $size = 10) {

    $target = imagecreatetruecolor($size, $size);
    $source = imagecreatefromstring($bin);

    imagecopyresized($target, $source, 0, 0, 0, 0, $size, $size, imagesx($source), imagesy($source));

    $r = $g = $b = 0;

    foreach(range(0, $size - 1) as $x) {
        foreach(range(0, $size - 1) as $y) {
            $rgb = imagecolorat($target, $x, $y);
            $r += $rgb >> 16;
            $g += $rgb >> 8 & 255;
            $b += $rgb & 255;
        }
    }   

    unset($source, $target);

    return (floor($r / $size ** 2) << 16) +  (floor($g / $size ** 2) << 8)  + floor($b / $size ** 2);
}

function compAvgColor($c1, $c2, $tolerance = 4) {

    return abs(($c1 >> 16) - ($c2 >> 16)) <= $tolerance && 
           abs(($c1 >> 8 & 255) - ($c2 >> 8 & 255)) <= $tolerance &&
           abs(($c1 & 255) - ($c2 & 255)) <= $tolerance;
}

$perms = [[0,1],[0,2],[1,2]];

foreach($perms as $perm) {
    var_dump(compAvgColor(getAvgColor($binEqual[$perm[0]]), getAvgColor($binEqual[$perm[1]])));
}

foreach($perms as $perm) {
    var_dump(compAvgColor(getAvgColor($binDiff[$perm[0]]), getAvgColor($binDiff[$perm[1]])));
}

प्रयुक्त आकार और रंग-सहिष्णुता के लिए मुझे अपेक्षित परिणाम प्राप्त होता है:

bool(true)
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)

अधिक उन्नत कार्यान्वयन

तुलना करने के लिए खाली टी शर्ट:

$binEqual = [
    file_get_contents('http://i.stack.imgur.com/D8ct1.png'),
    file_get_contents('http://i.stack.imgur.com/xNZt1.png'),
    file_get_contents('http://i.stack.imgur.com/kjGjm.png')
];

$binDiff = [
    file_get_contents('http://i.stack.imgur.com/WIOHs.png'),
    file_get_contents('http://i.stack.imgur.com/ljoBT.png'),
    file_get_contents('http://i.stack.imgur.com/qEKSK.png')
];

class Color {
    private $r = 0;
    private $g = 0;
    private $b = 0;

    public function __construct($r = 0, $g = 0, $b = 0)
    {
        $this->r = $r;
        $this->g = $g;
        $this->b = $b;
    }

    public function r()
    {
        return $this->r;
    }

    public function g()
    {
        return $this->g;
    }

    public function b()
    {
        return $this->b;
    }

    public function toInt()
    {
        return $this->r << 16 + $this->g << 8 + $this->b;
    }

    public function toRgb()
    {
        return [$this->r, $this->g, $this->b];  
    }

    public function mix(Color $color)
    {
        $this->r = round($this->r + $color->r() / 2);
        $this->g = round($this->g + $color->g() / 2);
        $this->b = round($this->b + $color->b() / 2);
    }

    public function compare(Color $color, $tolerance = 500)
    {
        list($r1, $g1, $b1) = $this->toRgb();
        list($r2, $g2, $b2) = $color->toRgb();

        $diff = round(sqrt(pow($r1 - $r2, 2) + pow($g1 - $g2, 2) + pow($b1 - $b2, 2)));

        printf("Comp r(%s : %s), g(%s : %s), b(%s : %s) Diff %s \n", $r1, $r2, $g1, $g2, $b1, $b2, $diff);

        return  $diff <= $tolerance;
    }

    public static function fromInt($int) {
        return new self($int >> 16, $int >> 8 & 255, $int & 255);
    }
}


function getAvgColor($bin, $size = 5) {

    $target    = imagecreatetruecolor($size, $size);
    $targetTmp = imagecreatetruecolor($size, $size);

    $sourceTmp = imagecreatefrompng('http://i.stack.imgur.com/gfn5A.png');
    $source    = imagecreatefromstring($bin);

    imagecopyresized($target, $source, 0, 0, 0, 0, $size, $size, imagesx($source), imagesy($source));
    imagecopyresized($targetTmp, $sourceTmp, 0, 0, 0, 0, $size, $size, imagesx($source), imagesy($source));

    $r = $g = $b = $relPx = 0;

    $baseColor = new Color();

    foreach(range(0, $size - 1) as $x) {
        foreach(range(0, $size - 1) as $y) {
            if (imagecolorat($target, $x, $y) != imagecolorat($targetTmp, $x, $y))
                $baseColor->mix(Color::fromInt(imagecolorat($target, $x, $y)));
        }
    }

    unset($source, $target, $sourceTmp, $targetTmp);

    return $baseColor;

}

$perms = [[0,0], [1,0], [2,0], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]];

echo "Equal\n";
foreach($perms as $perm) {
    var_dump(getAvgColor($binEqual[$perm[0]])->compare(getAvgColor($binEqual[$perm[1]])));
}

echo "Different\n";
foreach($perms as $perm) {
    var_dump(getAvgColor($binEqual[$perm[0]])->compare(getAvgColor($binDiff[$perm[1]])));
}

परिणाम:

Equal
Comp r(101 : 101), g(46 : 46), b(106 : 106) Diff 0 
bool(true)
Comp r(121 : 101), g(173 : 46), b(249 : 106) Diff 192 
bool(true)
Comp r(219 : 101), g(179 : 46), b(268 : 106) Diff 241 
bool(true)
Comp r(121 : 101), g(173 : 46), b(249 : 106) Diff 192 
bool(true)
Comp r(121 : 121), g(173 : 173), b(249 : 249) Diff 0 
bool(true)
Comp r(121 : 219), g(173 : 179), b(249 : 268) Diff 100 
bool(true)
Comp r(219 : 101), g(179 : 46), b(268 : 106) Diff 241 
bool(true)
Comp r(219 : 121), g(179 : 173), b(268 : 249) Diff 100 
bool(true)
Comp r(219 : 219), g(179 : 179), b(268 : 268) Diff 0 
bool(true)
Different
Comp r(101 : 446), g(46 : 865), b(106 : 1242) Diff 1442 
bool(false)
Comp r(121 : 446), g(173 : 865), b(249 : 1242) Diff 1253 
bool(false)
Comp r(219 : 446), g(179 : 865), b(268 : 1242) Diff 1213 
bool(false)
Comp r(121 : 446), g(173 : 865), b(249 : 1242) Diff 1253 
bool(false)
Comp r(121 : 654), g(173 : 768), b(249 : 1180) Diff 1227 
bool(false)
Comp r(121 : 708), g(173 : 748), b(249 : 1059) Diff 1154 
bool(false)
Comp r(219 : 446), g(179 : 865), b(268 : 1242) Diff 1213 
bool(false)
Comp r(219 : 654), g(179 : 768), b(268 : 1180) Diff 1170 
bool(false)
Comp r(219 : 708), g(179 : 748), b(268 : 1059) Diff 1090 
bool(false)

इस गणना में पृष्ठभूमि को ध्यान नहीं दिया जाता है जो औसत रंग में बड़ा अंतर होता है।

अंतिम कार्यान्वयन (ओओपी)

काफी सारे विषय। इसलिए मैंने इसे थोड़ा सा ढकने के लिए ट्यून किया। यह अब एक पूर्ण ओओपी कार्यान्वयन है पृष्ठभूमि को खत्म करने के लिए अब आप एक नई छवि बना सकते हैं और इसके कुछ मुखौटे को घटा सकते हैं। फिर आप तुलनात्मक विधि का उपयोग करके एक छवि को दूसरी में तुलना कर सकते हैं। गणना को सीमित रखने के लिए, पहले अपनी छवि का आकार बदलने के लिए बेहतर है (मास्क वर्तमान छवि के लिए पूरी तरह से फीट हैं)

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

Class Image {

    const HASH_SIZE = 8;
    const AVG_SIZE = 10;

    private $img = null;

    public function __construct($resource)
    {
        $this->img = $resource;;
    }

    private function permute(array $a1, array $a2) {
        $perms = array();
        for($i = 0; $i < sizeof($a1); $i++) {
            for($j = $i; $j < sizeof($a2); $j++) {
                if ($i != $j) {
                    $perms[] = [$a1[$i], 
                    $a2[$j]];
                }
            }
        }

        return $perms;
    }

    public function compare(Image $comp) {
        $avgComp = array();

        foreach($comp->chunk(25) as $chunk) {
            $avgComp[] = $chunk->avg();
        }

        $avgOrg = array();

        foreach($this->chunk(25) as $chunk) {
            $avgOrg[] = $chunk->avg();
        }

        $white = Color::fromInt(0xFFFFFF);

        $avgComp = array_values(array_filter($avgComp, function(Color $color) use ($white){
            return $white->compare($color, 1000);
        }));

        $avgOrg = array_values(array_filter($avgOrg, function(Color $color) use ($white){
            return $white->compare($color, 1000);
        }));

        $equal = 0;
        $pairs = $this->permute($avgOrg, $avgComp);

        foreach($pairs as $pair) {
            $equal += $pair[0]->compare($pair[1], 100) ? 1 : 0;
        }

        return ($equal / sizeof($pairs));
    }

    public function substract(Image $mask, $tolerance = 50)
    {
        $size = $this->size();

        if ($mask->size() != $size) {
            $mask = $mask->resize($size);
        }

        for ($x = 0; $x < $size[0]; $x++) {
            for ($y = 0; $y < $size[1]; $y++) {
                if ($this->colorat($x, $y)->compare($mask->colorat($x, $y), $tolerance))
                    imagesetpixel($this->img, $x, $y, 0xFFFFFF);
            }
        }

        return $this;
    }

    public function avg($size = 10)
    {
        $target = $this->resize([self::AVG_SIZE, self::AVG_SIZE]);

        $avg   = Color::fromInt(0x000000);
        $white = Color::fromInt(0xFFFFFF);  

        for ($x = 0; $x < self::AVG_SIZE; $x++) {
            for ($y = 0; $y < self::AVG_SIZE; $y++) {
                $color = $target->colorat($x, $y);
                if (!$color->compare($white, 10))
                    $avg->mix($color);
            }
        }

        return $avg;
    }

    public function colorat($x, $y)
    {
        return Color::fromInt(imagecolorat($this->img, $x, $y));
    }

    public function chunk($chunkSize = 10)
    {
        $collection = new ImageCollection();
        $size = $this->size();

        for($x = 0; $x < $size[0]; $x += $chunkSize) {
            for($y = 0; $y < $size[1]; $y += $chunkSize) {
                switch (true) {
                    case ($x + $chunkSize > $size[0] && $y + $chunkSize > $size[1]):
                        $collection->push($this->slice(['x' => $x, 'y' => $y, 'height' => $size[0] - $x, 'width' => $size[1] - $y]));
                        break;
                    case ($x + $chunkSize > $size[0]):
                        $collection->push($this->slice(['x' => $x, 'y' => $y, 'height' => $size[0] - $x, 'width' => $chunkSize]));
                        break;
                    case ($y + $chunkSize > $size[1]):
                        $collection->push($this->slice(['x' => $x, 'y' => $y, 'height' => $chunkSize, 'width' => $size[1] - $y]));
                        break;
                    default:
                        $collection->push($this->slice(['x' => $x, 'y' => $y, 'height' => $chunkSize, 'width' => $chunkSize]));
                        break;
                }
            }
        }

        return $collection;
    }

    public function slice(array $rect)
    {
        return Image::fromResource(imagecrop($this->img, $rect));
    }

    public function size()
    {
        return [imagesx($this->img), imagesy($this->img)];
    }

    public function resize(array $size = array(100, 100))
    {
        $target = imagecreatetruecolor($size[0], $size[1]);
        imagecopyresized($target, $this->img, 0, 0, 0, 0, $size[0], $size[1], imagesx($this->img), imagesy($this->img));

        return Image::fromResource($target);
    }

    public function show()
    {
        header("Content-type: image/png");
        imagepng($this->img);
        die();
    }

    public function save($name = null, $path = '') {
        if ($name === null) {
            $name = $this->hash();
        }

        imagepng($this->img, $path . $name . '.png');

        return $this;
    }

    public function hash()
    {
                // Resize the image.
        $resized = imagecreatetruecolor(self::HASH_SIZE, self::HASH_SIZE);
        imagecopyresampled($resized, $this->img, 0, 0, 0, 0, self::HASH_SIZE, self::HASH_SIZE, imagesx($this->img), imagesy($this->img));
        // Create an array of greyscale pixel values.
        $pixels = [];
        for ($y = 0; $y < self::HASH_SIZE; $y++)
        {
            for ($x = 0; $x < self::HASH_SIZE; $x++)
            {
                $rgb = imagecolorsforindex($resized, imagecolorat($resized, $x, $y));
                $pixels[] = floor(($rgb['red'] + $rgb['green'] + $rgb['blue']) / 3);
            }
        }
        // Free up memory.
        imagedestroy($resized);
        // Get the average pixel value.
        $average = floor(array_sum($pixels) / count($pixels));
        // Each hash bit is set based on whether the current pixels value is above or below the average.
        $hash = 0; $one = 1;
        foreach ($pixels as $pixel)
        {
            if ($pixel > $average) $hash |= $one;
            $one = $one << 1;
        }
        return $hash;
    }

    public static function fromResource($resource)
    {
        return new self($resource);
    }

    public static function fromBin($binf)
    {
        return new self(imagecreatefromstring($bin));
    }

    public static function fromFile($path)
    {
        return new self(imagecreatefromstring(file_get_contents($path)));
    }
}

class ImageCollection implements IteratorAggregate
{
    private $images = array();

    public function __construct(array $images = array())
    {
        $this->images = $images;
    }

    public function push(Image $image) {
        $this->images[] = $image;
        return $this;
    }

    public function pop()
    {
        return array_pop($this->images);
    }

    public function save()
    {
        foreach($this->images as $image)
        {
            $image->save();
        }

        return $this;
    }

    public function getIterator() {
        return new ArrayIterator($this->images);
    }
}

class Color {
    private $r = 0;
    private $g = 0;
    private $b = 0;

    public function __construct($r = 0, $g = 0, $b = 0)
    {
        $this->r = $r;
        $this->g = $g;
        $this->b = $b;
    }

    public function r()
    {
        return $this->r;
    }

    public function g()
    {
        return $this->g;
    }

    public function b()
    {
        return $this->b;
    }

    public function toInt()
    {
        return $this->r << 16 + $this->g << 8 + $this->b;
    }

    public function toRgb()
    {
        return [$this->r, $this->g, $this->b];  
    }

    public function mix(Color $color)
    {
        $this->r = round($this->r + $color->r() / 2);
        $this->g = round($this->g + $color->g() / 2);
        $this->b = round($this->b + $color->b() / 2);
    }

    public function compare(Color $color, $tolerance = 500)
    {
        list($r1, $g1, $b1) = $this->toRgb();
        list($r2, $g2, $b2) = $color->toRgb();

        $diff = round(sqrt(pow($r1 - $r2, 2) + pow($g1 - $g2, 2) + pow($b1 - $b2, 2)));

        //printf("Comp r(%s : %s), g(%s : %s), b(%s : %s) Diff %s \n", $r1, $r2, $g1, $g2, $b1, $b2, $diff);

        return  $diff <= $tolerance;
    }

    public static function fromInt($int) {
        return new self($int >> 16, $int >> 8 & 255, $int & 255);
    }
}

$mask = Image::fromFile('http://i.stack.imgur.com/gfn5A.png');

$image1 = Image::fromFile('http://i.stack.imgur.com/D8ct1.png')->resize([50, 100])->substract($mask, 100);
$image2 = Image::fromFile('http://i.stack.imgur.com/xNZt1.png')->resize([50, 100])->substract($mask, 100);
$image3 = Image::fromFile('http://i.stack.imgur.com/kjGjm.png')->resize([50, 100])->substract($mask, 100);

$other1 = Image::fromFile('http://i.stack.imgur.com/WIOHs.png')->resize([50, 100])->substract($mask, 100);
$other2 = Image::fromFile('http://i.stack.imgur.com/ljoBT.png')->resize([50, 100])->substract($mask, 100);
$other3 = Image::fromFile('http://i.stack.imgur.com/qEKSK.png')->resize([50, 100])->substract($mask, 100);


echo "Equal\n";
var_dump(
    $image1->compare($image2),
    $image1->compare($image3),
    $image2->compare($image3)
);

echo "Image 1 to Other\n";
var_dump(
    $image1->compare($other1),
    $image1->compare($other2),
    $image1->compare($other3)
);

echo "Image 2 to Other\n";
var_dump(
    $image2->compare($other1),
    $image2->compare($other2),
    $image2->compare($other3)
);

echo "Image 3 to Other\n";
var_dump(
    $image3->compare($other1),
    $image3->compare($other2),
    $image3->compare($other3)
);

परिणाम:

Equal
float(0.47619047619048)
float(0.53333333333333)
float(0.4)
Image 1 to Other
int(0)
int(0)
int(0)
Image 2 to Other
int(0)
int(0)
int(0)
Image 3 to Other
int(0)
int(0)
int(0)

जैसा कि किसी ने बताया है, छवियों के हिस्टोग्राम की गणना करने और उन्हें तुलना करने के अलावा कुछ भी आसानी से प्राप्त नहीं किया जा सकता है। यहां एक उदाहरण दिया गया है जो प्रश्न में दी गई छवियों के लिए सही परिणाम देता है। मुख्य बिंदु यह है कि कैसे चोटी रंग स्तर की संख्या के बीच सही संतुलन प्राप्त करना और उनमें स्वीकार्य राशि है ( similarity( $histograms, $levels = 30, $enough = 28 )

function histograms( $images ) {
    foreach( $images as $img ) {
        $image = imagecreatefrompng( $img );
        $width = imagesx( $image );
        $height = imagesy( $image );
        $num_pixels = $width * $height; 

        $histogram = [];
        for ( $x = 0; $x < $width; $x++ ) {
            for ( $y = 0; $y < $height; $y++ ) {
                $rgb = imagecolorat( $image, $y, $x );
                $rgb = [ $rgb >> 16, ( $rgb >> 8 ) & 0xFF, $rgb & 0xFF ];

                $histo_v = (int) round( ( $rgb[0] + $rgb[1] + $rgb[02] ) / 3 );
                $histogram[ $histo_v ] = array_key_exists( $histo_v, $histogram ) ? $histogram[ $histo_v ] + $histo_v/$num_pixels : $histo_v/$num_pixels;
            }
        }
        $histograms[$img] = $histogram;
        arsort( $histograms[$img] );
    }

    return $histograms;
}


function similarity( $histograms, $levels = 30, $enough = 28 ) {
    $keys = array_keys( $histograms );
    $output = [];
    for ( $x = 0; $x < count( $histograms ) - 1; $x++ ) {
        for ( $y = $x + 1; $y < count( $histograms ); $y++ ) {      
            $similarity = count( array_intersect_key( array_slice( $histograms[ $keys[$x] ], 0, $levels, true ), array_slice( $histograms[ $keys[$y] ], 0, $levels, true ) ) );

            if ( $similarity > $enough ) $output[] = [ $keys[$x], $keys[$y], $similarity ];                 
        }
    }
    return $output;
}


$histograms = histograms( [ 'http://i.stack.imgur.com/D8ct1.png', 'http://i.stack.imgur.com/xNZt1.png', 'http://i.stack.imgur.com/kjGjm.png', 'http://i.stack.imgur.com/WIOHs.png', 'http://i.stack.imgur.com/ljoBT.png', 'http://i.stack.imgur.com/qEKSK.png' ] );
$similarity = similarity( $histograms );

print_r( $similarity );

/*
Array
(
    [0] => Array
        (
            [0] => http://i.stack.imgur.com/D8ct1.png
            [1] => http://i.stack.imgur.com/xNZt1.png
            [2] => 30
        )

    [1] => Array
        (
            [0] => http://i.stack.imgur.com/D8ct1.png
            [1] => http://i.stack.imgur.com/kjGjm.png
            [2] => 30
        )

    [2] => Array
        (
            [0] => http://i.stack.imgur.com/D8ct1.png
            [1] => http://i.stack.imgur.com/qEKSK.png
            [2] => 29
        )

    [3] => Array
        (
            [0] => http://i.stack.imgur.com/xNZt1.png
            [1] => http://i.stack.imgur.com/kjGjm.png
            [2] => 30
        )

    [4] => Array
        (
            [0] => http://i.stack.imgur.com/xNZt1.png
            [1] => http://i.stack.imgur.com/qEKSK.png
            [2] => 29
        )

    [5] => Array
        (
            [0] => http://i.stack.imgur.com/kjGjm.png
            [1] => http://i.stack.imgur.com/qEKSK.png
            [2] => 29
        )

)
*/

इस आलेख ने मुझे हिस्टोग्राम बनाने में भी मदद की


समान रूप से दो बराबर आयाम वाली छवियों के बीच सामान्यीकृत पार सहसंबंध समानता मीट्रिक की गणना करता है। सामान्यीकृत क्रॉस सहसंबंध मेट्रिक उपाय करता है कि समान दो छवियां कैसे हैं, वे कितने अलग नहीं हैं। एनसीसी मीट्रिक मानों की सीमा 0 (भिन्न) और 1 (समान) के बीच है। यदि मोड = जी, तो दो छवियों को ग्रेस्केल में कनवर्ट किया जाएगा। यदि मोड = आरजीबी, तो दो छवियों को पहले रंगों में परिवर्तित किया जाएगा = rgb इसके बाद, प्रत्येक चैनल के लिए एनसीसी समानता मीट्रिक की गणना की जाएगी। अंत में, उन्हें एक आरएमएस वैल्यू में जोड़ दिया जाएगा। नोट: यह मेट्रिक निरंतर रंग चैनलों के लिए काम नहीं करता क्योंकि यह उस चैनल के लिए एक एनसीसी मेट्रिक = 0/0 का उत्पादन करता है। इस प्रकार, स्क्रिप्ट को पूरी तरह से अपारदर्शी या पूरी तरह से पारदर्शी अल्फा चैनल सक्षम करने वाले किसी भी छवि के साथ चलाने की सलाह नहीं दी जाती है।

इस एपीआई की कोशिश करो,

http://www.phpclasses.org/package/8255-PHP-Compare-two-images-to-find-if-they-are-similar.html

मैं वास्तव में इस विषय के बारे में कुछ नहीं जानती हूं, जिसे मुझे लगता है कि आम तौर पर 'दृष्टि' कहा जाता है

मैं हालांकि क्या करता हूं, इन पंक्तियों के साथ कुछ है:

बहे:

  • पोस्टर , रंगों / रंगों की न्यूनतम संख्या ( अनुमानित ) के लिए
  • दो सबसे बड़े रंग (सफेद + शर्ट) निकालें
  • शेष रंग-पैलेट की तुलना करें , और अगर योजनाएं बहुत भिन्न होती हैं तो असफल रहें।
  • किसी भी शेष रंग के चारों ओर मोटे बहुभुज की गणना करें '( https://en.wikipedia.org/wiki/Convex_hull देखें )
  • बहुभुज की संख्या की तुलना करें और सबसे बड़ा बहुभुज की संख्या कोण और कोण-मान की संख्या (आकार न हो), प्रत्येक छवि से, और विफल या पास करें।

इस तरह के एक सेटअप में मुख्य समस्या, गोल हो जाएगा ... एक रंग पोस्टिंग के रूप में, यह ठीक है कि दो रंगों के बीच मिडलपॉइंट पर ... कभी कभी यह रंग ए हो जाता है, कभी-कभी यह रंग बी हो जाता है बहुभुजों के साथ ही, मुझे लगता है





similarity