Saya memiliki proyek latihan ini yang memungkinkan pengguna untuk menggambar di layar saat mereka menyentuh dengan jari-jari mereka. App yang sangat sederhana saya lakukan sebagai latihan jalan kembali. Sepupu kecil saya mengambil kebebasan menggambar dengan jarinya dengan iPad saya di Aplikasi ini (Gambar anak-anak: lingkaran, garis, dll, apa pun yang terlintas dalam pikirannya). Kemudian dia mulai menggambar lingkaran dan kemudian dia meminta saya untuk menjadikannya "lingkaran yang baik" (dari pemahaman saya: membuat lingkaran yang digambar menjadi bulat sempurna, seperti yang kita ketahui tidak masalah seberapa stabil kita mencoba menggambar sesuatu dengan jari kita di layar, sebuah lingkaran tidak pernah benar-benar bulat seperti seharusnya lingkaran).
Jadi pertanyaan saya di sini adalah, apakah ada cara dalam kode di mana kita pertama kali dapat mendeteksi garis yang ditarik oleh pengguna yang membentuk lingkaran dan menghasilkan ukuran lingkaran yang kira-kira sama dengan membuatnya bulat sempurna di layar. Membuat garis yang tidak terlalu lurus adalah sesuatu yang saya tahu caranya, tetapi untuk lingkaran, saya tidak tahu bagaimana cara melakukannya dengan Quartz atau metode lain.
Alasan saya adalah bahwa, titik awal dan akhir dari garis harus menyentuh atau saling silang setelah pengguna mengangkat jarinya untuk membenarkan fakta bahwa ia mencoba untuk benar-benar menggambar lingkaran.
Jawaban:
Terkadang sangat berguna untuk meluangkan waktu menciptakan kembali roda. Seperti yang mungkin sudah Anda perhatikan ada banyak kerangka kerja, tetapi tidak sulit untuk mengimplementasikan solusi sederhana, namun bermanfaat tanpa memperkenalkan semua kompleksitas itu. (Tolong jangan salah paham, untuk tujuan serius apa pun lebih baik menggunakan kerangka kerja yang matang dan terbukti stabil).
Saya akan mempresentasikan hasil saya pertama dan kemudian menjelaskan ide sederhana dan langsung di belakang mereka.
Anda akan melihat dalam implementasi saya tidak perlu menganalisis setiap titik dan melakukan perhitungan yang kompleks. Idenya adalah untuk menemukan beberapa informasi meta yang berharga. Saya akan menggunakan tangen sebagai contoh:
Mari kita identifikasi pola yang sederhana dan langsung, khas untuk bentuk yang dipilih:
Jadi tidak sulit untuk menerapkan mekanisme deteksi lingkaran berdasarkan ide itu. Lihat demo yang berfungsi di bawah ini (Maaf, saya menggunakan Java sebagai cara tercepat untuk memberikan contoh cepat dan agak kotor ini):
Seharusnya tidak menjadi masalah untuk menerapkan perilaku serupa di iOS, karena Anda hanya perlu beberapa acara dan koordinat. Sesuatu seperti berikut ini (lihat contoh ):
Ada beberapa perangkat tambahan yang mungkin.
Mulai kapan saja
Persyaratan saat ini adalah mulai menggambar lingkaran dari titik tengah atas karena penyederhanaan berikut:
Mohon perhatikan nilai default dari
index
yang digunakan. Pencarian sederhana melalui "bagian" bentuk yang tersedia akan menghapus batasan itu. Harap dicatat Anda harus menggunakan buffer bundar untuk mendeteksi bentuk penuh:Searah jarum jam dan berlawanan arah jarum jam
Untuk mendukung kedua mode ini, Anda harus menggunakan buffer bundar dari perangkat tambahan sebelumnya dan mencari di kedua arah:
Gambarkan elips
Anda sudah memiliki semua yang Anda butuhkan di dalam
bounds
array.Cukup gunakan data itu:
Gerakan lain (opsional)
Terakhir, Anda hanya perlu menangani situasi dengan benar
dx
(ataudy
) sama dengan nol untuk mendukung gerakan lain:Memperbarui
PoC kecil ini mendapat perhatian yang cukup tinggi, jadi saya memperbarui sedikit kode untuk membuatnya bekerja dengan lancar dan memberikan beberapa petunjuk menggambar, menyorot poin pendukung, dll:
Ini kodenya:
sumber
Teknik Visi Komputer klasik untuk mendeteksi bentuk adalah Hough Transform. Salah satu hal yang menyenangkan tentang Hough Transform adalah sangat toleran terhadap data parsial, data tidak sempurna, dan kebisingan. Menggunakan Hough untuk lingkaran: http://en.wikipedia.org/wiki/Hough_transform#Circle_detection_process
Mengingat bahwa lingkaran Anda digambar tangan, saya pikir transformasi Hough mungkin cocok untuk Anda.
Inilah penjelasan "disederhanakan", saya minta maaf karena itu tidak benar-benar sesederhana itu. Sebagian besar dari proyek sekolah yang saya lakukan bertahun-tahun yang lalu.
The Hough Transform adalah skema pemungutan suara. Array bilangan bulat dua dimensi dialokasikan dan semua elemen diatur ke nol. Setiap elemen terkait dengan satu piksel dalam gambar yang dianalisis. Array ini disebut sebagai array akumulator karena setiap elemen akan mengumpulkan informasi, suara, yang menunjukkan kemungkinan bahwa suatu pixel mungkin berasal dari asal-usul lingkaran atau busur.
Detektor tepi operator gradien diterapkan pada gambar dan piksel tepi, atau edgels, direkam. Edgel adalah piksel yang memiliki intensitas atau warna berbeda sehubungan dengan tetangganya. Tingkat perbedaan disebut gradient magnitude. Untuk setiap edgel dengan besaran yang cukup, skema pemungutan suara diterapkan yang akan menambah elemen array akumulator. Elemen-elemen yang ditambahkan (dipilih) sesuai dengan kemungkinan asal usul lingkaran yang melewati edgel yang sedang dipertimbangkan. Hasil yang diinginkan adalah bahwa jika ada busur maka asal yang benar akan menerima lebih banyak suara daripada asal yang salah.
Perhatikan bahwa elemen array akumulator yang dikunjungi untuk pemungutan suara membentuk lingkaran di sekitar edgel yang sedang dipertimbangkan. Menghitung koordinat x, y untuk memilih sama dengan menghitung koordinat x, y dari lingkaran yang Anda gambar.
Pada gambar yang digambar dengan tangan Anda, Anda mungkin dapat menggunakan piksel yang diset (berwarna) secara langsung daripada menghitung edgels.
Sekarang dengan piksel yang terletak tidak sempurna Anda tidak perlu mendapatkan elemen array akumulator tunggal dengan jumlah suara terbanyak. Anda bisa mendapatkan koleksi elemen array tetangga dengan sekelompok suara, sebuah cluster. Pusat gravitasi dari kluster ini dapat menawarkan perkiraan yang baik untuk asal usulnya.
Perhatikan bahwa Anda mungkin harus menjalankan Hough Transform untuk nilai jari-jari R. yang berbeda yang menghasilkan kumpulan suara yang lebih padat adalah kecocokan "lebih baik".
Ada berbagai teknik yang digunakan untuk mengurangi suara untuk asal-usul palsu. Sebagai contoh satu keuntungan menggunakan edgels adalah bahwa mereka tidak hanya memiliki magnitudo tetapi mereka juga memiliki arah. Saat memberikan suara, kita hanya perlu memilih kemungkinan asal ke arah yang sesuai. Lokasi yang menerima suara akan membentuk busur daripada lingkaran lengkap.
Ini sebuah contoh. Kita mulai dengan lingkaran jari-jari satu dan array akumulator yang diinisialisasi. Karena setiap piksel dianggap sebagai asal potensial dipilih untuk. Asal sebenarnya menerima suara terbanyak yang dalam hal ini adalah empat.
sumber
Ini cara lain. Menggunakan UIView touchesMulai, touchesMoved, touchEnded dan menambahkan poin ke array. Anda membagi array menjadi dua, dan menguji apakah setiap titik dalam satu array kira-kira memiliki diameter yang sama dari pasangannya di array lain seperti semua pasangan lainnya.
Kedengarannya oke? :)
sumber
Saya bukan ahli pengenalan bentuk, tapi inilah cara saya mendekati masalah.
Pertama, saat menampilkan jalur pengguna sebagai bebas tangan, diam-diam mengumpulkan daftar titik (x, y) sampel bersamaan dengan waktu. Anda bisa mendapatkan kedua fakta dari acara seret, membungkusnya menjadi objek model sederhana, dan menumpuknya dalam array yang bisa berubah.
Anda mungkin ingin mengambil sampel dengan cukup sering — katakanlah, setiap 0,1 detik. Kemungkinan lain adalah mulai benar-benar sering, mungkin setiap 0,05 detik, dan perhatikan berapa lama pengguna menyeret; jika mereka menyeret lebih lama dari jumlah waktu tertentu, maka turunkan frekuensi sampel (dan jatuhkan sampel apa pun yang terlewatkan) menjadi sekitar 0,2 detik.
(Dan jangan mengambil nomor saya untuk Injil, karena saya baru saja mengeluarkannya dari topi saya. Bereksperimen dan temukan nilai yang lebih baik.)
Kedua, menganalisis sampel.
Anda ingin mendapatkan dua fakta. Pertama, pusat bentuk, yang (IIRC) seharusnya hanya rata-rata dari semua titik. Kedua, radius rata-rata setiap sampel dari pusat itu.
Jika, seperti yang ditebak @ user1118321, Anda ingin mendukung poligon, maka sisa analisisnya terdiri dari membuat keputusan itu: apakah pengguna ingin menggambar lingkaran atau poligon. Anda dapat melihat sampel sebagai poligon untuk memulai dengan menentukan itu.
Ada beberapa kriteria yang dapat Anda gunakan:
Langkah ketiga dan terakhir adalah membuat bentuk, berpusat pada titik pusat yang telah ditentukan sebelumnya, dengan jari-jari yang ditentukan sebelumnya.
Tidak ada jaminan bahwa apa pun yang saya katakan di atas akan berfungsi atau menjadi efisien, tetapi saya harap itu setidaknya membuat Anda berada di jalur yang benar — dan tolong, jika ada orang yang tahu lebih banyak tentang pengenalan bentuk daripada saya (yang merupakan bilah yang sangat rendah) melihat ini, jangan ragu untuk mengirim komentar atau jawaban Anda sendiri.
sumber
Saya sudah cukup beruntung dengan pengenal $ 1 yang terlatih dengan baik ( http://depts.washington.edu/aimgroup/proj/dollar/ ). Saya menggunakannya untuk lingkaran, garis, segitiga dan kotak.
Sudah lama sekali, sebelum UIGestureRecognizer, tapi saya pikir itu harus mudah untuk membuat subclass UIGestureRecognizer yang tepat.
sumber
Setelah Anda menentukan pengguna selesai menggambar bentuk di mana mereka mulai, Anda dapat mengambil sampel dari koordinat yang mereka gambar dan coba paskan mereka ke lingkaran.
Ada solusi MATLAB untuk masalah ini di sini: http://www.mathworks.com.au/matlabcentral/fileexchange/15060-fitcircle-m
Yang didasarkan pada makalah Least-Squares Fitting of Circles and Ellipses oleh Walter Gander, Gene H. Golub dan Rolf Strebel: http://www.emis.de/journals/BBMS/Bulletin/sup962/gander.pdf
Dr Ian Coope dari University of Canterbury, NZ menerbitkan sebuah makalah dengan abstrak:
http://link.springer.com/article/10.1007%2FBF00939613
File MATLAB dapat menghitung masalah TLS nonlinear dan linear LLS.
sumber
Berikut cara yang cukup sederhana menggunakan:
dengan asumsi kisi matriks ini:
Tempatkan beberapa UIViews di lokasi "X" dan uji mereka untuk menjadi hit (secara berurutan). Jika mereka semua terkena secara berurutan, saya pikir mungkin adil untuk membiarkan pengguna mengatakan "Bagus, Anda menggambar lingkaran"
Kedengarannya oke? (dan sederhana)
sumber