首页 > PHP资讯 > PHP培训技术 > 利用k-means聚类算法识别图片主色调

利用k-means聚类算法识别图片主色调

PHP培训技术

  由于使用php来写图片主色调识别功能太麻烦了,所以我给大家介绍利用利用k-means聚类算法识别图片主色调方法.

  识别图片主色调这个,网上貌似有几种方法,不过最准确,最优雅的解决方案还是利用聚类算法来做.

  直接上代码,不过,我测试结果表示,用PHP来做,效率不佳,PHP不适合做这种大规模运算,用nodejs做效率可以高出100倍左右,代码如下:

<?php  
 
$start = microtime(TRUE);  
 
main(); 
 
function main($img = ‘colors_files/T1OX3eXldXXXcqfYM._111424.jpg’)  
 
{  
    
list($width, $height, $mime_code) = getimagesize($img);  
//开源代码phpfensi.com 
 
 
$im = null;  
 
$point = array();  
 
switch ($mime_code)  
 
{  
 
# jpg  
 
case 2:  
 
$im =imagecreatefromjpeg($img);  
 
break;  
 
 
 
# png  
 
case 3:  
  
default:  
 
exit(‘擦 ,什么图像?解析不了啊’);  
 
}  
  
$new_width = 100;  
 
$new_height = 100;  
 
$pixel = imagecreatetruecolor($new_width, $new_height);  
 
imagecopyresampled($pixel, $im, 0, 0, 0, 0, $new_width, $new_height, $width, $height);  
  
run_time();  
  
$i = $new_width;  
 
while ($i–)  
 
{  
 
# reset高度  
 
$k = $new_height;  
 
while ($k–)  
 
{  
 
$rgb = ImageColorAt($im, $i, $k);  
 
array_push($point, array(‘r’=>($rgb >> 16) & 0xFF, ‘g’=>($rgb >> 8) & 0xFF, ‘b’=>$rgb & 0xFF));  
 
}  
 
}  
 
imagedestroy($im);  
 
imagedestroy($pixel); 
 
run_time();  
  
$color = kmeans($point);  
  
run_time();
  
foreach ($color as $key => $value)  
 
&nb 
sp; {  
 
echo ‘<br><span style=“background-color:’ . RGBToHex($value[0]) . ‘” >’ . RGBToHex($value[0]) . ‘</span>’;  
 
}  
  
}  
  
function run_time()  
 
{  
 
global $start;  
 
echo ‘<br/>消耗:’, microtime(TRUE) – $start;  
 
}  
  
function kmeans($point=array(), $k=3, $min_diff=1)  
 
{  
 
global $ii;  
 
$point_len = count($point);  
 
$clusters = array();  
 
$cache = array();  
    
for ($i=0; $i < 256; $i++)  
 
{  
 
$cache[$i] = $i*$i;  
 
} 
 
# 随机生成k值  
 
$i = $k;  
 
$index = 0;  
 
while ($i–)  
 
{  
 
$index = mt_rand(1,$point_len-100);  
 
array_push($clusters, array($point[$index], array($point[$index])));  
 
}  
 
run_time();  
 
$point_list = array();  
  
$run_num = 0;  
  
while (TRUE)  
 
{  
 
foreach ($point as $value)  
 
{  
 
$smallest_distance = 10000000;  
  
# 求出距离最小的点  
 
# index用于保存point最靠近的k值  
 
$index = 0;  
 
$i = $k;  
 
while ($i–)  
 
{  
 
$distance = 0;  
 
foreach ($value as $key => $p1)  
 
{  
 
&n 
bsp; if ($p1 > $clusters[$i][0][$key])  
 
{  
 
$distance += $cache[$p1 - $clusters[$i][0][$key]];  
 
}  
 
else  
 
{  
 
$distance += $cache[$clusters[$i][0][$key] – $p1];  
 
}  
 
} 
 
$ii++;  
 
 
if ($distance < $smallest_distance)  
 
{  
 
$smallest_distance = $distance;  
 
$index = $i;  
 
}  
 
}  
 
$point_list[$index][] = $value;  
 
}  
  
$diff = 0;  
 
# 1个1个迭代k值  
 
$i = $k;  
 
while ($i–)  
 
{  
 
$old = $clusters[$i];  
  
# 移到到队列中心  
 
$center = calculateCenter($point_list[$i], 3);  
 
# 形成新的k值集合队列  
 
$new_cluster = array($center, $point_list[$i]);  
 
$clusters[$i] = $new_cluster;  
  
# 计算新的k值与队列所在点的位置  
 
$diff = euclidean($old[0], $center);  
 
} 
 
# 判断是否已足够聚合  
 
if ($diff < $min_diff)  
 
{  
 
break;  
> 
 
}  
}  
 
echo ‘—>’.$ii;  
  
return $clusters;  
 
}  
  
# 计算2点距离  
 
$ii = 0;  
 
function euclidean($p1, $p2)  
 
{  
  
$s = 0;  
 
foreach ($p1 as $key => $value)  
 
{  
  
$temp = ($value – $p2[$key]);  
 
$s += $temp*$temp;  
 
} 
 
return sqrt($s);  
}  
  
# 移动k值到所有点的中心  
 
function calculateCenter($point_list, $attr_num) {  
 
$vals = array();  
 
$point_num = 0;  
 
 
 
$keys = array_keys($point_list[0]);  
 
foreach($keys as $value)  
 
{  
 
$vals[$value] = 0;  
 
}  
foreach ($point_list as $arr)  
 
{  
 
$point_num++;  
 
foreach ($arr as $key => $value)  
 
{  
 
$vals[$key] += $value;  
 
}  
 
}    
foreach ($keys as $index)  
 
{  
 
$vals[$index] = $vals[$index] / $point_num;  
 
}  
  
return $vals;  
 
}     
 
function RGBToHex($r, $g=”, $b=”)  
 
{  
 
if (is_array($r))  
 
{  
 
$b = $r['b'];  
 
$g = $r['g'];  
 
 
$r = $r['r'];  
 
}  
  
$hex = “#”;  
 
$hex.= str_pad(dechex($r), 2, ’0′, STR_PAD_LEFT);  
 
$hex.= str_pad(dechex($g), 2, ’0′, STR_PAD_LEFT);  
 
$hex.= str_pad(dechex($b), 2, ’0′, STR_PAD_LEFT);  
  
return $hex;  
 
}  
 
?>
 

  (欣才PHP培训

本文由欣才IT学院整理发布,未经许可,禁止转载。