由于使用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 ; } ?>查看更多关于利用k-means聚类算法识别图片主色调的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did29444