程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 利用k-means聚類算法識別圖片主色調

利用k-means聚類算法識別圖片主色調

編輯:關於PHP編程

由於使用php來寫圖片主色調識別功能太麻煩了,所以我給大家介紹利用利用k-means聚類算法識別圖片主色調方法,比php要己100倍哦。

識別圖片主色調這個,網上貌似有幾種方法,不過,最准確,最優雅的解決方案還是利用聚類算法來做。。。

直接上代碼。。。。不過,我測試結果表示,用PHP來做,效率不佳,PHP不適合做這種大規模運算~~~,用nodejs做 效率可以高出100倍左右。。。

 代碼如下 復制代碼

<?php 

$start = microtime(TRUE); 

main(); 

 

function main($img = ‘colors_files/T1OX3eXldXXXcqfYM._111424.jpg’) 

 

 

list($width, $height, $mime_code) = getimagesize($img); 

 

$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; 

?> 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved