低成本ESP32-CAM,YOLO核心代码识别,录像保存,项目中问题分享以及解决。

 低成本ESP32-CAM,YOLO核心代码识别,录像保存,项目中问题分享以及解决。_第1张图片低成本ESP32-CAM,YOLO核心代码识别,录像保存,项目中问题分享以及解决。_第2张图片

ESPCAM监控的具体细节

Arduino编写,

FreeRTOS系统,以便后面添加其他功能,

图片以UDP发送,数据处理基本在服务端,

TCL连接给ESP32人或物的位置,两个舵机控制转向。

服务端的具体细节

后端是python代码,

使用YOLOv5核心代码识别图像人或物,核心代码的提取花时间

用opencv调试和保存为录像以及在图片上标记记录时间。

如代码需要,问题讨论,私我,本人目前在校大二。

        前期的准备工作比如,ESP32-CAM的摄像头初始化,服务端的UDP通讯的建立和TCP的连接我就不详细赘述了,网上一大把都有,个人更倾向于分享一些比较有趣的问题。

        问题1:ESP32-CAM以UDP方式发送图片到局域网下的电脑端,而服务端的数据包接收是散的,个人猜测是图片数据大,而ESP32 WiFi的发送缓存区小导致的:

低成本ESP32-CAM,YOLO核心代码识别,录像保存,项目中问题分享以及解决。_第3张图片

         ESP32-CAM是发送了7205字节的图片,但是服务端却分5次接收,得想办法组合起来,当时网上搜索了没有找很好的解决办法。

        后面发现每次这一帧图片信息的开头几个字节和结尾两个字节都是不变的,开头固定“0xff,0xd8”结尾固定“0xff,0xd9”,顿时想通,图片数据是有的开头结尾啊,用这一点我接收到了完整的图片数据,下面是后端python接收UDP消息并组合数据包的代码:

	# 清空帧缓存
	recv_Buf = bytes()
	while True:
		# 接收图片数据包
		recv_data = udp_sock.recvfrom(2048)
		# 合并接收的数据
		recv_Buf += recv_data[0]
		if len(recv_Buf):
			# 判断帧结尾
			if recv_Buf[-1] == 0xd9 and recv_Buf[-2] == 0xff:
				# 判断帧开头
				if recv_Buf[0] == 0xff and recv_Buf[1] == 0xd8:
					# 完整帧数据
					image_Buf = recv_Buf
					recv_Buf = bytes()
					break
				else:
					# 错误帧开头 缓存清空
					recv_Buf = bytes() 

        此后便是帧数据JPEG的解码,然后就是运行YOLO的核心代码。

	# 解码JPEG
	image = np.asarray(bytearray(image_Buf), dtype="uint8")
	image = cv.imdecode(image, cv.IMREAD_COLOR)

	# YOLO核心代码
	im0, det_list = run(cv_image=image)

         问题2:本人python新手,大家就当我说了个笑话哈:

        项目中发现python的服务端TCP socket是没有判断与客户端的连接状态的函数,有时候客户端断开了都不知道,只在服务端发送消息给客户端的时候才会发现,然后报错退出进程,当时的解决办法是用UDP发送断开代码(ESP32客户端是有判断连接状态的函数的),提示服务端TCP断开连接了,让服务端千万别执行发送函数了,赶紧执行链接accept()函数。

        当时我是真不知道可以用try语句去实现,以为在python里报错是非常不好的,要避免这种情况发生,以前一直用C语言和C++编写STM32,产生了报错就gg这样的思维,后面才明白报错有时候也是一种提示作用。

         这里补上录像保存的代码

	# 创建该段时间(一小时一段)的视频文件名
	time_str = time.strftime('\\%Y_%m_%d_%H.avi', time.localtime())
	if video_dir != time_str:
		video_dir = time_str
		video_out = cv2.VideoWriter(str(save_dir) + video_dir,
		                            cv2.VideoWriter_fourcc(*'XVID'), video_fps, (800, 600))

	# Save results (image with detections)
	if save_img:
		if len(det):
			s_count = save_count
		if len(det) or s_count:
			cv2.putText(cv_image, time.strftime("%Y-%m-%d %H:%M:%S",
                        time.localtime()), (10, 20),
			            cv2.FONT_HERSHEY_COMPLEX,
			            0.5, (0, 255, 255), 1)
			video_out.write(cv_image)
			s_count -= 1

         总结:这个项目中我认为最花时间的部分就是YOLOv5的代码提取,为了提取我把YOLOv5的资料找了遍,讲解视频看了很多,也顺便提升我的python阅读量,了解了神经网络处理图像信息的基本原理,尝试了YOLO训练数据,才发现训练这么吃运算量,笔记本电脑一晚上嗷嗷叫的。但是这次的训练模型我还是采用官方的模型,80种类型的识别更加有扩展性。

        最后,感谢各位读到最后,阅读中有什么问题请一定指出来,一起技术进步~~

你可能感兴趣的:(项目实践总结,YOLO,嵌入式硬件,python,目标检测)