Bagaimana cara mengukur kesamaan antara dua gambar? [Tutup]

94

Saya ingin membandingkan tangkapan layar dari satu aplikasi (bisa jadi laman Web) dengan tangkapan layar yang diambil sebelumnya untuk menentukan apakah aplikasi tersebut menampilkan dirinya sendiri dengan benar. Saya tidak ingin perbandingan pencocokan persis, karena aspeknya bisa sedikit berbeda (dalam kasus aplikasi Web, bergantung pada browser, beberapa elemen mungkin berada di lokasi yang sedikit berbeda). Ini harus memberi ukuran seberapa mirip tangkapan layar.

Apakah ada pustaka / alat yang sudah melakukan itu? Bagaimana Anda akan menerapkannya?

Antoine Aubry
sumber
1
Ada beberapa jawaban bagus dalam pertanyaan serupa lainnya: stackoverflow.com/questions/75891/…
blak
1
Dan lebih banyak lagi di sini: stackoverflow.com/questions/189943/…
Anoyz
1
Saatnya memperbarui jawaban sehubungan dengan kemajuan terbaru dalam Machine Learning dan lebih khusus lagi "Pembelajaran Mendalam".
jldupont
Lab saya juga perlu memecahkan masalah ini, dan menggunakan alur kerja yang diuraikan di sini: douglasduhaime.com/posts/…
duhaime

Jawaban:

73

Ini sepenuhnya bergantung pada seberapa pintar Anda menginginkan algoritme tersebut.

Misalnya, berikut beberapa masalah:

  • gambar yang dipotong vs. gambar yang tidak dipotong
  • gambar dengan teks ditambahkan vs. gambar lain tanpa
  • gambar cermin

Algoritme termudah dan paling sederhana yang pernah saya lihat untuk ini hanyalah melakukan langkah-langkah berikut untuk setiap gambar:

  1. skala ke sesuatu yang kecil, seperti 64x64 atau 32x32, abaikan rasio aspek, gunakan algoritme penskalaan gabungan, bukan piksel terdekat
  2. skala rentang warna sehingga yang paling gelap adalah hitam dan yang paling terang adalah putih
  3. putar dan balikkan gambar sehingga warna terkecil berada di kiri atas, lalu kanan atas lebih gelap berikutnya, kiri bawah lebih gelap berikutnya (sejauh mungkin tentu saja)

Mengedit Sebuah algoritma menggabungkan skala adalah salah satu yang saat scaling 10 pixel ke satu akan melakukannya dengan menggunakan fungsi yang mengambil warna semua 10 piksel dan menggabungkan mereka ke dalam satu. Dapat dilakukan dengan algoritme seperti averaging, mean-value, atau yang lebih kompleks seperti bicubic splines.

Kemudian hitung jarak rata-rata piksel demi piksel antara dua gambar.

Untuk mencari kemungkinan kecocokan dalam database, simpan warna piksel sebagai kolom individual dalam database, indeks banyak dari mereka (tapi tidak semua, kecuali Anda menggunakan gambar yang sangat kecil), dan lakukan kueri yang menggunakan rentang untuk masing-masing nilai piksel, yaitu. setiap gambar di mana piksel pada gambar kecil berada di antara -5 dan +5 dari gambar yang ingin Anda cari.

Ini mudah diterapkan, dan cukup cepat dijalankan, tetapi tentu saja tidak akan menangani perbedaan yang paling lanjut. Untuk itu Anda membutuhkan algoritma yang lebih canggih.

Lasse V. Karlsen
sumber
14
Apa yang dimaksud dengan "menggabungkan algoritma penskalaan"?
Gregg Lind
32

Cara 'klasik' untuk mengukur ini adalah dengan memecah gambar menjadi beberapa bagian dalam jumlah kanonik (katakanlah kisi 10x10) dan kemudian menghitung histogram nilai RGB di dalam setiap sel dan membandingkan histogram yang sesuai. Jenis algoritme ini lebih disukai karena kesederhanaannya dan invariannya terhadap penskalaan dan terjemahan (kecil!).

Louis Brandy
sumber
6
Bukankah ini serupa dengan melakukan satu histogram untuk keseluruhan gambar, tetapi dengan kelemahan tambahan karena tidak tahan terhadap cermin dan memutar?
dodgy_coder
2 histogram dari 2 bagian gambar akan memiliki presisi pencocokan yang lebih baik daripada 1 histogram secara keseluruhan. Meskipun ada kekurangan yang Anda sebutkan, itu tergantung pada masalah yang Anda pecahkan.
psiko brm
25

Gunakan histogram warna yang dinormalisasi. (Baca bagian tentang aplikasi di sini ), ini biasanya digunakan dalam sistem pengambilan / pencocokan gambar dan merupakan cara standar untuk mencocokkan gambar yang sangat andal, relatif cepat dan sangat mudah diterapkan.

Intinya, histogram warna akan menangkap distribusi warna gambar. Ini kemudian dapat dibandingkan dengan gambar lain untuk melihat apakah distribusi warnanya cocok.

Jenis pencocokan ini cukup tahan terhadap penskalaan (setelah histogram dinormalisasi), dan rotasi / pergeseran / gerakan dll.

Hindari perbandingan piksel demi piksel karena jika gambar diputar / sedikit bergeser, hal itu dapat menyebabkan perbedaan besar yang dilaporkan.

Histogram akan langsung dibuat sendiri (dengan asumsi Anda bisa mendapatkan akses ke nilai piksel), tetapi jika Anda tidak menyukainya, pustaka OpenCV adalah sumber yang bagus untuk melakukan hal semacam ini. Berikut adalah presentasi powerpoint yang menunjukkan kepada Anda cara membuat histogram menggunakan OpenCV.

Lehane
sumber
14

Bukankah algoritme pengkodean video seperti MPEG menghitung perbedaan antara setiap bingkai video sehingga mereka dapat menyandikan delta saja? Anda mungkin melihat bagaimana algoritme encoding video menghitung perbedaan bingkai tersebut.

Lihat aplikasi pencarian gambar open source ini http://www.semanticmetadata.net/lire/ . Ini menjelaskan beberapa algoritme kesamaan gambar, tiga di antaranya berasal dari standar MPEG-7: ScalableColor, ColorLayout, EdgeHistogram, dan Auto Color Correlogram.

Mark B
sumber
1
Ini tidak akan menjawab pertanyaan di sini. Pertanyaannya bukan tentang perbandingan piksel per piksel.
Kousha
@Kha Benar, tapi tetap menjadi arah yang menarik untuk berpikir.
makna-hal
13

Anda dapat menggunakan pendekatan matematika murni O(n^2), tetapi akan berguna hanya jika Anda yakin bahwa tidak ada offset atau semacamnya. (Meskipun jika Anda memiliki beberapa objek dengan pewarnaan yang homogen, itu masih akan bekerja dengan baik.)

Bagaimanapun, idenya adalah menghitung produk titik yang dinormalisasi dari dua matriks. C = sum(Pij*Qij)^2/(sum(Pij^2)*sum(Qij^2)).

Rumus ini sebenarnya adalah "cosinus" dari sudut antar matriks (wierd). Semakin besar kesamaan (katakanlah Pij=Qij), C akan menjadi 1, dan jika mereka benar-benar berbeda, katakanlah untuk setiap i,j Qij = 1(hindari pembagian nol) Pij = 255, maka untuk ukuran nxn, semakin besar n, semakin dekat ke nol kita akan Dapatkan. (Dengan perhitungan kasar :) C=1/n^2.

Shachar
sumber
8

Anda akan membutuhkan pengenalan pola untuk itu. Untuk menentukan perbedaan kecil antara dua gambar, jaring Hopfield bekerja dengan cukup baik dan cukup mudah diterapkan. Saya tidak tahu implementasi yang tersedia.

Konrad Rudolph
sumber
7

Solusi ruby ​​dapat ditemukan di sini

Dari readme:

Phashion adalah pembungkus Ruby di sekitar pustaka pHash, "hash perseptual", yang mendeteksi duplikat dan mendekati file multimedia duplikat

edk750
sumber
5

Cara mengukur kemiripan antara dua gambar sepenuhnya tergantung pada apa yang ingin Anda ukur, misalnya: kontras, kecerahan, modalitas, noise ... lalu pilih ukuran kemiripan yang paling sesuai untuk Anda. Anda dapat memilih dari MAD (mean absolute difference), MSD (mean squared difference) yang baik untuk mengukur kecerahan ... tersedia juga CR (koefisien korelasi) yang baik dalam merepresentasikan korelasi antara dua citra. Anda juga dapat memilih dari ukuran kesamaan berbasis histogram seperti SDH (deviasi standar histogram gambar perbedaan) atau ukuran kesamaan multimodalitas seperti MI (informasi timbal balik) atau NMI (informasi timbal balik yang dinormalisasi).

Karena ukuran kesamaan ini menghabiskan banyak waktu, disarankan untuk memperkecil gambar sebelum menerapkan ukuran ini pada gambar.

Gregor Simončič
sumber
4

Saya bertanya-tanya (dan saya benar-benar hanya membuang ide ke luar sana untuk ditembakkan) apakah sesuatu dapat diturunkan dengan mengurangi satu gambar dari gambar lainnya, dan kemudian mengompresi gambar yang dihasilkan sebagai jpeg gif, dan mengambil ukuran file sebagai ukuran kesamaan.

Jika Anda memiliki dua gambar yang identik, Anda akan mendapatkan kotak putih, yang akan dikompres dengan sangat baik. Semakin banyak gambar yang berbeda, semakin kompleks gambar tersebut untuk direpresentasikan, dan karenanya semakin tidak dapat dikompres.

Mungkin bukan pengujian yang ideal, dan mungkin jauh lebih lambat dari yang diperlukan, tetapi ini mungkin bekerja sebagai implementasi yang cepat dan kotor.

Matt Sheppard
sumber
Pikirkan tentang memutar 90 derajat; gambar masih serupa.
makna-hal
3

Anda mungkin melihat kode untuk findimagedupes alat open source , meskipun tampaknya telah ditulis dalam perl, jadi saya tidak bisa mengatakan betapa mudahnya untuk mengurai ...

Membaca halaman findimagedupes yang saya suka, saya melihat bahwa ada implementasi C ++ dari algoritma yang sama . Agaknya ini akan lebih mudah dipahami.

Dan tampaknya Anda juga bisa menggunakan gqview .

dmckee --- mantan moderator anak kucing
sumber
2

Bukan untuk menjawab pertanyaan Anda secara langsung, tetapi saya telah melihat ini terjadi. Microsoft baru-baru ini meluncurkan alat yang disebut PhotoSynth yang melakukan sesuatu yang sangat mirip untuk menentukan area yang tumpang tindih dalam sejumlah besar gambar (yang dapat memiliki rasio aspek berbeda).

Saya ingin tahu apakah mereka memiliki perpustakaan atau potongan kode yang tersedia di blog mereka.

Vaibhav
sumber
1
Teknologi ini. Sudah tidak dilanjutkan.
Joseph Rosson
2

untuk memperluas catatan Vaibhav, hugin adalah 'autostitcher' open-source yang seharusnya memiliki beberapa wawasan tentang masalah tersebut.

pantai
sumber
2

Ada perangkat lunak untuk pengambilan gambar berbasis konten, yang melakukan (sebagian) apa yang Anda butuhkan. Semua referensi dan penjelasan ditautkan dari situs proyek dan ada juga buku teks pendek (Kindle): LIRE

Mathias
sumber
1

Anda dapat menggunakan Siamese Network untuk melihat apakah kedua gambar tersebut serupa atau tidak sama dengan mengikuti tutorial ini . Tutorial ini mengelompokkan gambar yang serupa sedangkan Anda dapat menggunakan L2jarak untuk mengukur kesamaan dua gambar.

cpwah
sumber
0

Jika ini adalah sesuatu yang akan Anda lakukan sesekali dan tidak perlu diotomatisasi, Anda dapat melakukannya di editor gambar yang mendukung lapisan, seperti Photoshop atau Paint Shop Pro (mungkin GIMP atau Paint.Net juga, tetapi saya ' saya tidak yakin tentang itu). Buka kedua tangkapan layar, dan letakkan satu sebagai lapisan di atas yang lain. Ubah blending mode layer menjadi Difference, dan semua yang sama di antara keduanya akan menjadi hitam. Anda dapat memindahkan lapisan atas untuk meminimalkan perbedaan perataan.

Mark Ransom
sumber
Alat lain yang membuat perbedaan jenis ini sangat sederhana adalah kaleidoscopeapp.com
Michael Osofsky
0

Beyond Compare memiliki perbandingan piksel demi piksel untuk gambar, misalnya,

masukkan deskripsi gambar di sini

emallove
sumber
@xilpex, OP bertanya: Apakah ada perpustakaan / alat yang sudah melakukan itu ? Jawaban saya menyertakan link ke perpustakaan / alat tersebut.
emallove
-1

Nah, metode tingkat dasar yang benar-benar digunakan bisa melalui setiap warna piksel dan membandingkannya dengan warna piksel yang sesuai pada gambar kedua - tapi itu mungkin solusi yang sangat lambat.

Ross
sumber