好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

由于使用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聚类算法识别图片主色调的详细内容...

  阅读:71次