使用Tensorflow对象检测API,“很抱歉,我识别出...”或识别树莓和控制器

去年年底,我写了一篇文章,讲述了我对使用神经网络识别图像中对象的能力所着迷。在那篇文章中,我们使用PyTorch对视频中的树莓派或类似arduino的控制器进行了分类。尽管事实上我喜欢PyTorch,但我还是向他求助,因为我无法立即处理TensorFlow。但是我保证我会回到视频中物体识别的问题。似乎是时候兑现了诺言。

在本文中,我们将尝试在本地计算机上重新训练Tensorflow 1.13中的成品模型和对象检测API(在我们自己的图像集上),然后使用它来识别使用OpenCV的网络摄像机视频流中的浆果和控制器。

是否想在夏天之前提高您的浆果识别能力?那么,您将受到猫的欢迎。



内容:

第一部分:简介
第二部分:在TenosrFlow中训练模型第三
部分:在OpenCV中应用模型
第四部分:结论

第一部分:简介


那些已经阅读过有关PyTorch的文章的人已经知道,我是神经网络方面的业余爱好者。因此,不要将本文视为最终真理。但是无论如何,我希望我可以使用Tensorflow Object Detection API帮助某人处理视频识别的基础知识。

这次我没有尝试制作教程,因此这篇文章将比平时短。
首先,温和地说,有关在本地计算机上使用对象检测API 官方教程并不详尽。作为一个新手,我完全不够用,只能专注于博客文章。

老实说,我想尝试TensorFlow 2.0,但是在大多数出版物中,在撰写本文时,迁移问题尚未完全解决。因此,最后,我选择了TF 1.13.2。

第二部分:在TensorFlow上讲授模型


从本文开始,或者从上半年开始讲授有关模型的指导,直到应用JavaScript为止(如果您不会说英语,则可以在Habré中看到有关同一主题的文章

的确,就我而言,有几个区别:

  1. 我之所以使用Linux,是因为Linux的Anaconda已经构建了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, , .

以防万一,我会说我没有使用图形加速器。培训仅针对处理器能力进行。

可以像往常一样从GitHub下载一组图像,一个配置文件,一个保存的图形以及使用OpenCV识别图像的脚本

经过长达23小时的模型培训,屋子里所有的茶都已经喝完了,“什么?哪里?什么时候?”检查,现在我的耐心终于结束了。

我们停止训练并保存模型。

使用以下命令在与“ Anaconda”相同的环境中安装OpenCV:

conda install -c conda-forge opencv

我最终安装了4.2版,

此外,我们将不再需要本文中的说明

保存模型后,我犯了一个对我来说并不明显的错误,即,我立即尝试替换先前在Training /文件夹中使用的graph.pbtxt文件的功能:

cv2.dnn.readNetFromTensorflow()

不幸的是,这种方式无法正常工作,我们将不得不再做一次操作来获取针对OpenCV的graph.pbtxt。

我现在建议的事实很可能不是一个很好的方法,但对我来说却有效。

下载tf_text_graph_ssd.py,还将tf_text_graph_common.py放入我们保存的图形所在的文件夹中(我有这个inference_graph文件夹)。
然后转到该文件夹​​中的控制台,并从中执行大约以下内容的命令:

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的控制器。也许这是因为在训练数据中,Arduino及其类似物上有深色图片,模型在23小时内成功达到碰撞。

结果,我不得不将计算机再加载8个小时并训练一个新模型。

她的情况要好得多。

这是CraftDuino的示例:



没有活树莓。我不得不打印图片。在电话或显示器的屏幕上,您也可以识别,但是从纸上看,它更方便。



让我们检查一下模型如何识别Arduino nano,它会在适当的时候德祖格里克对我来说,我用传感器焊接到大型设备中:



如您所见,它可以很好地识别,但是角度很差,在温暖的灯光下,它可以识别一些碎片,例如覆盆子。但是实际上,有错误的镜框很难抓住镜头。

现在,让我们检查一下她是如何对那些未经训练的对象进行分类的。

同样,有一个带有刀和黑色背景的示例:



这次一切都按预期进行。

我们将提供模型来识别我在上一篇文章中写到的Canny 3微型控制器



由于我们的模型除了覆盆子和类似arduino的控制器之外什么都不知道,因此可以说该模型非常成功地识别了Canny控制器。

诚然,就像Arduino nano一样,很大程度上取决于角度和照明。

在白炽灯的暖光和不成功的角度下,控制器不仅可能被识别,甚至被定义为覆盆子。诚然,像过去一样,这些角度仍然必须设法抓住镜头。



好吧,最后一种情况是有关PyTorch中图像分类的文章的一种讽刺与上次一样,Raspberry Pi 2单板计算机及其徽标在一帧内兼容。与前一篇文章不同,在这篇文章中我们解决了分类问题并为图像选择了一个最可能的对象,在这种情况下,徽标和Raspberry本身都被识别。




第四部分:结论


总而言之,我想说的是,尽管这个使用Tensorflow Object Detection API的小例子没有经验,但它花了几天的时间和星期一的一部分时间,我对此并不感到遗憾。当至少对如何使用它有了一点了解时,所有这些都变得非常好奇。在学习过程中,您开始将模型视为活生生的模型,跟随其成功和失败。
因此,我建议所有不熟悉这一天的人尝试并认识自己的东西。

而且,由于它在不断增加,您甚至不需要购买真正的网络摄像头。事实是,在撰写本文的过程中,我设法破坏了我的网络摄像头(打破了焦点机制),并且已经认为我必须放弃一切。但是事实证明,借助Droidcam,您可以使用智能手机代替网络摄像头(不计入广告费用)。而且,事实证明,其拍摄质量比损坏的相机要好得多,这极大地影响了图像中物体的识别质量。

顺便说一下,由于Anaconda具有正常的pycocotools构建我发现它仅适用于Linux,而且我懒得在操作系统之间进行切换,因此我仅使用开放源代码软件来准备整篇文章。有Word和Photoshop的类似物,甚至还有打印机的驱动程序。这是我生命中的第一次。事实证明,即使对于已经使用Microsoft操作系统超过25年的人来说,现代版本的Linux OS和应用程序也可以非常方便。

PS如果有人知道如何正确运行
Tensorflow版本2及更高版本的对象检测API ,请在PM或评论中退订。

祝您有美好的一天,身体健康!

All Articles