"Maaf, saya mengenali ..." atau mengenali raspberry dan pengontrol menggunakan Tensorflow Object Detection API

Pada akhir tahun lalu, saya menulis artikel tentang bagaimana saya tertarik dengan kemampuan mengenali objek dalam gambar menggunakan jaringan saraf. Dalam artikel itu, menggunakan PyTorch, kami mengategorikan raspberry atau pengontrol mirip-arduino pada video. Dan terlepas dari kenyataan bahwa saya menyukai PyTorch, saya menoleh kepadanya karena saya tidak bisa langsung berurusan dengan TensorFlow. Tetapi saya berjanji bahwa saya akan kembali ke masalah pengenalan objek dalam video. Tampaknya sudah tiba saatnya untuk menepati janji.

Pada artikel ini, kita akan mencoba pada mesin lokal kita untuk melatih ulang model yang sudah selesai di Tensorflow 1.13 dan Object Detection API pada set gambar kita sendiri, dan kemudian menggunakannya untuk mengenali beri dan pengontrol dalam aliran video kamera web menggunakan OpenCV.

Ingin meningkatkan keterampilan pengenalan buah beri Anda di musim panas? Maka Anda dipersilakan di bawah kucing.



Isi:

Bagian I: pengantar
Bagian II: latih model dalam TenosrFlow
Bagian III: terapkan model di OpenCV
Bagian IV: kesimpulan

Bagian I: Pendahuluan


Mereka yang telah membaca artikel sebelumnya tentang PyTorch sudah tahu bahwa saya seorang amatir dalam pertanyaan jaringan saraf. Karena itu, jangan menganggap artikel ini sebagai kebenaran tertinggi. Tapi bagaimanapun, saya berharap bahwa saya dapat membantu seseorang menangani dasar-dasar pengenalan video menggunakan Tensorflow Object Detection API.

Kali ini saya tidak mencoba membuat tutorial, jadi artikelnya akan lebih pendek dari biasanya.
Untuk memulainya, tutorial resmi tentang penggunaan API Deteksi Objek pada mesin lokal, untuk membuatnya lebih sederhana, hampir tidak lengkap. Sebagai seorang pemula, saya benar-benar tidak memadai dan harus fokus pada artikel blog.

Sejujurnya, saya ingin mencoba TensorFlow 2.0, tetapi dalam kebanyakan publikasi, pada saat penulisan ini, masalah migrasi tidak sepenuhnya terselesaikan. Karena itu, pada akhirnya, saya memilih TF 1.13.2.

Bagian II: mengajar model di TensorFlow


Saya menggambar instruksi untuk mengajar model dari artikel ini , atau lebih tepatnya dari semester pertama, sampai JavaScript diterapkan (Jika Anda tidak berbicara bahasa Inggris, Anda dapat melihat artikel tentang topik yang sama di Habré ) .

Benar, dalam kasus saya ada beberapa perbedaan:

  1. Saya menggunakan Linux karena Anaconda untuk Linux sudah membuat protobuf dan pycocoapi, jadi saya tidak harus membuatnya sendiri.
  2. TensorFlow 1.13.2, Object Detection API 1.13 , TensorFlow 1.13.2. master TF 1.15, 1.13.
  3. numpy — 1.17.5, 1.18 .
  4. faster_rcnn_inception_v2_coco ssd_mobilenet_v2_coco, , .

Untuk jaga-jaga, saya akan mengatakan bahwa saya tidak menggunakan akselerator grafis. Pelatihan dilakukan hanya pada kapasitas prosesor.

Seperangkat gambar, file konfigurasi, grafik yang disimpan, serta skrip untuk mengenali gambar menggunakan OpenCV, seperti biasa, dapat diunduh dari GitHub .

Selama 23 jam pelatihan model telah berlalu, semua teh di rumah sudah diminum, “Apa? Dimana? Kapan?" diperiksa dan sekarang kesabaran saya akhirnya berakhir.

Kami berhenti melatih dan menyimpan model.

Instal OpenCV di lingkungan yang sama "Anaconda" dengan perintah berikut:

conda install -c conda-forge opencv

Saya akhirnya menginstal versi 4.2

Selanjutnya, instruksi dari artikel ini tidak lagi kita perlukan.

Setelah menyimpan model, saya membuat satu kesalahan yang tidak jelas bagi saya, yaitu, saya segera mencoba untuk mengganti file graph.pbtxt yang digunakan sebelumnya dalam pelatihan / folder dalam fungsi:

cv2.dnn.readNetFromTensorflow()

Sayangnya, ini tidak berfungsi seperti ini dan kita harus melakukan satu manipulasi lagi untuk mendapatkan graph.pbtxt untuk OpenCV.

Kemungkinan besar, fakta yang sekarang saya anjurkan bukanlah cara yang sangat baik, tetapi bagi saya itu berhasil.

Unduh tf_text_graph_ssd.py , dan juga tf_text_graph_common.py taruh di folder tempat grafik tersimpan kami (saya punya folder inference_graph ini).
Lalu pergi ke konsol di folder ini dan jalankan perintah tentang konten berikut:

python tf_text_graph_ssd.py --input frozen_inference_graph.pb --config pipeline.config --output graph.pbtxt

Dan hanya itu yang tersisa untuk mengunggah model kami ke OpenCV.


Bagian III: terapkan model dalam OpenCV


Seperti dalam artikel tentang PyTorch mengenai pekerjaan dengan OpenCV saya mengambil sebagai dasar kode program dari publikasi ini .

Saya membuat perubahan kecil untuk menyederhanakannya sedikit lagi, tetapi karena saya tidak sepenuhnya memahami kode, saya tidak akan mengomentarinya. Bekerja dan menyenangkan. Jelas bahwa kodenya bisa lebih baik, tetapi saya belum punya waktu untuk mengikuti tutorial OpenCV .

Kode OpenCV

# USAGE
# based on this code https://proglib.io/p/real-time-object-detection/
# import the necessary packages
from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import imutils
import time
import cv2

prototxt="graph.pbtxt"
model="frozen_inference_graph.pb"
min_confidence = 0.5

# initialize the list of class labels MobileNet SSD was trained to
# detect, then generate a set of bounding box colors for each class
CLASSES = ["background", "duino","raspb"]
COLORS = [(40,50,60),((140,55,130)),(240,150,25)]

# load our serialized model from disk
print("[INFO] loading model...")

net =cv2.dnn.readNetFromTensorflow(model,prototxt)

# initialize the video stream, allow the cammera sensor to warmup,
# and initialize the FPS counter
print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
time.sleep(0.5)
fps = FPS().start()

# loop over the frames from the video stream
while True:
	# grab the frame from the threaded video stream and resize it
	# to have a maximum width of 400 pixels
	frame = vs.read()
	frame = imutils.resize(frame, width=300)

	# grab the frame dimensions and convert it to a blob
	(h, w) = frame.shape[:2]
	blob = cv2.dnn.blobFromImage(frame, size=(300, 300), swapRB=True)

	# pass the blob through the network and obtain the detections and
	# predictions
	net.setInput(blob)
	detections = net.forward()

	# loop over the detections
	for i in np.arange(0, detections.shape[2]):
		# extract the confidence (i.e., probability) associated with
		# the prediction
		print (detections)
		confidence = detections[0, 0, i, 2]

		if confidence > min_confidence:
			# extract the index of the class label from the
			# `detections`, then compute the (x, y)-coordinates of
			# the bounding box for the object
			idx = int(detections[0, 0, i, 1])
			box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
			(startX, startY, endX, endY) = box.astype("int")

			# draw the prediction on the frame
			label = "{}: {:.2f}%".format(CLASSES[idx],
				confidence * 100)
			cv2.rectangle(frame, (startX, startY), (endX, endY),
				COLORS[idx], 2)
			y = startY - 15 if startY - 15 > 15 else startY + 15
			cv2.putText(frame, label, (startX, y+3),
				cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 1)

	# show the output frame
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(1) & 0xFF

	# if the `q` key was pressed, break from the loop
	if key == ord("q"):
		break

	# update the FPS counter
	fps.update()

# stop the timer and display FPS information
fps.stop()
print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()


Jadi semuanya sudah siap. Kami meluncurkan model, arahkan lensa ke CraftDuino lama saya dan nikmati hasilnya:



Sekilas, itu tidak buruk sama sekali, tetapi hanya pada pandangan pertama.
Sepertinya dalam 23 jam, model itu dilatih ulang, oleh karena itu memberikan kesalahan serius ketika mendefinisikan objek.

Berikut adalah demonstrasi visual:



Seperti yang Anda lihat, tidak hanya pisau, tetapi bahkan hanya latar belakang hitam, model ini mendefinisikannya sebagai pengontrol seperti arduino. Mungkin ini karena dalam data pelatihan ada gambar gelap dengan Arduino dan analognya, di mana model berhasil bertemu dalam 23 jam.

Akibatnya, saya harus memuat komputer saya selama 8 jam dan melatih model baru.

Banyak hal lebih baik dengannya.

Berikut ini adalah contoh dengan CraftDuino:



Raspberry langsung tidak tersedia. Saya harus mencetak gambar. Dari layar ponsel atau monitor, Anda juga bisa mengenali, tetapi dari kertas itu lebih nyaman.



Mari kita periksa bagaimana model mengenali nano Arduino, yang pada waktunyaDrzugrikbagi saya, saya menyolder ke perangkat mega saya dengan sensor:



Seperti yang Anda lihat, itu mengenali dengan cukup baik, tetapi dengan sudut yang sangat buruk dan dalam pencahayaan yang hangat, ia dapat mengenali beberapa fragmen seperti raspberry. Namun pada kenyataannya, bingkai dengan kesalahan sulit ditangkap di lensa.

Sekarang mari kita periksa bagaimana dia mengklasifikasikan objek-objek di mana dia tidak dilatih.

Sekali lagi, contoh dengan pisau dan latar belakang hitam:



Kali ini semuanya berfungsi sebagaimana mestinya.

Kami akan menawarkan model kami untuk mengenali kontroler kecil Canny 3, yang saya tulis di artikel sebelumnya .



Karena model kami tidak tahu apa-apa kecuali raspberry dan pengontrol mirip Arduino, kita dapat mengatakan bahwa model itu mengenali pengontrol Canny dengan cukup sukses.

Benar, seperti pada kasus nano Arduino, banyak tergantung pada sudut dan pencahayaan.

Dalam cahaya hangat dari lampu pijar dan dengan sudut yang tidak berhasil, pengontrol mungkin tidak hanya tidak dikenali, tetapi bahkan dapat didefinisikan sebagai raspberry. Benar, seperti pada kasus sebelumnya, sudut-sudut ini masih harus mencoba menangkap lensa.



Nah, kasus terakhir adalah semacam curtsy untuk artikel tentang klasifikasi gambar di PyTorch . Seperti terakhir kali, komputer papan tunggal Raspberry Pi 2 dan logonya kompatibel dalam satu bingkai. Berbeda dengan artikel sebelumnya, di mana kami memecahkan masalah klasifikasi dan memilih satu objek yang paling mungkin untuk gambar, dalam hal ini logo dan Raspberry itu sendiri dikenali.




Bagian IV: Kesimpulan


Sebagai kesimpulan, saya ingin mengatakan bahwa terlepas dari kurangnya pengalaman contoh kecil ini bekerja dengan Tensorflow Object Detection API, butuh dua hari libur dan bagian dari hari Senin, saya tidak menyesal apa pun. Ketika setidaknya sedikit pemahaman tentang bagaimana menggunakannya semua menjadi sangat ingin tahu. Dalam proses belajar, Anda mulai menganggap model sebagai model yang hidup, mengikuti keberhasilan dan kegagalannya.
Karena itu, saya merekomendasikan kepada semua orang yang tidak terbiasa dengan ini suatu hari mencoba dan mengenali sesuatu dari mereka sendiri.

Selain itu, karena telah meningkat dalam proses, Anda bahkan tidak perlu membeli webcam nyata. Faktanya adalah bahwa selama persiapan artikel, saya berhasil memecahkan webcam saya (merusak mekanisme fokus) dan sudah berpikir bahwa saya harus meninggalkan segalanya. Tapi ternyata menggunakan Droidcam Anda bisa menggunakan smartphone alih-alih webcam (tidak termasuk iklan). Selain itu, kualitas pemotretan ternyata jauh lebih baik daripada kamera yang rusak, dan ini sangat memengaruhi kualitas pengenalan objek dalam gambar.

Ngomong-ngomong, karena Anaconda memiliki tubuh pycocotools yang normalSaya hanya menemukan untuk Linux, dan saya terlalu malas untuk beralih di antara sistem operasi, saya menyiapkan seluruh artikel ini hanya menggunakan perangkat lunak open source. Ada analog dari Word dan Photoshop dan bahkan driver untuk printer. Pertama kali dalam hidupku ini terjadi. Ternyata versi modern dari OS Linux dan program aplikasi bisa sangat nyaman, bahkan untuk orang yang menggunakan Microsoft OS selama lebih dari 25 tahun.

PS Jika seseorang tahu cara menjalankan API Deteksi Objek dengan benar
untuk Tensorflow versi 2 dan lebih tinggi, silakan berhenti berlangganan di PM atau dalam komentar.

Semoga hari Anda menyenangkan dan kesehatan yang baik!

All Articles