İyinet'e Hoşgeldiniz!

Türkiye'nin En Eski Webmaster Forum'una Hemen Kayıt Olun!

Kayıt Ol!

PHP ile benzer resimleri bulma

serkantkar

0
İyinet Üyesi
Katılım
17 Temmuz 2012
Mesajlar
977
Reaction score
7
Konum
Sammamish, WA, US
Son gunlerde sitemde yer alan 300bin fotografin munferit olanlarini bulmak icin kafa patlatiyordum. Sorun basit. Insan yardimi olmadan iki resmin ne kadar benzer olduguna programatik olarak nasil karar verebilirsiniz? Biraz arastirmadan sonra birkac fikri yanyana getirip gercekten ise yarayan bir script yazdim. Bu algoritma cok yuksek oranda benzer resimleri bulabiliyor. Hatta resimler crop edilmis ya da uzerinde yazi dahi olsa benzer oldugunu fark ediyor.

Isinize yarayabilirse ne mutlu bana.

Bazi noktalar:
GetHexString() fonksiyonuna resmin absolute pathini geciyorsunuz. Yani /home/dir1/dir2/image1.jpg. Iki resmi karsilastirdiginizi farz edersek bu fonksiyonu her iki resim icin de cagiriyorsunuz. Fonksiyon size her resim icin bir hex string dondurecek. Bu stringleri resimler arasinda ne kadar benzerlik oldugunu bulmak icin kullanacagiz.

Hex stringleri su sekilde kullaniyoruz :
$diff = levenshtein($hex1, $hex2);
levenshtein fonksiyonu iki stringi birbirine benzetmek icin minimum kac adet karakteri degistirmeniz gerektigini hesaplar. Bu yuzden ne kadar kucuk deger dondururse iki resim birbirine o kadar benziyor demektir.
Ben su esik degerinin ise yaradigini gordum. Eger $diff < 10 ise iki resim ayni, insan gozuyle farki ayiramazsiniz. Eger $diff < 100 ise benzer karalere bakiyorsunuz fakat resimler arasinda farklar var; mesela birisinde text var ya da birisi digerinin crop edilmis hali.

Cok ender de olsa bazi benzer resimler algoritmadan kacabiliyor. Mesela ayni resmin kontrast ya da doygunluk (saturation) degeri cok fazla degistirilmis ise $diff 150 uzeri cikabiliyor. Bu aklinizda bulunsun.

PHP:
function GetHexString($path)
{
  // Convert image into 8x8 64 pixels thumbnail.
  $thumb = ResizeImg($path, 8, 8, false);
  $hex = "";

  // Get HSV for each pixels.
  for ($i=0; $i<8; $i++)
  {
    for ($j=0; $j<8; $j++)
    {         
      // Get the rgb value for current pixel                 
      $rgb = imagecolorat($thumb, $i, $j);
      $r = ($rgb >> 16) & 0xFF;
      $g = ($rgb >> 8) & 0xFF;
      $b = $rgb & 0xFF;
      
      // Calculate HSV  
      $hsv = RgbToHsv($r, $g, $b);
      $h = GetRounded($hsv['H']);
      $s = GetRounded($hsv['S']);
      $v = GetRounded($hsv['V']);
      
      //$hex .= " x". dechex($h + $s + $v);
      $hex .= "x$h$s$v";

      //$hex = substr($hex, 0, 255);      
    }
  }

  // Delete first x to reduce to 255 characters.
  return substr($hex, 1, 255);
}

function GetRounded($val)
{
  while ($val >= 10)
  {
    $val = round($val / 10);
  }
  
  $val = round($val);
  if ($val >= 10)
  {
    return 1;
  }
  else
  {
    return $val;
  }
}
  
function RgbToHsv($R, $G, $B)  
{                                 
   $HSL = array(); 
 
   $var_R = ($R / 255); 
   $var_G = ($G / 255); 
   $var_B = ($B / 255); 
 
   $var_Min = min($var_R, $var_G, $var_B); 
   $var_Max = max($var_R, $var_G, $var_B); 
   $del_Max = $var_Max - $var_Min; 
 
   $V = $var_Max; 
 
   if ($del_Max == 0) 
   { 
      $H = 0; 
      $S = 0; 
   } 
   else 
   { 
      $S = $del_Max / $var_Max; 
 
      //  var d = (r==minRGB) ? g-b : ((b==minRGB) ? r-g : b-r);
      $d = ($var_R == $var_Min) ? $var_G - $var_B : (($var_B == $var_Min) ? $var_R - $var_G : $var_B - $var_R);
      // var h = (r==minRGB) ? 3 : ((b==minRGB) ? 1 : 5);
      $h = ($var_R == $var_Min) ? 3 : (($var_B == $var_Min) ? 1 : 5);

      $H = 60*($h - $d/$del_Max);
   } 
 
   $HSL['H'] = $H; 
   $HSL['S'] = $S * 100; 
   $HSL['V'] = $V * 100; 
 
   return $HSL; 
} 

function ResizeImg($path, $newWidth, $newHeight)
{
  list($width, $height, $type, $attr) = getimagesize($path);

  if ($type == IMAGETYPE_BMP)
  {
	  $img_src=imagecreatefrombmp($path);
  }
  else if ($type == IMAGETYPE_PNG)
  {
	  $img_src=imagecreatefrompng($path);
  }
  else if ($type == IMAGETYPE_GIF)
  {
	  $img_src=imagecreatefromgif($path);
  }
  else if ($type == IMAGETYPE_JPEG)
  {
	  $img_src=imagecreatefromjpeg($path);
  }
  else
  {
    throw new Exception("Doesn't know how to handle image type $type"); 
  }

  $img_thumb= imagecreatetruecolor($newWidth,$newHeight);
  $result= imagecopyresampled($img_thumb,$img_src,0,0,0,0,$newWidth,$newHeight,$width,$height);
  
  if(!$img_src || !$img_thumb || !$result)
  { 
     return lisanssız;
  }

  imagedestroy($img_src);

  return $img_thumb;
}
 

Türkiye’nin ilk webmaster forum sitesi iyinet.com'da forum üyeleri tarafından yapılan tüm paylaşımlardan; Türk Ceza Kanunu’nun 20. Maddesinin, 5651 Sayılı Kanununun 4. maddesinin 2. fıkrasına göre, paylaşım yapan üyeler sorumludur.

Üst