Dalam aplikasi kami ada fitur, seperti
anak dari pacar ibu saya vivino - definisi anggur dari sebuah foto. Di bawah tenda - penggunaan layanan pihak ketiga, Tineye - untuk menentukan label yang paling cocok, Google Vision - untuk membaca teks di atasnya. Yang terakhir diperlukan untuk mengklarifikasi produk yang benar, karena pencarian gambar tidak memperhitungkan pentingnya beberapa daerah, sebagai aturan - ini adalah informasi tekstual - tahun dan jenis anggur.
Namun, keakuratan kedua layanan tersebut berkurang karena fakta bahwa label terdistorsi oleh permukaan silinder.
Ini terutama terlihat dengan Google Vision - teks apa pun di luar bagian tengah label praktis tidak dapat dibaca, meskipun seseorang mudah mengenalinya. Dalam artikel ini, saya akan menjelaskan cara membalikkan distorsi dan meningkatkan akurasi pengakuan produk.

Pertama-tama, pertimbangkan distorsi.

Label persegi panjang, ketika direkatkan ke silinder, memiliki bentuk karakteristik barel (b pada diagram di atas). Kurva ABC dalam hal ini, dalam perkiraan yang agak baik, adalah elips, karena kita melihat sebuah lingkaran (bagian silinder) pada suatu sudut. Banyak garis horizontal label juga berubah menjadi banyak elips di foto.
Yang paling menarik adalah untuk memperluas label, cukup tentukan 6 marker (ABCDEF):

Dan dengan menggunakannya, bangun kisi-kisi permukaan yang lengkap:

Memiliki grid permukaan, kami dapat memperluas setiap ubin secara terpisah, dan mendapatkan permukaan asli:
Kode perpustakaan tersedia di github . Kemudahan metode ini adalah bahwa parameter input untuk transformasi invers adalah karakteristik label yang ditentukan secara visual (sudut dan atas, titik bawah), yang memungkinkan Anda untuk mengotomatisasi sepenuhnya proses.
Bagian selanjutnya adalah tentang mendefinisikan marker. Kode kerja hanya tersedia sebagian di
cabang di github , seperti solusi yang benar-benar berfungsi ditutupi oleh peretasan dan perdukunan, jadi hati nurani tidak mengizinkan timah semacam itu diunggah ke github.
Tahap satu - mengonversi gambar menjadi hitam dan putih.
Maka Anda perlu mendapatkan kontur botol dengan label. Untuk melakukan ini, kami menggunakan
transformasi sobel . Singkatnya, filter ini pertama-tama mengaburkan gambar, dan kemudian menguranginya dari aslinya. Akibatnya, bahkan area tetap gelap, dan tepi (perubahan) tetap terang.

Hal berikutnya yang harus dilakukan adalah mengidentifikasi dua garis vertikal yang paling mencolok, yang, jika Anda beruntung, adalah ujung botol. Dalam hal ini, ini benar, tetapi jika Anda memotret botol di sebelah botol lain, maka ini tidak lagi menjadi masalah.
Untuk menentukan garis-garis ini, gunakan
transformasi Hough . Inti dari teknik ini adalah kami mengambil banyak garis yang melintasi seluruh layar dan mempertimbangkan nilai rata-rata piksel (misalnya, kami mengambil garis yang bergerak dari atas gambar ke bawah). Kami mentransfer nilai-nilai ini ke bidang koordinat baru dan mendapatkan sesuatu seperti peta panas. Pada peta panas ini, kami mencari dua ekstrema - mereka adalah garis samping.
Diagram di bawah ini menunjukkan bagaimana garis kiri menuju ke titik pada bidang koordinat baru:

Dengan elips sedikit lebih rumit, tetapi mengetahui bahwa transformasi Hough dapat diterapkan pada kurva yang didefinisikan secara matematis, kita akan menggunakan metode ini lagi, tetapi kali ini kita akan mencari banyak kurva eliptik.
Tetapi pertama-tama Anda perlu membawa masalah ke bentuk dua dimensi. Mengetahui bahwa botol itu simetris terpusat, kami mengambil sumbu pusat untuk koordinat Y, dan satu sisi untuk X. Untuk nilai-nilai pada bidang koordinat baru, kami mengambil banyak elips yang dibangun antara sumbu pusat dan samping. Ini dimungkinkan karena fakta bahwa titik arbitrer di samping dan sumbu pusat hanya memiliki satu metode koneksi. Mungkin ini tidak terlalu jelas pada pandangan pertama, tetapi jauh lebih mudah untuk dipahami jika kita beralih ke rumus parametrik elips:
x = a * cos (t)
y = b * sin (t)

Dengan cara yang persis sama, kami menemukan dua ekstrem yang dicari yang mendefinisikan dua elips label (kurva AB, FE). Sekarang kita memiliki semua parameter label yang diperlukan (kurva sisi, serta elips atas dan bawah), kita dapat menerapkan algoritma dari bagian pertama artikel dan melakukan transformasi terbalik.
Apa yang bisa diperbaiki. Pertama, algoritme tidak memperhitungkan distorsi perspektif elips itu sendiri, sebagai akibatnya, fragmen sisi label ditarik sedikit lebih dari yang seharusnya. Untuk melakukan koreksi, Anda perlu mengetahui sudut pandang sebenarnya dari kamera, atau setidaknya menggunakan yang paling khas untuk telepon (Anda dapat memilih secara empiris).
Kedua, transformasi Hough bekerja agak tidak stabil dalam kondisi sulit - misalnya, ketika botol yang berdekatan jatuh ke dalam bingkai dan ujung-ujung botol yang menarik mungkin tidak terdeteksi dengan benar.
Ketiga, jika label tidak berbentuk persegi panjang (misalnya, elips), maka marka akan terdeteksi secara tidak benar, dan transformasi hanya akan mendistorsi gambar lebih kuat.
Dalam praktiknya, jauh lebih menarik menggunakan jaringan saraf untuk mengidentifikasi penanda, karena itu dapat dilatih menggunakan contoh-contoh kompleks sehingga, setidaknya, algoritma tidak melakukan transformasi jika marker tidak dapat ditentukan. Tapi sejauh ini saya belum mencoba menggunakan neuron untuk tugas ini, jadi mungkin ini akan menjadi topik artikel terpisah :)