"عذرًا ، لقد تعرفت على ..." أو تعرف على التوت وعناصر التحكم باستخدام واجهة برمجة التطبيقات لكشف كائن Tensorflow

في نهاية العام الماضي ، كتبت مقالًا عن مدى اهتمامي بالقدرة على التعرف على الأشياء في الصور باستخدام الشبكات العصبية. في هذه المقالة ، باستخدام PyTorch ، قمنا بتصنيف التوت أو وحدة تحكم شبيهة بأردوينو على الفيديو. وعلى الرغم من أنني أحببت PyTorch ، فقد التفت إليه لأنني لم أستطع التعامل مع TensorFlow على الفور. لكنني وعدت بأن أعود إلى مسألة التعرف على الأشياء في الفيديو. يبدو أن الوقت قد حان للوفاء بالوعد.

في هذه المقالة ، سنحاول على جهازنا المحلي إعادة تدريب النموذج النهائي في Tensorflow 1.13 و Object Detection API على مجموعة الصور الخاصة بنا ، ثم استخدامه للتعرّف على التوت ووحدات التحكم في دفق الفيديو لكاميرا الويب باستخدام OpenCV.

هل تريد تحسين مهارتك في التعرف على التوت بحلول الصيف؟ ثم أنت مرحب بك تحت القط.



المحتويات:

الجزء الأول: مقدمة
الجزء الثاني: تدريب النموذج في TenosrFlow
الجزء الثالث: تطبيق النموذج في OpenCV
الجزء الرابع: الخاتمة

الجزء الأول: مقدمة


أولئك الذين قرأوا المقالة السابقة حول PyTorch يعرفون بالفعل أنني هاوي في مسائل الشبكات العصبية. لذلك ، لا تعتبر هذه المقالة الحقيقة المطلقة. ولكن على أي حال ، آمل أن أتمكن من مساعدة شخص ما على التعامل مع أساسيات التعرف على الفيديو باستخدام Tensorflow Object Detection API.

هذه المرة لم أحاول عمل برنامج تعليمي ، لذلك ستكون المقالة أقصر من المعتاد.
بادئ ذي بدء ، البرنامج التعليمي الرسمي حول استخدام واجهة برمجة التطبيقات Object Detection API على جهاز محلي ، بعبارة ملطفة ، لا يكاد يكون شاملاً. كمبتدئ ، كنت غير ملائم تمامًا واضطررت إلى التركيز على مقالات المدونة.

لنكون صادقين ، أود أن أجرب TensorFlow 2.0 ، ولكن في معظم المنشورات ، حتى كتابة هذه السطور ، لم يتم حل مشاكل الهجرة بالكامل. لذلك ، في النهاية ، استقرت على TF 1.13.2.

الجزء الثاني: تدريس نموذج في TensorFlow


لقد رسمت تعليمات لتدريس النموذج من هذه المقالة ، أو بالأحرى من النصف الأول ، حتى تم تطبيق جافا سكريبت (إذا كنت لا تتحدث الإنجليزية ، يمكنك مشاهدة مقال حول نفس الموضوع في حبري ) .

صحيح ، في حالتي هناك العديد من الاختلافات:

  1. لقد استخدمت Linux لأن Anaconda for Linux قد قامت بالفعل ببناء protobuf و pycocoapi ، لذلك لم يكن علي بناءها بنفسي.
  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, , .

فقط في حالة ، سأقول أنني لم أستخدم مسرع الرسومات. تم التدريب فقط على قدرات المعالج.

يمكن تنزيل مجموعة من الصور ، وملف التكوين ، والرسم البياني المحفوظ ، بالإضافة إلى برنامج نصي للتعرف على الصور باستخدام OpenCV ، كما هو الحال دائمًا ، من GitHub .

لقد مرت 23 ساعة طويلة من التدريب النموذجي ، وقد تم شرب جميع الشاي في المنزل بالفعل ، "ماذا؟ أين؟ متى؟" تم فحصها والآن صبرى انتهى أخيرا.

نتوقف عن التدريب وحفظ النموذج.

قم بتثبيت OpenCV في نفس بيئة "Anaconda" باستخدام الأمر التالي:

conda install -c conda-forge opencv

لقد قمت في النهاية بتثبيت الإصدار 4.2.

علاوة على ذلك ، لن نحتاج إلى تعليمات من هذه المقالة بعد الآن.

بعد حفظ النموذج ، ارتكبت خطأً واحدًا لم يكن واضحًا بالنسبة لي ، وهو أنني حاولت على الفور استبدال ملف graph.pbtxt المستخدم سابقًا في التدريب / المجلد في الوظيفة:

cv2.dnn.readNetFromTensorflow()

للأسف ، هذا لا يعمل بهذه الطريقة وسوف يتعين علينا القيام بمعالجة أخرى للحصول على Graph.pbtxt لـ OpenCV.

على الأرجح ، حقيقة أن أنصحك الآن ليست طريقة جيدة جدًا ، ولكنها بالنسبة لي تعمل.

قم بتنزيل tf_text_graph_ssd.py ، وكذلك tf_text_graph_common.py وضعها في المجلد حيث يوجد الرسم البياني المحفوظ لدينا (لدي مجلد الاستدلال).
ثم انتقل إلى وحدة التحكم في هذا المجلد وقم بتنفيذ أمر من المحتويات التالية تقريبًا:

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

وهذا كل ما تبقى لتحميل نموذجنا إلى OpenCV.


الجزء الثالث: تطبيق النموذج في OpenCV


كما هو الحال في المقالة حول PyTorch فيما يتعلق بالعمل مع OpenCV ، أخذت كأساس رمز البرنامج من هذا المنشور .

لقد أجريت تغييرات بسيطة لتبسيطها أكثر قليلاً ، ولكن نظرًا لأنني لا أفهم الرمز بالكامل ، فلن أعلق عليه. يعمل وجميل. من الواضح أن الشفرة كان يمكن أن تكون أفضل ، ولكن ليس لدي الوقت حتى الآن للجلوس في دروس OpenCV .

كود 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()


لذا ، كل شيء جاهز. أطلقنا النموذج ، وجه العدسة إلى CraftDuino القديم الخاص بي واستمتع بالنتيجة:



للوهلة الأولى ، إنه ليس سيئًا على الإطلاق ، لكنه فقط للوهلة الأولى.
يبدو أنه في غضون 23 ساعة ، تم إعادة تدريب النموذج ، وبالتالي فإنه يعطي أخطاء خطيرة عند تحديد الأشياء.

هنا عرض مرئي:



كما ترى ، ليس فقط سكينًا ، ولكن حتى مجرد خلفية سوداء ، يعرّفه هذا النموذج على أنه جهاز تحكم يشبه أردوينو. ربما هذا لأنه في بيانات التدريب كانت هناك صور مظلمة مع Arduino ونظائرها ، والتي تمكن النموذج من الارتطام بها في 23 ساعة.

ونتيجة لذلك ، اضطررت إلى تحميل جهاز الكمبيوتر الخاص بي لمدة 8 ساعات أخرى وتدريب نموذج جديد.

الأمور أفضل بكثير معها.

هنا مثال مع CraftDuino:



التوت الحية ليست في متناول اليد. اضطررت لطباعة الصور. من شاشة الهاتف أو الشاشة ، يمكنك أيضًا التعرف عليها ، ولكن من الورق كانت أكثر ملاءمة.



دعونا نتحقق من الطريقة التي يتعرف بها النموذج على Arduino nano ، والذي في الوقت المناسبDrzugrikبالنسبة لي ، أنا ملحوم بجهازي الضخم مع أجهزة الاستشعار:



كما ترون ، فإنه يتعرف جيدًا ، ولكن بزاوية ضعيفة جدًا وفي إضاءة دافئة ، يمكنه التعرف على بعض الأجزاء مثل التوت. ولكن في الواقع ، كان من الصعب التقاط إطار به خطأ في العدسة.

الآن دعونا نتحقق من كيفية تصنيفها لتلك الأشياء التي لم يتم تدريبها عليها.

مرة أخرى ، مثال بسكين وخلفية سوداء:



هذه المرة كل شيء يعمل كما يجب.

سوف نقدم نموذجنا للتعرف على جهاز تحكم Canny 3 الصغير ، الذي كتبت عنه في مقال سابق .



نظرًا لأن نموذجنا لا يعرف أي شيء باستثناء التوت وأجهزة التحكم الشبيهة بأردوينو ، يمكننا القول أن النموذج قد تعرف على وحدة تحكم Canny بنجاح كبير.

صحيح ، كما هو الحال في Arduino nano ، يعتمد الكثير على الزاوية والإضاءة.

مع الضوء الدافئ لمصباح متوهج وزاوية غير ناجحة ، قد لا يتم التعرف على وحدة التحكم فقط ، بل يمكن تعريفها على أنها التوت. صحيح ، كما في الحالة السابقة ، لا يزال يتعين على هذه الزوايا محاولة التقاط العدسة.



حسنًا ، الحالة الأخيرة هي نوع من الانحناء للمقالة حول تصنيف الصور في PyTorch . مثل آخر مرة ، يتوافق الكمبيوتر ذو اللوحة الواحدة Raspberry Pi 2 وشعاره في إطار واحد. على عكس المقالة السابقة ، التي قمنا فيها بحل مشكلة التصنيف واخترنا أحد الكائنات الأكثر احتمالًا للصورة ، في هذه الحالة يتم التعرف على كل من الشعار و Raspberry نفسه.




الجزء الرابع: الخاتمة


في الختام ، أود أن أقول إنه على الرغم من قلة خبرة هذا المثال الصغير للعمل مع Tensorflow Object Detection API ، فقد استغرق الأمر أيام راحة وجزءًا من يوم الاثنين ، إلا أنني لست نادمًا. عندما يصبح فهم القليل على الأقل لكيفية استخدامها كل شيء غريبًا بشكل جنوني. في عملية التعلم ، تبدأ في اعتبار النموذج نموذجًا حيًا ، وتتبع نجاحاته وإخفاقاته.
لذلك ، أوصي كل شخص ليس على دراية بهذا يومًا ما بمحاولة التعرف على شيء خاص به.

علاوة على ذلك ، نظرًا لارتفاعها في هذه العملية ، لا تحتاج حتى إلى شراء كاميرا ويب حقيقية. والحقيقة هي أنه أثناء إعداد المقال ، تمكنت من كسر كاميرا الويب الخاصة بي (كسر آلية التركيز) وفكرت بالفعل أنه سيتعين علي التخلي عن كل شيء. ولكن اتضح أنه بمساعدة Droidcam ، يمكنك استخدام الهاتف الذكي بدلاً من كاميرا الويب (لا تحتسب للإعلان). علاوة على ذلك ، تبين أن جودة التصوير أفضل بكثير من جودة الكاميرا المكسورة ، مما أثر بشكل كبير على جودة التعرف على الأشياء في الصورة.

بالمناسبة ، لأن Anaconda لديها بنية pycocotools عاديةلقد وجدت للينكس فقط ، وكنت كسولًا جدًا للتبديل بين أنظمة التشغيل ، لقد حضرت هذه المقالة بأكملها فقط باستخدام برنامج مفتوح المصدر. كانت هناك نظائر لكل من Word و Photoshop وحتى برنامج تشغيل للطابعة. حدث هذا في المرة الأولى في حياتي. اتضح أن الإصدارات الحديثة من نظام التشغيل Linux والبرامج التطبيقية يمكن أن تكون مريحة للغاية ، حتى بالنسبة لشخص يستخدم نظام التشغيل Microsoft لأكثر من 25 عامًا.

سكرتير خاص إذا كان شخص ما يعرف كيفية تشغيل Object Detection API بشكل صحيح
للإصدار 2 من Tensorflow والإصدارات الأحدث ، فيرجى إلغاء الاشتراك في PM أو في تعليق.

أتمنى لك يوما جميلا وصحة جيدة!

All Articles