Inilah yang ingin saya lakukan:
Saya mengambil foto dengan webcam secara berkala. Semacam hal selang waktu. Namun, jika tidak ada yang benar-benar berubah, yaitu, gambar cukup banyak terlihat sama, saya tidak ingin menyimpan snapshot terbaru.
Saya membayangkan ada beberapa cara untuk mengukur perbedaan, dan saya harus menentukan ambang batas secara empiris.
Saya mencari kesederhanaan daripada kesempurnaan. Saya menggunakan python.
Jawaban:
Ide umum
Opsi 1: Muat kedua gambar sebagai array (
scipy.misc.imread
) dan hitung perbedaan elemen-bijaksana (pixel-by-pixel). Hitung norma perbedaannya.Opsi 2: Muat kedua gambar. Hitung beberapa vektor fitur untuk masing-masing (seperti histogram). Hitung jarak antara vektor fitur daripada gambar.
Namun, ada beberapa keputusan yang harus diambil terlebih dahulu.
Pertanyaan
Anda harus menjawab pertanyaan-pertanyaan ini terlebih dahulu:
Apakah gambar dengan bentuk dan dimensi yang sama?
Jika tidak, Anda mungkin perlu mengubah ukuran atau memangkasnya. PIL library akan membantu melakukannya dengan Python.
Jika mereka diambil dengan pengaturan yang sama dan perangkat yang sama, mereka mungkin sama.
Apakah gambar sejajar dengan baik?
Jika tidak, Anda mungkin ingin menjalankan korelasi silang terlebih dahulu, untuk menemukan keselarasan terbaik terlebih dahulu. SciPy memiliki fungsi untuk melakukannya.
Jika kamera dan pemandangan diam, gambar-gambar tersebut kemungkinan akan sejajar dengan baik.
Apakah paparan gambar selalu sama? (Apakah terang / kontras sama?)
Jika tidak, Anda mungkin ingin menormalkan gambar.
Tapi hati-hati, dalam beberapa situasi ini mungkin melakukan lebih banyak kesalahan daripada kebaikan. Misalnya, satu piksel terang pada latar belakang gelap akan membuat gambar yang dinormalisasi menjadi sangat berbeda.
Apakah informasi warna penting?
Jika Anda ingin melihat perubahan warna, Anda akan memiliki vektor nilai warna per titik, bukan nilai skalar seperti pada gambar skala abu-abu. Anda perlu lebih banyak perhatian saat menulis kode seperti itu.
Apakah ada tepi yang berbeda pada gambar? Apakah mereka cenderung bergerak?
Jika ya, Anda dapat menerapkan algoritme deteksi tepi terlebih dahulu (mis. Menghitung gradien dengan transformasi Sobel atau Prewitt, menerapkan beberapa ambang batas), lalu membandingkan tepi pada gambar pertama dengan tepi pada yang kedua.
Apakah ada noise pada gambar?
Semua sensor mencemari gambar dengan sejumlah noise. Sensor berbiaya rendah memiliki lebih banyak noise. Anda mungkin ingin menerapkan sedikit pengurangan noise sebelum membandingkan gambar. Blur adalah pendekatan yang paling sederhana (tapi bukan yang terbaik) di sini.
Perubahan apa yang ingin Anda perhatikan?
Ini dapat memengaruhi pilihan norma yang digunakan untuk perbedaan antar gambar.
Pertimbangkan untuk menggunakan norma Manhattan (jumlah nilai absolut) atau norma nol (jumlah elemen yang tidak sama dengan nol) untuk mengukur seberapa banyak gambar telah berubah. Yang pertama akan memberi tahu Anda berapa banyak gambar dimatikan, yang terakhir hanya akan memberitahu berapa banyak piksel berbeda.
Contoh
Saya berasumsi gambar Anda selaras, ukuran dan bentuk yang sama, mungkin dengan pencahayaan berbeda. Untuk kesederhanaan, saya mengonversinya menjadi skala abu-abu walaupun itu adalah gambar berwarna (RGB).
Anda akan membutuhkan impor ini:
Fungsi utama, membaca dua gambar, mengkonversi ke skala abu-abu, membandingkan dan mencetak hasil:
Bagaimana cara membandingkan.
img1
danimg2
adalah array 2D SciPy di sini:Jika file tersebut adalah gambar berwarna,
imread
mengembalikan array 3D, saluran RGB rata-rata (sumbu array terakhir) untuk mendapatkan intensitas. Tidak perlu melakukannya untuk gambar skala abu-abu (mis..pgm
):Normalisasi itu sepele, Anda dapat memilih untuk menormalkan ke [0,1] daripada [0,255].
arr
adalah array SciPy di sini, jadi semua operasi adalah elemen-bijaksana:Jalankan
main
fungsinya:Sekarang Anda bisa meletakkan ini semua dalam skrip dan menjalankan dua gambar. Jika kita membandingkan gambar dengan dirinya sendiri, tidak ada perbedaan:
Jika kita mengaburkan gambar dan dibandingkan dengan aslinya, ada beberapa perbedaan:
PS Seluruh skrip compare.py .
Pembaruan: teknik yang relevan
Karena pertanyaannya adalah tentang urutan video, di mana frame cenderung hampir sama, dan Anda mencari sesuatu yang tidak biasa, saya ingin menyebutkan beberapa pendekatan alternatif yang mungkin relevan:
Saya sangat merekomendasikan untuk melihat buku "Belajar OpenCV", Bab 9 (Bagian gambar dan segmentasi) dan 10 (Pelacakan dan gerakan). Yang pertama mengajarkan untuk menggunakan metode pengurangan Background, yang terakhir memberikan beberapa info tentang metode aliran optik. Semua metode diimplementasikan dalam pustaka OpenCV. Jika Anda menggunakan Python, saya sarankan untuk menggunakan OpenCV ≥ 2.3, dan
cv2
modul Python -nya .Versi pengurangan latar belakang yang paling sederhana:
Versi yang lebih canggih mempertimbangkan seri waktu akun untuk setiap piksel dan menangani adegan non-statis (seperti memindahkan pohon atau rumput).
Gagasan aliran optik adalah untuk mengambil dua atau lebih bingkai, dan menetapkan vektor kecepatan ke setiap piksel (aliran optik padat) atau beberapa di antaranya (aliran optik jarang). Untuk memperkirakan aliran optik yang jarang, Anda dapat menggunakan metode Lucas-Kanade (ini juga diterapkan di OpenCV). Jelas, jika ada banyak aliran (rata-rata tinggi di atas nilai maks dari bidang kecepatan), maka ada sesuatu yang bergerak dalam bingkai, dan gambar berikutnya lebih berbeda.
Membandingkan histogram dapat membantu mendeteksi perubahan mendadak antara frame yang berurutan. Pendekatan ini digunakan dalam Courbon et al, 2010 :
sumber
RuntimeWarning: invalid value encountered in double_scalars
on line 44 (return (arr-amin)*255/rng
) danValueError: array must not contain infs or NaNs
on line 30 (z_norm = norm(diff.ravel(), 0)
)rng
sama dengan nol. Tambahkan saja cek dan aturrng = 1
Solusi sederhana:
Encode gambar sebagai jpeg dan cari perubahan substansial dalam ukuran file .
Saya telah mengimplementasikan sesuatu yang mirip dengan gambar mini video, dan memiliki banyak kesuksesan dan skalabilitas.
sumber
Anda dapat membandingkan dua gambar menggunakan fungsi dari PIL .
Objek diff adalah gambar di mana setiap piksel adalah hasil dari pengurangan nilai warna dari piksel tersebut di gambar kedua dari gambar pertama. Menggunakan gambar diff Anda dapat melakukan beberapa hal. Yang paling sederhana adalah
diff.getbbox()
fungsinya. Ini akan memberi tahu Anda persegi panjang minimal yang berisi semua perubahan antara dua gambar Anda.Anda mungkin dapat mengimplementasikan perkiraan hal-hal lain yang disebutkan di sini menggunakan fungsi dari PIL juga.
sumber
Dua metode populer dan relatif sederhana adalah: (a) jarak Euclidean sudah disarankan, atau (b) normalisasi lintas-korelasi. Korelasi silang yang dinormalisasi cenderung lebih kuat pada perubahan pencahayaan daripada korelasi silang sederhana. Wikipedia memberikan rumus untuk korelasi silang yang dinormalisasi . Ada metode yang lebih canggih juga, tetapi mereka membutuhkan sedikit lebih banyak pekerjaan.
Menggunakan sintaks seperti numpy,
dengan asumsi itu
i1
dani2
adalah array gambar grayscale 2D.sumber
Suatu hal yang sepele untuk dicoba:
Ubah sampel kedua gambar menjadi thumbnail kecil (mis. 64 x 64) dan bandingkan thumbnail piksel-demi-piksel dengan ambang batas tertentu. Jika gambar aslinya hampir sama, thumbnail yang di-resampled akan sangat mirip atau bahkan sama persis. Metode ini menangani kebisingan yang dapat terjadi terutama dalam adegan cahaya rendah. Bahkan mungkin lebih baik jika Anda menggunakan skala abu-abu.
sumber
Saya membahas secara khusus pertanyaan tentang bagaimana menghitung jika mereka "cukup berbeda". Saya berasumsi Anda dapat mengetahui cara mengurangi piksel satu per satu.
Pertama, saya akan mengambil banyak gambar tanpa perubahan apa pun , dan mencari tahu jumlah maksimum yang diubah oleh piksel apa pun hanya karena variasi tangkapan, derau dalam sistem pencitraan, artefak kompresi JPEG, dan perubahan pencahayaan dari waktu ke waktu dalam pencahayaan. . Mungkin Anda akan menemukan bahwa perbedaan 1 atau 2 bit diharapkan bahkan ketika tidak ada yang bergerak.
Kemudian untuk tes "nyata", Anda ingin kriteria seperti ini:
Jadi, mungkin, jika E = 0,02, P = 1000, itu akan berarti (kurang-lebih) bahwa itu akan "berbeda" jika ada satu piksel yang berubah lebih dari ~ 5 unit (dengan asumsi gambar 8-bit), atau jika lebih dari 1000 piksel memiliki kesalahan sama sekali.
Ini dimaksudkan terutama sebagai teknik "triase" yang baik untuk dengan cepat mengidentifikasi gambar yang cukup dekat sehingga tidak perlu pemeriksaan lebih lanjut. Gambar-gambar yang "gagal" mungkin lebih ke teknik yang lebih rumit / mahal yang tidak akan memiliki positif palsu jika kamera bergetar sedikit, misalnya, atau lebih kuat untuk perubahan pencahayaan.
Saya menjalankan proyek open source, OpenImageIO , yang berisi utilitas bernama "idiff" yang membandingkan perbedaan dengan ambang batas seperti ini (bahkan lebih rumit, sebenarnya). Bahkan jika Anda tidak ingin menggunakan perangkat lunak ini, Anda mungkin ingin melihat sumbernya untuk melihat bagaimana kami melakukannya. Ini digunakan secara komersial sedikit dan teknik thresholding ini dikembangkan sehingga kami bisa memiliki test suite untuk rendering dan perangkat lunak pemrosesan gambar, dengan "gambar referensi" yang mungkin memiliki perbedaan kecil dari platform ke platform atau saat kami membuat perubahan kecil untuk algoritma, jadi kami ingin operasi "cocok dalam toleransi".
sumber
Saya memiliki masalah yang sama di tempat kerja, saya sedang menulis ulang titik akhir transformasi gambar kami dan saya ingin memeriksa bahwa versi baru menghasilkan keluaran yang sama atau hampir sama dengan versi lama. Jadi saya menulis ini:
https://github.com/nicolashahn/diffimg
Yang beroperasi pada gambar dengan ukuran yang sama, dan pada level per-pixel, mengukur perbedaan nilai di setiap saluran: R, G, B (, A), mengambil perbedaan rata-rata dari saluran tersebut, dan kemudian rata-rata selisih lebih dari semua piksel, dan mengembalikan rasio.
Misalnya, dengan gambar 10x10 piksel putih, dan gambar yang sama tetapi satu piksel telah berubah menjadi merah, perbedaan pada piksel tersebut adalah 1/3 atau 0,33 ... (RGB 0,0,0 vs 255,0,0 ) dan semua piksel lainnya adalah 0. Dengan total 100 piksel, 0,33 ... / 100 = perbedaan ~ 0,33% pada gambar.
Saya percaya ini akan bekerja dengan sempurna untuk proyek OP (saya menyadari ini adalah posting yang sangat lama sekarang, tetapi memposting untuk StackOverflowers masa depan yang juga ingin membandingkan gambar dengan python).
sumber
Sebagian besar jawaban yang diberikan tidak akan berurusan dengan tingkat pencahayaan.
Pertama-tama saya akan menormalkan gambar ke tingkat cahaya standar sebelum melakukan perbandingan.
sumber
Cara lain yang bagus dan sederhana untuk mengukur kesamaan antara dua gambar:
Jika orang lain tertarik dengan cara yang lebih kuat untuk membandingkan gambar kesamaan, saya mengumpulkan tutorial dan web app untuk mengukur dan memvisualisasikan gambar yang sama menggunakan Tensorflow.
sumber
skimage
sangat bagus digunakan untuk aplikasi ini. Saya menggunakanfrom skimage.measure import compare_ssim, compare_mse
banyak. skimage.measure docs .Pernahkah Anda melihat Algoritma untuk menemukan pertanyaan gambar yang serupa ? Lihat untuk melihat saran.
Saya akan menyarankan transformasi wavelet dari frame Anda (Saya telah menulis ekstensi C untuk itu menggunakan transformasi Haar); kemudian, dengan membandingkan indeks faktor-faktor wavelet terbesar (proporsional) antara kedua gambar, Anda harus mendapatkan perkiraan kemiripan numerik.
sumber
Saya minta maaf jika sudah terlambat untuk menjawab, tetapi karena saya sudah melakukan hal yang serupa, saya pikir saya bisa berkontribusi.
Mungkin dengan OpenCV Anda bisa menggunakan pencocokan templat. Dengan asumsi Anda menggunakan webcam seperti yang Anda katakan:
Tip: max_val (atau min_val tergantung pada metode yang digunakan) akan memberi Anda angka, angka besar. Untuk mendapatkan perbedaan dalam persentase, gunakan pencocokan templat dengan gambar yang sama - hasilnya adalah 100% Anda.
Kode palsu untuk dicontohkan:
Semoga ini bisa membantu.
sumber
Jarak penggerak bumi mungkin persis seperti yang Anda butuhkan. Mungkin abit berat untuk melaksanakan secara real time sekalipun.
sumber
Bagaimana dengan menghitung Jarak Manhattan dari dua gambar. Itu memberi Anda nilai n * n. Kemudian Anda bisa melakukan sesuatu seperti rata-rata baris untuk mengurangi ke nilai n dan fungsi lebih dari itu untuk mendapatkan satu nilai tunggal.
sumber
Saya telah memiliki banyak keberuntungan dengan gambar jpg yang diambil dengan kamera yang sama pada tripod dengan (1) sangat menyederhanakan (seperti pergi dari lebar 3000 piksel ke lebar 100 piksel atau bahkan lebih sedikit) (2) meratakan setiap jpg array menjadi satu vektor (3) gambar sekuensial berkorelasi berpasangan dengan algoritma korelasi sederhana untuk mendapatkan koefisien korelasi (4) kuadrat koefisien korelasi untuk mendapatkan r-square (yaitu fraksi variabilitas dalam satu gambar dijelaskan oleh variasi di gambar berikutnya) (5) umumnya dalam aplikasi saya jika r-square <0,9, saya katakan dua gambar berbeda dan sesuatu terjadi di antaranya.
Ini kuat dan cepat dalam implementasi saya (Mathematica 7)
Sebaiknya Anda bermain-main dengan bagian gambar yang Anda minati dan memusatkan perhatian pada hal itu dengan memangkas semua gambar ke area kecil itu, jika tidak, jauh dari kamera tetapi perubahan penting akan terlewatkan.
Saya tidak tahu cara menggunakan Python, tetapi saya yakin itu berkorelasi juga, bukan?
sumber
Anda dapat menghitung histogram dari kedua gambar dan kemudian menghitung Koefisien Bhattacharyya , ini adalah algoritma yang sangat cepat dan saya telah menggunakannya untuk mendeteksi perubahan bidikan dalam video kriket (dalam C menggunakan openCV)
sumber
Lihatlah bagaimana Haar Wavelets diimplementasikan oleh isk-daemon . Anda dapat menggunakannya dengan kode imgdb C ++ untuk menghitung perbedaan antara gambar secara langsung:
sumber
Saya memiliki masalah yang sama dan menulis modul python sederhana yang membandingkan dua gambar berukuran sama menggunakan ImageChops bantal untuk membuat gambar diff hitam / putih dan merangkum nilai histogram.
Anda bisa mendapatkan skor ini secara langsung, atau nilai persentase dibandingkan dengan perbedaan hitam penuh vs putih.
Ini juga berisi fungsi is_equal sederhana, dengan kemungkinan untuk memasok ambang fuzzy di bawah (dan termasuk) gambar melewati sama.
Pendekatannya tidak terlalu rumit, tetapi mungkin berguna bagi orang lain di luar sana yang berjuang dengan masalah yang sama.
https://pypi.python.org/pypi/imgcompare/
sumber
Pendekatan yang agak lebih berprinsip adalah menggunakan deskriptor global untuk membandingkan gambar, seperti GIST atau CENTRIST. Fungsi hash, seperti dijelaskan di sini , juga menyediakan solusi serupa.
sumber
keluaran:
Salah
Benar
image2 \ 5.jpg image1 \ 815.jpg
image2 \ 6.jpg image1 \ 819.jpg
image2 \ 7.jpg image1 \ 900.jpg
image2 \ 8.jpg image1 \ 998.jpg
image2 \ 9.jpg image1 \ 1012 .jpg
contoh gambar:
815.jpg
5.jpg
sumber
Saya pikir Anda bisa menghitung jarak euclidean (yaitu sqrt (jumlah kuadrat perbedaan, piksel demi piksel)) antara luminansi dua gambar, dan menganggapnya sama jika ini berada di bawah ambang empiris. Dan Anda lebih baik melakukannya dengan membungkus fungsi C.
sumber
Ada banyak metrik di luar sana untuk mengevaluasi apakah dua gambar terlihat seperti / seberapa mirip.
Saya tidak akan membahas kode apa pun di sini, karena saya pikir itu harus menjadi masalah ilmiah, selain masalah teknis.
Secara umum, pertanyaan tersebut terkait dengan persepsi manusia tentang gambar, sehingga masing-masing algoritma memiliki dukungan pada ciri-ciri sistem visual manusia.
Pendekatan klasik adalah:
Prediktor perbedaan yang terlihat: algoritme untuk penilaian kesetiaan gambar ( https://www.spiedigitallibrary.org/conference-proceedings-of-spie/1666/0000/Visible-differences-predictor--an-algorithm-for-the- penilaian-of / 10.1117 / 12.135952.short? SSO = 1 )
Penilaian Kualitas Gambar: Dari Visibilitas Kesalahan hingga Kesamaan Struktural ( http://www.cns.nyu.edu/pub/lcv/wang03-reprint.pdf )
FSIM: Indeks Kesamaan Fitur untuk Penilaian Kualitas Gambar ( https://www4.comp.polyu.edu.hk/~cslzhang/IQA/TIP_IQA_FSIM.pdf )
Di antara mereka, SSIM (Penilaian Kualitas Gambar: Dari Visibilitas Kesalahan ke Kesamaan Struktural) adalah yang termudah untuk dihitung dan biaya overhead juga kecil, seperti yang dilaporkan dalam makalah lain "Penilaian Kualitas Gambar Berdasarkan Kemiripan Gradien" ( https: //www.semanticscholar .org / kertas / Gambar-Penilaian-Kualitas-Berbasis-Gradien-Liu-Lin / 2b819bef80c02d5d4cb56f27b202535e119df988 ).
Ada banyak lagi pendekatan lain. Lihatlah Google Cendekia dan cari sesuatu seperti "perbedaan visual", "penilaian kualitas gambar", dll, jika Anda tertarik / benar-benar peduli pada seni.
sumber
Ada solusi sederhana dan cepat menggunakan numpy dengan menghitung mean squared error:
sumber