Dalam
seri sebelumnya, saya melakukan percobaan dengan gerakan otonom
tangki rumah saya . Jalan itu dikenali menggunakan filter warna, dan topeng yang dihasilkan pergi ke pintu masuk jaringan saraf penggolong terlatih, yang memilih untuk pergi ke kanan, kiri atau lurus.
Titik lemah adalah pengakuan jalan itu sendiri karena variabilitas warna, karena itu jaringan saraf pengambilan keputusan menghasilkan hasil yang aneh. Komentar pada artikel itu merekomendasikan untuk memperhatikan segmentasi semantik. Topiknya ternyata menjanjikan dan penggunaan jaringan saraf tersegmentasi membawa keuntungan, tetapi juga kelemahannya, di mana itu tanpa mereka.
Tetapi hal pertama yang pertama dan sedikit peralatan.
Segmentasi
Segmentasi adalah proses menyoroti beberapa bagian dari suatu gambar. Jenis segmentasi yang paling sederhana dan paling jelas adalah warna. Namun, menggunakan metode ini, tidak mungkin untuk memahami apa dan di mana digambarkan dalam gambar.
Berikut adalah
artikel bagus yang menggambarkan pendekatan primitif.
Segmentasi semantik
Segmentasi semantik - memecah gambar menjadi objek dengan menentukan jenis objek ini.
Itu terlihat seperti ini:

Hasilnya sangat mengesankan, mari kita lihat apa yang layak diterjemahkan ke dalam kehidupan nyata.
U-net
Jaringan saraf paling terkenal, awalnya dikembangkan untuk kedokteran.
Sumber utamaOrang dengan cepat menyadari bahwa pendekatan itu dapat digunakan untuk semua kesempatan.
Ada banyak artikel di Internet tentang cara menyiapkan data dan melatih jaringan U-net:
Namun, saya tidak menemukan jaringan U-net siap pakai untuk dengan cepat mengambil dan bereksperimen.
E-net
Jaringan yang lebih muda dan kurang dikenal. Dirancang hanya untuk mengenali jalan-jalan kota.
Data
Kumpulan data paling populer untuk segmentasi jalan (mereka awalnya mengajarkan E-net):
Pada dataset yang sama, U-net sekarang sedang dilatih.
Pilihan Implementasi
Banjir informasi baru tentang segmentasi cukup luar biasa. Secara naluriah, saya ingin menangkap sesuatu yang lebih sederhana. Saya tidak merasakan batin Zen untuk memahami arsitektur jaringan dan menghabiskan waktu belajar. Tetapi dalam artikel dari
PyImageSearch ada jaringan saraf yang siap pakai dan terlatih, apalagi, dalam format yang kompatibel dengan OpenCV-DNN.
Jadi pilihan dibuat ke arah perlawanan paling sedikit.
Penggunaannya sangat sederhana:
(Yang paling mengkhawatirkan adalah bahwa jaringan dilatih dalam gambar 1024x512 - ini, pertama, lebih banyak dari yang diberikan kamera pada Raspberry, dan kedua, kinerja yang diperlukan untuk memproses jumlah data ini agak membingungkan. Akibatnya, masalah utamanya adalah persis seperti itu).
Kami membaca jaringan saraf dari file (dalam satu, model itu sendiri, dalam nama kelas lainnya, dalam warna ketiga).
def load_segment_model(): try: classes = None with open(PiConf.SEGMENT_CLASSES) as f: classes = f.read().strip().split("\n") colors = None with open(PiConf.SEGMENT_COLORS) as f: colors= f.read().strip().split("\n") colors = [np.array(c.split(",")).astype("int") for c in colors] colors = np.array(colors, dtype="uint8") print("[INFO] loading model...") net = cv2.dnn.readNet(PiConf.SEGMENT_MODEL) return net, classes, colors except Exception as e: logging.exception("Cannot load segment model") return None, None, None
Kami mengelompokkan gambar, sekaligus menandai segmen di atas gambar asli
(Dalam kasus saya, semua kelas kecuali jalan tidak terlihat).
def segment_image(image_path, seg_net, seg_classes, seg_colors): image0 = cv2.imread(image_path) image = cv2.resize(image0, (1024, 512),interpolation=cv2.INTER_NEAREST) blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (1024, 512), 0, swapRB=True, crop=False) seg_net.setInput(blob) start = time.time() output = seg_net.forward() end = time.time() print("[INFO] inference took {:.4f} seconds".format(end - start)) (numClasses, height, width) = output.shape[1:4] classMap = np.argmax(output[0], axis=0) mask = seg_colors[classMap] mask = cv2.resize(mask, (image0.shape[1], image0.shape[0]),interpolation=cv2.INTER_NEAREST) classMap = cv2.resize(classMap, (image0.shape[1], image0.shape[0]), interpolation=cv2.INTER_NEAREST) gmask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY) gmask = cv2.resize(gmask, (128, 64), interpolation=cv2.INTER_NEAREST) gmask = gmask[0:64,32:96] output = ((0.6 * image0) + (0.4 * mask)).astype("uint8") return output, gmask
Periksa
Kami mengambil gambar yang sudah jadi dari tangki dan mengatur jaringan saraf tersegmentasi pada mereka.
1

Hanya sisi kiri trotoar yang diakui mahal.
Kami memampatkan gambar dan mengambilnya dari ukuran tengah 64x64:
(Ukuran ini diharapkan oleh jaringan saraf, yang memutuskan untuk mengubah arah)

Jaringan saraf arah (pada kenyataannya - pengklasifikasi) perintah untuk mengambil ke kiri. Tidak terlalu benar, tapi bisa diterima.
2

Situasi serupa, sekali lagi, sudut kanan bawah hilang (ada juga aspal basah).
Namun, sebagian besar jalan masih dikenali.

Pengklasifikasi menawarkan untuk langsung.
3
Keadaan ketika robot berada di tengah trotoar.

Jalannya dikenali hampir sempurna.

Perintah classifier untuk mengambil ke kanan (untuk menemukan tepi jalan waktu berikutnya).
Aplikasi
Setelah menyulap sedikit tentang firmware tangki, saya mengganti detektor jalan warna dengan jaringan saraf segmentasi.
Saat meluncurkan semua ini di Raspberry Pi, hal pertama yang keluar adalah kinerja yang menyedihkan.
Dibutuhkan 6 detik untuk mengelompokkan satu gambar - selama waktu ini, tangki berhasil menyelinap melalui semua belokan dengan berlari cepat.
Dalam tes nyata, ini terjadi - meskipun pengakuan yang hampir sempurna dari trotoar dan perintah yang benar dari jaringan saraf kontrol - selama waktu gambar diproses, tangki berhasil menyingkir.

Secara umum, gambar dengan ukuran ini tidak dapat dicerna di Raspberry.
Tampaknya Anda masih harus melakukan pelatihan jaringan saraf khusus.
Referensi