Dzaky Zakiyal Fawwaz
Seberapa Jauh Galat 2 Piksel Bisa Mengubah Estimasi Denah?

Seberapa Jauh Galat 2 Piksel Bisa Mengubah Estimasi Denah?

Diterbitkan pada
10 mnt baca
computer-visionconstructiongeometryevaluation

Hasil Ukurlah Produknya

Quantity takeoff mengubah gambar menjadi angka: berapa meter persegi lantai, berapa meter plint, berapa ruangan yang perlu dicat. Tool yang mengotomatiskannya mencari ruangan di denah lalu mengukurnya, dan akurasinya biasanya dilaporkan sebagai satu angka: seberapa baik ruangannya ditemukan.

Angka itu bisa menyembunyikan hal yang justru penting bagi takeoff. Ruangan yang ditemukan 2 piksel lebih kecil di setiap dinding tetap dihitung "ketemu", padahal luasnya meleset beberapa persen. Galat yang menyatukan dua ruangan bisa membuat luas total tetap sempurna, sementara semua angka per ruangan salah. Saya membuat quantity-lab untuk mengukur efek-efek ini secara terpisah, bukan melipatnya jadi satu skor.

Kode: github.com/dzakybd/quantity-lab (MIT) · Demo: huggingface.co/spaces/dzakybd/quantity-lab

TL;DR

  • Apa itu: CLI Python yang mengukur luas, keliling dan jumlah ruangan pada denah dalam tiga mode terpisah. Oracle mengukur ruangan beranotasi; galat terkendali merusak ruangan itu dengan cara yang diketahui; predicted menjalankan pencari ruangan OpenCV klasik. Semuanya dalam piksel gambar.
  • Data: tiga denah uji dari set test CubiCasa5K (5, 9 dan 28 ruangan). Pencari ruangannya hanya di-tuning pada tiga denah train.
  • Batas ruangan: galat batas 2 piksel mengubah luas ruangan 3,3 sampai 4,1%; 5 piksel mengubahnya 8,3 sampai 10,1%. Menggeser seluruh denah 5 piksel mengubah luas paling banyak 0,2%.
  • Jumlah ruangan: satu sekat hilang atau satu garis palsu membuat luas total tetap dalam 0,6%, tetapi jumlah ruangannya salah.
  • Pencari ruangan: cocok dengan 0 sampai 5 ruangan per denah (F1 jumlah 0,00 sampai 0,11). Di satu denah luas totalnya hanya meleset 1,3%, padahal tidak ada satu ruangan pun yang cocok.
Gambarnya adalah denah sintetis; angkanya dari tiga denah CubiCasa5K uji, dalam piksel.

Tiga Mode, Dijaga Terpisah

Asal galat menentukan cara memperbaikinya, jadi quantity-lab tidak pernah mencampurnya:

  1. Oracle. Mengukur poligon ruangan beranotasi secara langsung. Mode ini juga melewatkannya lewat perjalanan bolak-balik raster (digambar ke mask piksel, lalu dilacak kembali) untuk menunjukkan berapa galat dari rasterisasi saja. Kode pengukurnya dibuktikan dulu sebelum menyalahkan yang lain.

  2. Galat terkendali. Ruangan oracle dirusak dengan satu cara yang diketahui setiap kali:

    • batas ditarik ke dalam atau didorong ke luar 2 atau 5 piksel;
    • seluruh denah digeser;
    • skala diubah ±2%;
    • satu sekat dihapus sehingga dua ruangan menyatu;
    • satu garis palsu ditambahkan sehingga satu ruangan terbelah.

    Lalu diukur ulang.

  3. Predicted. Pencari ruangan sungguhan dijalankan pada gambar, dan ruangannya dicocokkan dengan ruangan oracle.

Tiga versi denah sintetis yang sama. Kiri: enam ruangan referensi, masing-masing diisi warna sendiri. Tengah: ruangan yang sama dengan setiap batas 5 piksel terlalu kecil, menyisakan celah tipis di dinding. Kanan: baseline OpenCV, yang menyatukan dapur, ruang tamu, entri dan satu kamar tidur menjadi satu wilayah serta menambahkan potongan kecil untuk furnitur.

Denah sintetis yang sama di tiap mode. Isian berwarna adalah yang diukur, garis gelap adalah referensinya.

Datanya, dan Apa yang Tidak Saya Publikasikan

CubiCasa5K adalah kumpulan terbuka berisi 5.000 denah. Setiap denah punya file SVG yang menandai setiap ruangan, dinding, pintu dan jendela. Saya mengambil tiga denah dari split test-nya, dipilih sebagai sederhana, sedang dan padat:

  • 5 ruangan;
  • 9 ruangan, dengan dapur dan ruang tamu yang berbagi bukaan tanpa dinding;
  • 28 ruangan di dua lantai.

Dua kandidat saya lewati karena sebagian besar gambarnya tidak beranotasi, sehingga ruangan sungguhan akan terhitung sebagai kesalahan.

Tiga catatan soal metode:

  • Satu jalur PDF. Setiap gambar denah dibungkus ke PDF dan dibaca kembali lewat jalur PDF yang sama dengan tool sungguhan. Isinya tetap gambar di dalam PDF, bukan gambar vektor.
  • Hanya piksel. Semuanya diukur dalam piksel. Denahnya tidak punya skala terverifikasi, jadi saya melaporkan px dan px², tidak pernah meter persegi.
  • Tidak ada gambar yang dipublikasikan. Dataset-nya berlisensi non-komersial, jadi tidak ada gambar CubiCasa5K di tulisan ini. Semua gambar adalah denah sintetis yang saya buat dengan format yang sama, dan hasil CubiCasa5K hanya ditampilkan sebagai angka.

Apakah Kode Pengukurnya Benar?

Sebelum merusak apa pun, oracle memeriksa penggarisnya. Perjalanan bolak-balik raster mendapatkan kembali setiap ruangan di ketiga denah:

  • galat median luas ruangan 0,12 sampai 0,36%;
  • luas total dalam 0,06%.

Unit test mengunci dasar-dasarnya:

  • persegi 10 × 10 punya luas 100 dan keliling 40;
  • menggandakan skala mengalikan luas dengan 4;
  • memindahkan atau memutar ruangan tidak mengubah apa pun;
  • poligon yang memotong dirinya sendiri diperbaiki dan ditandai.

Galat Batas yang Kecil

Galat paling umum di langkah pencarian ruangan adalah batas yang sedikit meleset: beberapa piksel di dalam atau di luar muka dinding. Ini efeknya pada luas ruangan di tiga denah uji.

Grafik garis rata-rata galat luas ruangan terhadap galat batas dalam piksel untuk tiga denah. Ketiga garis nyaris berimpit: sekitar minus 3,3 sampai minus 4,1 persen pada minus 2 piksel, minus 8,3 sampai minus 10,1 persen pada minus 5 piksel, plus 3,6 sampai 3,7 persen pada plus 2 piksel dan plus 8,8 sampai 9,6 persen pada plus 5 piksel.

GalatLuas ruangan (sederhana / sedang / padat)KelilingJumlah ruangan
Batas 2 px terlalu kecil−3,3% / −4,1% / −3,9%1,3 sampai 1,8%tidak berubah
Batas 5 px terlalu kecil−8,3% / −10,1% / −9,7%3,5 sampai 4,6%tidak berubah
Batas 2 px terlalu besar+3,6% / +3,7% / +3,7%0,6 sampai 1,2%tidak berubah
Batas 5 px terlalu besar+8,8% / +9,6% / +8,9%2,1 sampai 3,4%tidak berubah
Seluruh denah digeser 5 px+0,2% / −0,1% / 0,0%≤ 0,13%tidak berubah
Skala meleset 2%sekitar ±4%sekitar 2%tidak berubah, kecuali di denah padat (F1 0,82)

Rata-rata galat bertanda atas ruangan di tiap denah; kolom keliling adalah median galat absolut.

Tiga hal yang menonjol:

  • Luas bergerak sekitar dua kali lipat dibanding keliling. Menarik batas persegi panjang ke dalam sejauh d piksel menghapus sekitar keliling × d dari luasnya, tetapi hanya 8d dari kelilingnya (2d di setiap sudut). Untuk ruangan yang kurang lebih persegi, hasilnya sekitar dua kali perubahan relatif.
  • Galat tumbuh seiring jumlah pikselnya dan paling terasa di ruangan kecil. Pita 2 piksel di sekeliling lemari adalah porsi yang lebih besar dari lemari itu dibanding dari ruang tamu.
  • Denah yang digeser tetap mempertahankan luasnya. Menggeser semuanya 5 piksel nyaris tidak mengubah luas, jadi galat registrasi merusak skor overlap tanpa merugikan takeoff. Skala yang salah justru sebaliknya: 2% skala berarti sekitar 4% luas, di semua ruangan sekaligus.

Total Benar, Ruangan Salah

Jenis galat kedua mengubah topologi: sebuah sekat hilang, atau garis palsu membelah ruangan.

Tiga versi denah sintetis. Kiri: ruangan referensi. Tengah: satu sekat hilang, sehingga dapur dan ruang tamu menjadi satu wilayah. Kanan: satu garis palsu, yang membelah ruang tamu menjadi dua wilayah.

Pada denah uji:

  • Satu sekat hilang membuat luas total tetap dalam 0,6% dan menurunkan F1 jumlah ruangan ke 0,89–0,98.
  • Satu garis palsu membuat luas total tetap dalam 0,3% dan menurunkan F1 jumlah ke 0,73–0,95.

Takeoff yang dihargai berdasarkan luas lantai total tidak akan menyadari keduanya. Takeoff yang menghitung ruangan, pintu per ruangan, atau lantai per ruangan akan salah. Inilah poin yang paling ingin saya sampaikan: luas total yang benar bukan bukti bahwa ruangannya benar.

Pencari Ruangan Sungguhan

Untuk mode predicted, saya memakai baseline computer vision klasik, tanpa model terlatih:

  • goresan gelap yang tebalnya minimal beberapa piksel dianggap dinding;
  • celah di antara potongan dinding yang segaris ditutup sebagai pintu;
  • setiap wilayah ruang kosong yang tertutup di antara dinding dianggap ruangan.

Lima setelannya saya tuning pada tiga denah train CubiCasa5K, lalu saya bekukan sebelum melihat denah uji.

DenahRuangan referensiDitemukanCocokF1 jumlahLuas total
Sederhana53120,11+33,8%
Sedang (dapur terbuka)92300,00−1,3%
Padat (dua lantai)287150,10−4,5%

Sebagai penghitung ruangan, baseline ini gagal, dan cara gagalnya lebih penting daripada skornya:

  • Ia membelah ruangan di garis furnitur, meja dapur dan perlengkapan: 4 sampai 10 belahan per denah.
  • Ia menyatukan ruangan lewat pintu dan dapur terbuka. Ruang kosong tidak punya cara untuk tahu di mana satu ruangan berakhir dan yang berikutnya dimulai kalau tidak ada dinding.
  • Setelannya tidak terbawa antar gaya gambar. CubiCasa5K mencampur gaya: ada yang menggambar dinding sebagai pita gelap pekat, ada yang abu-abu muda dengan garis tepi tipis, ada yang garis ganda tipis. Bahkan di denah train ia hanya mencapai F1 jumlah 0,33. Di denah sintetis saya, pintunya (setelah diskalakan ke resolusi kerjanya) lebih lebar dari celah yang dipelajarinya untuk ditutup, sehingga satu unit utuh menjadi satu wilayah.

Baseline pada dua denah sintetis. Kiri: kamar mandi ditemukan, tetapi kamar tidur dan ruang tamu menyatu lewat pintu. Kanan: di denah dua belas ruangan hampir semua ruangan menyatu menjadi satu wilayah, dan garis tepi furnitur keluar sebagai potongan kecil terpisah.

Denah sedang menunjukkan poin sebelumnya di dunia nyata: luas total baseline hanya meleset 1,3% padahal tidak ada satu ruangan pun yang cocok. Kalau yang dilaporkan hanya luas total, baseline ini terlihat sangat bagus.

Artinya dalam Praktik

  • Laporkan galat per ruangan dan jumlah ruangan, bukan hanya luas total atau overlap. Masing-masing menyembunyikan kegagalan yang berbeda: overlap menyembunyikan bias batas, dan total menyembunyikan ruangan yang menyatu atau terbelah.
  • Bias batas murah untuk diperkirakan. Galat luas kira-kira sama dengan offset batas dikali keliling, jadi bias 2 piksel yang diketahui bisa dikoreksi, atau setidaknya ditandai untuk ruangan kecil.
  • Skala adalah tuas tunggal terbesar. Galat skala 2% menggeser luas setiap ruangan sekitar 4%. Takeoff butuh skala terverifikasi sebelum apa pun.
  • Ruang kosong bukan ruangan. Denah terbuka dan pintu butuh pemisahan ruangan yang tidak bisa diberikan dinding saja. Itu pekerjaan untuk model segmentasi terlatih atau aturan eksplisit tentang bukaan, dan ke sanalah saya akan membawa mode C berikutnya.

Batasan

BatasanKenapa pentingLangkah berikutnya
Tiga denah ujiMenunjukkan perilaku galatnya, bukan akurasi umumJalankan set uji yang lebih besar per gaya gambar
Piksel, bukan meterTakeoff sungguhan butuh satuan fisikBaca skala dari skala batang atau garis dimensi
Hanya baseline klasikSedikit bicara soal model terlatihTambahkan model segmentasi terlatih untuk mode C
Tanpa panjang dindingLuas poligon dinding bukan panjangnyaTambahkan metode centreline yang tervalidasi

Coba Sendiri

  • Ukur sebuah denah: uv run python -m quantity_lab --input plan.pdf --annotations model.svg --mode oracle --output out/plan (instalasi dan opsi).
  • Telusuri galatnya pada denah sintetis di Space showcase.
  • Jalankan ulang benchmark-nya: tuning, sapuan galat dan semua file hasil ada di repo.

Kalau kamu membuat atau memeriksa takeoff: angka mana yang kamu percaya duluan, luas total atau daftar ruangan? Eksperimen ini menunjukkan keduanya bisa tidak sepakat dengan cara yang tidak akan terlihat dari satu skor akurasi.

Referensi

  • A. Kalervo, J. Ylioinas, M. Häikiö, A. Karhu dan J. Kannala, "CubiCasa5K: A Dataset and an Improved Multi-Task Model for Floorplan Image Analysis", SCIA 2019. Data: zenodo.org/records/2613548 (CC BY-NC-SA 4.0); mirror per file di Kaggle.
  • Shapely untuk pengukuran poligon dan make_valid, OpenCV untuk mask dan kontur, SciPy linear_sum_assignment untuk pencocokan ruangan.