目录
一、数据集处理部分
数据集的制作是识别训练模型最为关键的一点,并且在我的实际操作过程中发现有几大注意要点(一般人可不会告诉你哦)
(1)一定要注意数据集的制作的多角度
以垃圾识别为例,在拍摄时一定要多角度多方位的拍摄多组照片,包括一个垃圾的360°照片和在托盘上的所有方位(位置点)照片。因为垃圾掉落下去具有不确定因素,可能在托盘停稳后落在托盘上的各个方位并且旋转成为各个角度,给目标检测带来不确定性。(为了更好的模拟识别环境,我选择在摄像头固定好位置后在树莓派上拍摄照片,以追求更好的仿真性)
以下是我在树莓派上运行的拍照程序(程序运行后将会逐帧保存拍摄照片——保存在images
文件夹里,打标签时可以从树莓派里提取出来)
import cv2
from threading import Thread
import uuid
import os
import time
count = 0
def image_collect(cap):
global count
while True:
success, img = cap.read()
if success:
file_name = str(uuid.uuid4())+'.jpg'
cv2.imwrite(os.path.join('images',file_name),img)
count = count+1
print("save %d %s"%(count,file_name))
time.sleep(0.4)
if __name__ == "__main__":
os.makedirs("images",exist_ok=True)
# 打开摄像头
cap = cv2.VideoCapture(0)
m_thread = Thread(target=image_collect, args=([cap]),daemon=True)
while True:
# 读取一帧图像
success, img = cap.read()
if not success:
continue
cv2.imshow("video",img)
key = cv2.waitKey(1) & 0xFF
# 按键 "q" 退出
if key == ord('c'):
m_thread.start()
continue
elif key == ord('q'):
break
cap.release()
(代码参考了csdn大佬——链接如下 基于树莓派4B的YOLOv5-Lite目标检测的移植与部署(含训练教程)_树莓派yolo-CSDN博客)
(2)数据集的优化
自己在手动拍摄时无法做到真正的360°,并且如果全靠手动调整角度后期修改时会无形的添加工作量。为了更好的添加多角度照片,以下是我旋转已有照片的代码。
使用前先在文件夹里创建
images
、result
文件夹,然后把需要旋转的照片放在images里
from math import *
import cv2
import os
import glob
import imutils
import numpy as np
def rotate_img(img, angle):
'''
img --image
angle --rotation angle
return--rotated img
'''
h, w = img.shape[:2]
rotate_center = (w / 2, h / 2)
# 获取旋转矩阵
# 参数1为旋转中心点;
# 参数2为旋转角度,正值-逆时针旋转;负值-顺时针旋转
# 参数3为各向同性的比例因子,1.0原图,2.0变成原来的2倍,0.5变成原来的0.5倍
M = cv2.getRotationMatrix2D(rotate_center, angle, 1.0)
# 计算图像新边界
new_w = int(h * np.abs(M[0, 1]) + w * np.abs(M[0, 0]))
new_h = int(h * np.abs(M[0, 0]) + w * np.abs(M[0, 1])) # 调整旋转矩阵以考虑平
M[0, 2] += (new_w - w) / 2
M[1, 2] += (new_h - h) / 2
rotated_img = cv2.warpAffine(img, M, (new_w, new_h))
return rotated_img
if __name__ == '__main__':
output_dir = "result"
image_names = glob.glob("images/e080b004-ddd9-404c-a518-a8f5671bc658.jpg")#这里改为自己需要旋转的照片名称,注意路径
for image_name in image_names:
image = cv2.imread(image_name, -1)
for i in range(1, 361, 3): # 修改步长为3(每3°旋转一次)可修改
rotated_img1 = rotate_img(image, i)
basename = os.path.basename(image_name)
tag, _ = os.path.splitext(basename)
cv2.imwrite(os.path.join(output_dir, 'qqq-%d.jpg' % i), rotated_img1)#这里可以修改自己的文件名称
二、数据集打标签建议
(1)打标签应用
官方指定的labelimg特别容易崩溃,本人深受其害,后发现makesense网站出奇好用,现推荐给大家——附链接 Make Sense
(2)一些问题
以本项目为例(垃圾识别)需要四种垃圾,标签需要转出为yolo形式,yolo中的第一个数字含义为物体的种类,如下图所示,不同数字代表不同种类。所以如果是小组四个人在打标签,一个人打一种,在配置标签种类时四种也都需要配上,并且每个人打标签的名称顺序以及名称的命名也要保持一致(0,1,2,3)
0 0.503021 0.511827 0.477341 0.261498
3 0.319119 0.725658 0.050600 0.053973
如果打错了想要修改标签数字怎么办,以下是我的代码
import os
def modify_yolo_txt(file_path, new_value):
with open(file_path, 'r') as file:
lines = file.readlines()
modified_lines = []
for line in lines:
parts = line.split(' ')
parts[0] = str(new_value)
modified_lines.append(' '.join(parts))
with open(file_path, 'w') as file:
file.writelines(modified_lines)
# 遍历指定目录下的所有txt文件
directory = 'C:/Users/under/Desktop/Hazardous/labels/val'#修改的标签文件夹(注意绝对路径)
new_value = 1 #修改想要的数字
for filename in os.listdir(directory):
if filename.endswith('.txt'):
file_path = os.path.join(directory, filename)
modify_yolo_txt(file_path, new_value)