PHP比较一组图片是否有相似的图片:之两层循环,使用握手计数原理,计算出两两图片对比的组合,并删除重复的图片
说明:
最近有一个需求,说。一组图片地址,如果两张图片相似,就进行去重。
例如:
如下图,img_list 中,如果第一个和第二个,图片相同,那么就保留其中一个,其余的依次类推,最终取的一个不重复的,图片img_listing。
思路:
至于图片怎么识别为重复的,这里使用的是一个扩展,扩展git地址:https://github.com/jenssegers/imagehash
这个利用的是,图像哈希。
Laravel安装扩展
composer require jenssegers/imagehash
去重思路:
1、N张图片对比后去重,这里就需要每两两进行比较,如果重复,就删除一张。所以,这里两两的组合比对次数为 ((n-1)*n )/2。这其实就是一个握手计数原理。
2、所以,我们可以按这个逻辑进行写代码。
步骤一:定义一个方法,传入需要对比的图片地址数组;
步骤二:使用两层for循环,计算出所有的组合数;
步骤三:对二中的组合进行哈希比对,如果为重复,即删除第一个键名内容,然后,将删除后的数组再传入到该方法中,如此进行递归调用,最后取的没有重复的数组img。
代码如下:
/** * 删除数组中相似的图片地址方法 * $img_list 图片数组list * $img_count 数组长度 * $img_hash 图片地址与的散列值的映射数组,承载,减少重复处理次数,优化处理时间 */ public function deleteSha1Img($img_list, $img_count, $img_hash = []){ try{ $hasher = new ImageHash(new DifferenceHash()); //两层循环,使用握手计数原理,计算出两两图片对比的组合 for ($i=0; $i < $img_count; $i++) { for ($i1 = $img_count - 1; $i1 > $i; $i1 --) { if(empty($img_hash[$img_list[$i]])){//承载数组中,没有,直接获取 $value1_sh = $hasher->hash($img_list[$i]);//获取图片的散列值对象 $hash->toHex(); $img_hash[$img_list[$i]] = $value1_sh;//进行赋值 }else{ $value1_sh = $img_hash[$img_list[$i]];//有,直接读取 } if(empty($img_hash[$img_list[$i1]])){ $value2_sh = $hasher->hash($img_list[$i1]); $img_hash[$img_list[$i1]] = $value2_sh; }else{ $value2_sh = $img_hash[$img_list[$i1]]; } $sh = $hasher->distance($value1_sh, $value2_sh);//进行相似比较 if($sh <= 5){ unset($img_list[$i]);//两张相似的,直接删除第一张 $img_list = array_values($img_list);//对新数组进行重新排序 return $this->deleteSha1Img($img_list, count($img_list), $img_hash); } } } }catch(\Exception $e){ throw new \Exception($e->getMessage()); } return $img_list; }
结束:
记录一下,发现最近经常写递归,递归注意返回值,不然会出现,明明有值,却调用的时候,返回null。