Saya ingin mengambil gambar label pada toples makanan, dan dapat mengubahnya sehingga labelnya rata, dengan sisi kanan dan kiri diubah ukurannya menjadi rata dengan bagian tengah gambar.
Idealnya, saya ingin menggunakan kontras antara label dan latar belakang untuk menemukan tepi dan menerapkan koreksi. Kalau tidak, saya bisa meminta pengguna untuk mengidentifikasi sudut dan sisi gambar.
Saya sedang mencari teknik dan algoritma umum untuk mengambil gambar yang miring secara sphere (dalam kasus saya berbentuk silindris) dan dapat meratakan gambar. Saat ini gambar label yang dililitkan di sekitar toples atau botol, akan memiliki fitur dan teks yang menyusut ketika surut ke kanan atau kiri gambar. Juga garis-garis yang menunjukkan tepi label, hanya akan sejajar di tengah gambar, dan akan condong ke arah satu sama lain di sisi kanan dan kiri label.
Setelah memanipulasi gambar, saya ingin dibiarkan dengan kotak hampir sempurna di mana teks dan fitur berukuran seragam, seolah-olah saya mengambil gambar label ketika itu tidak ada di botol atau botol.
Saya juga ingin jika teknik ini dapat secara otomatis mendeteksi tepi label, untuk menerapkan koreksi yang sesuai. Kalau tidak, saya harus meminta pengguna saya untuk menunjukkan batas label.
Saya sudah mencari di Google dan menemukan artikel seperti ini: meratakan dokumen melengkung , tapi saya mencari sesuatu yang sedikit lebih sederhana, karena kebutuhan saya adalah label dengan kurva sederhana.
sumber
Jawaban:
Sebuah pertanyaan serupa diminta di Mathematica.Stackexchange . Jawaban saya di sana berkembang dan cukup panjang pada akhirnya, jadi saya akan meringkas algoritme di sini.
Abstrak
Ide dasarnya adalah:
Algoritme hanya berfungsi untuk gambar yang:
Namun, algoritma ini bersifat modular. Setidaknya pada prinsipnya, Anda dapat menulis deteksi label Anda sendiri yang tidak memerlukan latar belakang gelap, atau Anda dapat menulis fungsi pengukuran kualitas Anda sendiri yang dapat mengatasi label elips atau oktagonal.
Hasil
Gambar-gambar ini diproses sepenuhnya secara otomatis, yaitu algoritma mengambil gambar sumber, bekerja selama beberapa detik, kemudian menunjukkan pemetaan (kiri) dan gambar tidak terdistorsi (kanan):
Gambar berikutnya diproses dengan versi algoritma yang dimodifikasi, jika pengguna memilih batas kiri dan kanan tabung (bukan label), karena kelengkungan label tidak dapat diperkirakan dari gambar dalam bidikan frontal (yaitu algoritma sepenuhnya otomatis akan mengembalikan gambar yang sedikit terdistorsi):
Pelaksanaan:
1. Temukan label
Labelnya cerah di depan latar belakang yang gelap, jadi saya bisa menemukannya dengan mudah menggunakan binarisasi:
Saya cukup memilih komponen terhubung terbesar dan menganggap itu label:
2. Temukan batas label
Langkah selanjutnya: temukan batas atas / bawah / kiri / kanan menggunakan masker konvolusi derivatif sederhana:
Ini adalah fungsi pembantu kecil yang menemukan semua piksel putih di salah satu dari empat gambar ini dan mengonversi indeks menjadi koordinat (
Position
mengembalikan indeks, dan indeks berbasis 1 {y, x} -tupel, di mana y = 1 berada di atas Tetapi semua fungsi pemrosesan gambar mengharapkan koordinat, yang merupakan 0-{{x, y} -tuples, di mana y = 0 adalah bagian bawah gambar):3. Temukan pemetaan dari koordinat gambar ke silinder
Sekarang saya memiliki empat daftar koordinat terpisah dari batas atas, bawah, kiri, kanan label. Saya mendefinisikan pemetaan dari koordinat gambar ke koordinat silinder:
Ini adalah pemetaan silindris, yang memetakan koordinat X / Y pada gambar sumber ke koordinat silindris. Pemetaan memiliki 10 derajat kebebasan untuk ketinggian / radius / pusat / perspektif / kemiringan. Saya menggunakan seri Taylor untuk memperkirakan arc arc, karena saya tidak bisa mendapatkan optimasi bekerja dengan ArcSin secara langsung. Itu
Clip
panggilan adalah upaya ad-hoc saya untuk mencegah angka-angka kompleks selama optimasi. Ada trade-off di sini: Di satu sisi, fungsinya harus sedekat mungkin dengan pemetaan silinder yang tepat, untuk memberikan distorsi serendah mungkin. Di sisi lain, jika terlalu rumit, akan semakin sulit untuk menemukan nilai optimal untuk derajat kebebasan secara otomatis. (Yang menyenangkan tentang melakukan pemrosesan gambar dengan Mathematica adalah bahwa Anda dapat bermain-main dengan model matematika seperti ini dengan sangat mudah, memperkenalkan istilah tambahan untuk distorsi yang berbeda dan menggunakan fungsi optimisasi yang sama untuk mendapatkan hasil akhir. Saya tidak pernah bisa melakukan apa pun. seperti itu menggunakan OpenCV atau Matlab. Tapi saya tidak pernah mencoba kotak alat simbolis untuk Matlab, mungkin itu membuatnya lebih berguna.)Selanjutnya saya mendefinisikan "fungsi kesalahan" yang mengukur kualitas gambar -> pemetaan koordinat silinder. Ini hanya jumlah kesalahan kuadrat untuk piksel perbatasan:
Fungsi kesalahan ini mengukur "kualitas" pemetaan: Paling rendah jika titik-titik di perbatasan kiri dipetakan ke (0 / [apa saja]), piksel pada batas atas dipetakan ke ([apa saja] / 0) dan seterusnya .
Sekarang saya dapat memberitahu Mathematica untuk menemukan koefisien yang meminimalkan fungsi kesalahan ini. Saya dapat membuat "tebakan-tebakan" tentang beberapa koefisien (mis. Jari-jari dan pusat tabung pada gambar). Saya menggunakan ini sebagai titik awal optimasi:
FindMinimum
menemukan nilai untuk 10 derajat kebebasan fungsi pemetaan saya yang meminimalkan fungsi kesalahan. Gabungkan pemetaan generik dan solusi ini dan saya mendapatkan pemetaan dari koordinat gambar X / Y, yang sesuai dengan area label. Saya dapat memvisualisasikan pemetaan ini menggunakanContourPlot
fungsi Mathematica :4. Ubah gambar
Akhirnya, saya menggunakan
ImageForwardTransform
fungsi Mathematica untuk mengubah gambar sesuai dengan pemetaan ini:Itu memberikan hasil seperti yang ditunjukkan di atas.
Versi yang dibantu secara manual
Algoritma di atas adalah otomatis penuh. Tidak diperlukan penyesuaian. Ini bekerja dengan baik selama gambar diambil dari atas atau bawah. Tetapi jika itu adalah pukulan frontal, jari-jari jar tidak dapat diperkirakan dari bentuk label. Dalam kasus ini, saya mendapatkan hasil yang lebih baik jika saya membiarkan pengguna memasukkan batas kiri / kanan jar secara manual, dan mengatur derajat kebebasan yang sesuai dalam pemetaan secara eksplisit.
Kode ini memungkinkan pengguna memilih batas kiri / kanan:
Ini adalah kode optimalisasi alternatif, di mana pusat & radius diberikan secara eksplisit.
sumber