— Mendeteksi Gambar Serupa atau biasa remove duplicate image – Hilangkan Duplikasi Foto akan saya gunakan untuk mengurangi file media pada WhatsApp yang kadang isinya belasan ribu file, bila kalian sudah membaca akses storage ponsel yang menggunakan bahasa C# dengan Media Transfer Protocol. Belasan ribu file media yang isinya gambar semua tentu tidak semuanya dipakai! akan terasa sekali kalau kita menggunakan storage jenis HDD yang cukup lambat!
Namun walaupun kalian telah menggunakan storage bertipe SSD untuk meningkatkan akses baca tulis, maka alangkah baiknya kalian menerapkan Mendeteksi Gambar Serupa – remove dupilcate image sehingga ukurannya yang belasan ribu tersebut bisa dikurangi lagi. Ada beberapa aplikasi android untuk deteksi gambar serupa – remove duplicate image
tapi saya tertarik membuat algoritma tersendiri atau kalian tertarik ingin tahu cara kerja aplikasi hilangkan duplikasi foto tersebut?
Algoritma deteksi gambar serupa – remove duplicate image
Contents
Algoritma deteksi gambar serupa – remove duplicate image yang paling mudah yaitu menggunakan teknik hashing. Fungsi hash/hash function adalah sebuah pemetaan dari sebuah himpunan asal/domain (berupa teks/gambar/atau sembarang object) yang memiliki panjang/ukuran yang beragam ke suatu nilai/vektor/string yang (biasanya) memiliki panjang tetap. Hasil pemetaan-nya sering disebut sebagai nilai hash (terkadang disebut juga hash codes, digests, atau hashes) atau sering disebut dengan Perceptual image hashing
Kegunaan hash value
Fungsi hash digunakan di banyak aplikasi, baik cryptography, database, sampai di data science dalam pengolahan data besar. Fungsi Hash juga bermacam-macam, salah satu yang paling tenar mungkin Secure Hash Algorithm 1 (SHA-1) dalam cryptographic hashing. Nah contoh yang akan kita gunakan dengan tujuan untuk deteksi gambar serupa – remove duplicate image dengan menghitung jarak antar hash value. Tentu jika ada 2 file gambar hanya berbeda nama file maka akan dianggap 2 file yang berbeda, nah hash function yang akan kita gunakan lebih dari itu! misalkan terjadi resize, terjadi perubahan content (dikasih coretan).
Library hash Image
Library hash image ada banyak sekali dan yang paling gampang menggunakan bahasa Python yaitu
Imagedash sesuai dengan dokumentasinya menggunakan beberapa algoritma seperti average, perceptual, difference, dan wavelet
The image hash algorithms (average, perceptual, difference, wavelet) analyse the image structure on luminance (without color information). The color hash algorithm analyses the color distribution and black & gray fractions (without position information).
Imagededup lebih advance lagi karena banyak menggunakan library tensorflow
Mendeteksi Gambar Serupa – remove dupilcate image secara mudah gunakan saja library imagedash, yuk kita buat algoritmanya secara visual menggunakan excel saja terlebih dahulu. Misalkan saja kita punya record file ada 10, maka perhitungannya menggunakan teknik combination dengan r = 2, maksudnya adalah semua file akan dihitung jaraknya dengan file lain tapi tidak dengan dirinya sendiri.
jadi file 1 akan dihitung jarak terhadap 2,3,4,5,6,7,8,9,10, kemudian file 2 akan dihitung jarak terhadap 3,4,5,6,7,8,9,10 dan begitu seterusnya. Kita gunakan library numpy dan itertools
import numpy as np from itertools import combinations n = 10 #jumlah file comb = combinations(np.arange(1,n+1),r=2) records = list() # Print the obtained permutations for idx in list(comb): print(idx)
kalian bisa melihat hasilnya sebagai berikut
(1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) (1, 9) (1, 10) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) (2, 9) (2, 10) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) (3, 9) (3, 10) (4, 5) (4, 6) (4, 7) (4, 8) (4, 9) (4, 10) (5, 6) (5, 7) (5, 8) (5, 9) (5, 10) (6, 7) (6, 8) (6, 9) (6, 10) (7, 8) (7, 9) (7, 10) (8, 9) (8, 10) (9, 10)
Jadi sudah paham ya, kita menggunakan teknik combination, yuk sekarang kita coba saja, misalkan saya punya folder data yang berisi gambar *.jpg. Langsung kita lakukan enumerasi sebagai berikut dan menyimpannya dalam bentuk list()
from PIL import Image import imagehash import glob files = glob.glob("data/*.jpg") n = len(files) nilai_hash = list() for file in files: nilai_hash.append(imagehash.average_hash(Image.open(file)))
Jadi semua file akan dihitung nilai hash nya, langkah selanjutnya melakukan perhitungan jarak dan menerapkan nilai ambang batas. Variabel global records = list()
digunakan untuk menyimpan hasil setiap perhitungan jika memenuhi syarat jarak<jarak_minimal
import numpy as np from itertools import combinations comb = combinations(np.arange(0,n),r=2) records = list() jarak_minimal = 5 for idx in list(comb): a = idx[0] b = idx[1] jarak = (nilai_hash[a]-nilai_hash[b]) print(files[a]+" --> "+file[b]+" : "+str(jarak)) record ={'file1':files[a],'file2':files[b],'jarak':jarak} if(jarak<jarak_minimal): records.append(record)
Agar tampil menarik dibuatlah data frame
import pandas as pd final = pd.DataFrame(records) print(final)
hasilnya
file1 file2 jarak 0 data\12.jpg data\13.jpg 2 1 data\7.jpg data\8.jpg 2 2 data\7.jpg data\9.jpg 2 3 data\8.jpg data\9.jpg 0
artinya file 12.jpg mirip dengan 13.jpg dan begitu seterusnya.
Perbaikan kode
Pada contoh diatas harus ada beberapa perbaikanya, kalian bisa melihat hasil mengenai file 7.jpg; 8; jpg; dan 9.jpg
file1 file2 jarak 0 data\12.jpg data\13.jpg 2 1 data\7.jpg data\8.jpg 2 2 data\7.jpg data\9.jpg 2 3 data\8.jpg data\9.jpg 0
Kira-kira mana yang harus didelete? karena artinya adalah 3 file tersebut harus didelete dengan meninggalkan satu file saja, untuk hal tersebut kalian gunakan teknik meta file yaitu selain membaca nama file juga membaca file tersebut di create. Sehingga misalkan saja yang akan dihapus 7.jpg dan 9.jpg karena 8.jpg baru saja dibuat/create! hemm… itu PR kalian saja…untuk melengkapi perbaikan kodenya sendiri, saya kasih bocoran cara mengelola date time di Python
Hash Image di Java
Tentu bila kalian ingin membuat aplikasi berbasis android java, maka library diatas tidak bisa digunakan. Ada beberapa library/kode yang bisa kalian pakai salah satunya adalah
- https://github.com/srch07/Duplicate-Image-Finder-API kode/library ini simple tapi sayang nya tidak robust! kalau beda ukuran width dan height nya maka tidak bisa!
- http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html pembahasan mengenai algoritma phash.org
- https://github.com/krishnact/jphash bisa juga kalian gunakan
- https://reposhub.com/java/imagery/KilianB-JImageHash.html yang kode ada di https://github.com/KilianB/JImageHash
Saya sarankan untuk menggunakan point 4 karena lebih robust, bila ingin mencoba bisa gunakan gradle (kalau menggunakan gradle ada error di JDFX nya) dan maven https://mvnrepository.com/artifact/dev.brachtendorf/JImageHash/1.0.0 . Mari kita coba menggunakan maven saja, oiya saya memilih PerceptiveHash berdasarkan fitur Frequency dimana Hash based on Discrete Cosine Transformation. Smaller hash distribution but best accuracy / bitResolution sehingga semakin kecil nilainya semakin tidak sensitif.
Algo / Resolution | 2^6 = 64 bit | 2^8 = 256 bit | 2^12 = 4096 bit | 2^18 = 262144 bit |
Perceptive Hash |
Kode yang saya gunakan u ntuk menghitung mendeteksi gambar serupa atau biasa remove duplicate image yaitu
File lokasi = new File("D:\\C# akses storage ponsel\\data"); File [] files = lokasi.listFiles(); HashingAlgorithm hasher = new PerceptiveHash(128); Map map = new HashMap(); int index=0; for(File f : files){ Hash hash = hasher.hash(f); map.put(index,hash); index++; } double ambang_batas = .2; for(int i=0;i<map.size();i++){ for(int j=i;j<map.size();j++){ if(i!=j){ String a= files[i].getName(); String b= files[j].getName(); Hash hash0 = (Hash)map.get(i); Hash hash1 = (Hash)map.get(j); double similarityScore = hash0.normalizedHammingDistance(hash1); if(similarityScore<=ambang_batas){ System.out.println(a+" , "+b+": "+similarityScore); } } } }
hasilnya
12.jpg , 13.jpg: 0.17424242424242425 7.jpg , 8.jpg: 0.1590909090909091 8.jpg , 9.jpg: 0.16666666666666666