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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM