Dzaky Zakiyal Fawwaz
Apakah Kita Benar-Benar Butuh Computer Vision untuk Membaca Gambar Konstruksi?

Apakah Kita Benar-Benar Butuh Computer Vision untuk Membaca Gambar Konstruksi?

Diterbitkan pada
11 mnt baca
computer-visionconstructionpdfgeometry

Dua Jenis PDF

Menghitung volume pekerjaan, memeriksa desain, dan merencanakan pekerjaan, semuanya berawal dari garis di sebuah gambar: dinding, bukaan, garis grid. Gambar itu biasanya datang sebagai PDF, dan PDF ada dua jenis. Kalau diekspor dari CAD, setiap garis masih tersimpan sebagai path vektor dengan koordinat yang tepat. Kalau hasil scan atau sudah diratakan, isinya hanya gambar, dan garisnya harus dicari ulang dari piksel.

Jadi pertanyaannya sederhana: kalau PDF masih menyimpan path-nya, apakah kita masih butuh computer vision? Dan kalau gambarnya hanya piksel, seberapa banyak yang hilang? Saya membuat floorplan-parser untuk menjawab keduanya dengan pengukuran, bukan opini: satu tool, dua extractor dengan output yang sama, dan benchmark yang menilai keduanya terhadap geometri gambar itu sendiri.

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

TL;DR

  • Apa itu: CLI Python yang mengambil geometri garis dari PDF gambar, dengan membaca path vektor (PyMuPDF) atau dengan merender halaman lalu mencari garis memakai computer vision klasik (threshold dan Hough lines di OpenCV). Output JSON, CSV dan overlay-nya sama.
  • Cara mengujinya: tiga gambar FloorPlanCAD uji (sederhana, sedang, padat). Masing-masing dijadikan satu PDF vektor dan PDF gambar pada 150, 300 dan 600 DPI, lalu dinilai berdasarkan panjang terhadap geometri SVG aslinya. Setelan jalur piksel hanya di-tuning pada gambar sintetis.
  • Vektor: mendapatkan semua garis di ketiganya (F1 1,000), tetapi setiap busur kembali sebagai puluhan potongan lurus: 7.967 potongan untuk 807 garis di gambar padat.
  • Piksel: F1 1,000, 0,890 dan 0,984 pada 300 DPI. Paling lemah ketika panel pintu digambar sebagai garis yang berjarak di bawah 2 pt, dan di sana resolusi lebih tinggi justru menambah garis yang salah.
  • Catatan jujur: PDF vektor dibuat dari SVG yang sama dengan yang menilainya, jadi angka vektor yang hampir sempurna memang wajar. Yang menarik adalah apa yang tetap salah, dan berapa harga yang dibayar jalur piksel.
Gambarnya adalah gambar sintetis; angkanya dari tiga gambar FloorPlanCAD uji.

Membuat Perbandingannya Adil

Perbandingan seperti ini mudah dimiringkan. Beri satu metode input yang lebih bersih, atau tuning di gambar uji, dan hasilnya sudah ditentukan sebelum dijalankan. Karena itu setiap gambar melewati satu pipeline sebelum dilihat metode mana pun:

  1. Satu sumber. Setiap gambar berawal dari SVG FloorPlanCAD, kumpulan denah CAD nyata yang terbuka.
  2. Tidak ada jawaban di input. Label SVG (primitif mana yang dinding, mana yang pintu) dan semua teksnya dibuang. Gambar dibuat hitam di atas putih dan diskalakan ke halaman 800 × 800 pt.
  3. Dua file dari halaman yang sama. Gambar dikonversi sekali ke PDF vektor. PDF itu lalu dirender ke PDF berisi gambar saja pada 150, 300 dan 600 DPI, jadi jalur piksel melihat gambar yang persis sama.
  4. Kunci jawabannya adalah gambar itu sendiri. Ground truth adalah garis, busur dan lingkaran SVG asli dalam koordinat yang sama. Labelnya hanya dipakai lagi untuk memecah skor per kelas.

Kiri: PDF vektor, ayunan pintu digambar dengan garis yang halus dan tepat. Kanan: halaman yang sama sebagai PDF gambar 150 DPI, busurnya menjadi tangga piksel.

Halaman yang sama, dua file. Di kiri, busurnya tersimpan sebagai geometri; di kanan, hanya piksel, dan metodenya harus menebak di mana garis itu berada.

Catatan soal data: salinan FloorPlanCAD di Hugging Face hanya berisi gambar PNG tanpa SVG, jadi tidak bisa dipakai untuk perbandingan vektor. Saya memakai arsip uji asli dari situs proyeknya. Anotasinya berlisensi non-komersial dan penulisnya tidak memiliki gambar-gambar itu, jadi tidak ada gambar FloorPlanCAD di tulisan ini atau di tempat publik mana pun. Semua gambar di sini adalah gambar sintetis yang saya buat dengan gaya yang sama, dan hasil FloorPlanCAD hanya ditampilkan sebagai angka.

Dua Metodenya

Path vektor. page.get_drawings() di PyMuPDF mendaftar setiap path di halaman: garis lurus, kurva Bézier, persegi panjang. floorplan-parser memecah kurva menjadi potongan lurus pendek (galat 0,1 pt), memecah persegi panjang menjadi empat sisi, dan membuang garis ganda serta garis tanpa panjang. Tidak ada yang dideteksi; semuanya dibaca.

Piksel. Halaman dirender, atau kalau isinya satu gambar besar, didekode pada resolusi aslinya. Lalu:

  • threshold menandai tinta;
  • probabilistic Hough transform (HoughLinesP di OpenCV) mencari segmen lurus;
  • potongan yang terletak di garis yang sama digabung.

Panjang di setelannya memakai satuan point, jadi satu setelan berarti ukuran fisik yang sama di semua resolusi. Tanpa neural network dan tanpa training: satu-satunya tuning adalah grid search kecil atas lima parameter.

Keduanya menulis elements.json yang sama: setiap garis sebagai koordinat dalam point PDF, dengan kotak sumbernya, halamannya, dan metode yang menemukannya.

Dua overlay denah sintetis dengan ayunan pintu dan lingkaran kecil. Path vektor: semuanya biru. Piksel 300 DPI: dinding biru, sementara busur pintu dan lingkaran yang lebih besar sebagian oranye karena kembali sebagai tali busur lurus, dan dua lingkaran terkecil sebagian merah.

Biru adalah yang ditemukan tiap metode, merah garis yang terlewat, oranye garis yang ditambahkan. Jalur piksel hanya mengembalikan segmen lurus, jadi lingkaran menjadi cincin tali busur. Dari dekat, tali busur sedikit menyimpang dari arah kurva, dan skor menghitungnya sebagai kelebihan.

Cara Penilaiannya

Saya menilai berdasarkan panjang, bukan jumlah garis, karena kedua metode memecah garis dengan cara berbeda. Kedua set garis diambil sampelnya setiap 1 pt. Recall adalah porsi garis asli yang berada dalam 2 pt dan 5° dari garis hasil ekstraksi; precision adalah porsi garis hasil ekstraksi yang berada di garis asli. Dinding yang ditemukan dalam 50 potongan mendapat skor sama dengan dinding yang ditemukan utuh. Potongan yang lebih pendek dari 4 pt dicocokkan berdasarkan jarak saja, karena itu adalah kurva yang dipecah, dan dua cara memecah kurva tidak sepakat soal arah per potongan.

Scorer-nya diuji dulu sebelum menilai apa pun:

  • set yang identik mendapat 1,0;
  • garis yang dipecah jadi 50 potongan tetap 1,0;
  • geseran 3 pt mendapat 0;
  • garis yang memotong tegak lurus di bawah 0,05;
  • setengah garis mendapat recall 0,5.

Setelan jalur piksel di-tuning pada lima gambar sintetis dan dibekukan sebelum gambar FloorPlanCAD dijalankan, sekali saja. Set sintetisnya ternyata mudah: setelan hasil tuning mendapat rata-rata F1 0,995 dibanding 0,993 untuk setelan bawaan, jadi tuning hampir tidak berpengaruh.

Hasil

Tiga gambar FloorPlanCAD uji, dipilih berdasarkan ukuran file: grid struktur yang sederhana, lembar sedang dengan pintu, tangga dan garis ganda yang rapat, serta denah apartemen yang padat.

Grafik titik F1 berbasis panjang pada tiga gambar uji. Path vektor mendapat 1,000 di ketiganya. Piksel 300 DPI mendapat 1,000 di grid sederhana, 0,890 di gambar sedang dan 0,984 di denah padat.

GambarGaris asliPath vektorPiksel 150 DPIPiksel 300 DPIPiksel 600 DPI
Sederhana: grid struktur1141,000 (114)0,999 (110)1,000 (102)1,000 (104)
Sedang: pintu, tangga, garis ganda2291,000 (667)0,878 (1.217)0,890 (1.371)0,880 (1.675)
Padat: denah apartemen8071,000 (7.967)0,976 (439)0,984 (515)0,985 (641)

F1 berbasis panjang; jumlah potongan yang dikembalikan tiap metode ada di dalam kurung.

  • Kecepatan: di dua gambar yang lebih sederhana, jalur vektor butuh 5 dan 21 ms dibanding 0,25 dan 0,39 detik untuk piksel 300 DPI. Di gambar padat keduanya setara, 0,38 detik dibanding 0,40 detik, karena jalur vektor harus membersihkan 7.967 potongan.
  • Resolusi: di gambar padat, piksel yang lebih banyak membantu: galat panjang turun dari 9,0% pada 150 DPI ke 0,8% pada 600. Di gambar sedang terjadi sebaliknya (lihat bagian berikut).
  • Scan yang sedikit miring atau berderau (sintetis, 300 DPI): memutar halaman 2° mengurangi F1 0,3 sampai 2,4 poin; derau plus blur menggesernya paling banyak 0,6.

Di Mana Masing-Masing Gagal

Vektor: garisnya benar, jumlahnya salah. Jalur vektor tidak pernah melewatkan garis di sini, tetapi mengembalikannya dalam potongan. MuPDF menyimpan busur sebagai rangkaian segmen lurus pendek, jadi di gambar padat 807 garis asli kembali sebagai 7.967 potongan, sekitar 10 per garis. Skornya berbasis panjang, jadi F1 tetap 1,000. Tetapi langkah yang menghitung dinding atau mengukur bukaan dari potongan itu akan meleset jauh sampai potongannya digabung.

Satu busur pintu dari PDF vektor sintetis, digambar dengan warna bergantian untuk menunjukkan bahwa ia kembali sebagai 90 potongan lurus terpisah. Di gambarnya hanya satu busur.

Hal yang sama di gambar sintetis: satu busur pintu, 90 potongan. Di gambar nyata, ini terjadi pada setiap busur.

Piksel: garis yang bertemu dengan jarak di bawah 2 pt. Di gambar sedang, setiap panel pintu dalam deretan pintu ganda digambar sebagai garis tepi tipis: dua sisi yang berjarak 1 sampai 2,4 pt (kurang dari satu milimeter di kertas), bertemu di sudut yang sama, sebagian digambar dua kali dengan warna berbeda. Di piksel, goresan-goresan itu menyatu menjadi satu gumpalan. Hough lalu menarik segmen menembus gumpalan itu ke arah yang tidak diikuti garis asli mana pun. Pada 300 DPI, sekitar 80% panjang kelebihan di gambar itu berada di garis pintu ganda, dengan jarak median hanya 0,3 pt dari garis asli: di atas tinta, tetapi dengan sudut yang salah. Resolusi lebih tinggi justru memperburuknya: precision turun dari 0,842 ke 0,817 dan galat panjang naik dari 2,8% ke 25,1% antara 150 dan 600 DPI. Pintu ganda juga kelas dengan recall terendah (0,890 pada 300 DPI). Saya mencoba membuat ulang kasus ini di gambar sintetis yang bersih dan tidak berhasil. Panel yang rapi dan berjarak rata terbaca dengan baik, jadi yang membuatnya gagal adalah garis nyata yang berantakan, dan saya tidak punya gambarnya yang boleh dibagikan.

Piksel: kurva kecil. Lingkaran kecil dan ujung busur pintu adalah tempat jalur piksel melewatkan garis. Lingkaran selebar beberapa point kembali sebagai beberapa tali busur, dan yang terkecil kehilangan sisi utuh.

Close-up tiga lingkaran sintetis kecil yang dibaca dari piksel pada 150, 300 dan 600 DPI. Lingkaran terkecil sebagian merah di setiap resolusi, tempat garisnya terlewat.

Keduanya: teks yang digambar sebagai garis. Ekspor CAD sering menggambar label dimensi sebagai goresan, bukan teks. Kedua metode lalu membacanya sebagai geometri. Di halaman sintetis dengan label "1200" yang digambar sebagai garis, semua metode mempertahankan recall 1,0 dan kehilangan precision, jalur vektor sampai 0,963. SVG FloorPlanCAD menyimpan teks secara terpisah, itulah kenapa gambar nyatanya tidak menunjukkan masalah ini. Banyak PDF nyata tidak begitu.

Dinding dan garis dimensi sintetis, dengan label 1200 yang digambar sebagai goresan garis. Extractor membaca goresan label itu sebagai geometri, ditandai oranye.

Bug saya sendiri, ketemu karena melihat overlay. Dua bug mengubah angkanya, dan keduanya sekarang punya test:

  1. Lingkaran kecil dinilai salah. Scorer pertama memeriksa arah di setiap potongan, jadi lingkaran kecil yang dipecah dengan dua cara berbeda terhitung sebagai garis kelebihan. Dari situ aturan 4 pt berasal.
  2. Dinding hasil gabungan jadi miring. Versi pertama penggabung potongan mengelompokkan potongan dengan merangkai sudut yang mirip. Potongan pendek yang dikembalikan Hough untuk sebuah lingkaran mencakup semua sudut, jadi rangkaian itu menyambungkan hampir semuanya, dan dinding digambar ulang mengikuti arah rata-rata yang miring. Ayunan pintu pada 600 DPI mendapat 0,34 sebelum diperbaiki.

Artinya dalam Praktik

  • Kalau PDF masih punya path vektor, baca path-nya. Untuk mendapatkan garis, computer vision di sini hanya menambah galat: path-nya tepat dan, di gambar yang lebih sederhana, 19 sampai 49 kali lebih cepat dibaca. Siapkan langkah untuk menggabung potongan dan menyaring teks yang digambar sebagai garis.
  • Kalau PDF hanya piksel, computer vision klasik sudah cukup jauh untuk gambar yang bersih, tanpa model yang perlu dilatih: F1 0,984 sampai 1,000 pada 300 DPI di gambar sederhana dan padat. Waspadai detail padat seperti panel pintu dan simbol rapat, tempat garis bertemu dengan jarak di bawah 2 pt. Di sana resolusi saja tidak membantu.
  • Apa pun caranya, yang didapat adalah garis, bukan makna. Kedua metode tidak bisa membedakan dinding, pintu atau ruangan. Itu butuh langkah pengenalan terpisah di atasnya, pekerjaan untuk model terlatih atau aturan, dan memang untuk itulah dataset seperti FloorPlanCAD dibuat.

Batasan dan Langkah Berikutnya

BatasanKenapa pentingLangkah berikutnya
Tiga gambar nyataMenunjukkan perilaku metodenya, bukan akurasi umumJalankan set uji yang lebih besar, dibagi per kepadatan
PDF vektor dibuat dari SVG penilaiPDF hasil ekspor CAD menambah hatching, clipping dan layerUji pada PDF yang diekspor langsung dari tool CAD
Jalur piksel hanya garis lurusKurva kembali sebagai tali busurTambahkan deteksi lingkaran dan busur (Hough circles atau contour fitting)
Teks yang digambar sebagai garis tidak disaringLabel mengotori geometriDeteksi kelompok goresan seukuran huruf, atau pakai layer teks PDF
Tidak ada maknaGaris belum berarti dinding atau pintuTambahkan langkah simbol atau segmentasi di atas garisnya

Coba Sendiri

  • Jalankan di gambar kamu: uv run python -m floorplan_parser --input plan.pdf --method vector --output out/plan (instalasi dan opsi).
  • Bandingkan metode dan resolusi pada gambar sintetis di Space showcase.
  • Jalankan ulang benchmark-nya: scorer, tuning dan semua file hasil ada di repo.

Kalau kamu bekerja dengan PDF gambar: berapa banyak yang masih punya path vektor, dan berapa banyak yang hasil scan? Jawaban itu menentukan setengah bagian mana dari tulisan ini yang relevan buat kamu.

Referensi

  • Z. Fan, L. Zhu, H. Li, X. Chen, S. Zhu, P. Tan, FloorPlanCAD: A Large-Scale CAD Drawing Dataset for Panoptic Symbol Spotting, ICCV 2021. Anotasi CC BY-NC 4.0. Nama kelas mengikuti config/anno_config.py di VITA-Group/CADTransformer.
  • R. O. Duda dan P. E. Hart, "Use of the Hough Transformation to Detect Lines and Curves in Pictures", Communications of the ACM, 1972. J. Matas, C. Galambos dan J. Kittler, "Robust Detection of Lines Using the Progressive Probabilistic Hough Transform", Computer Vision and Image Understanding, 2000.
  • PyMuPDF Page.get_drawings() dan OpenCV HoughLinesP.