当前位置:   article > 正文

基于YOLOv5的多余物检测技术_yolo做图片对比

yolo做图片对比

0.介绍

记录了“基于YOLOv5的多余物检测技术”的所有操作步骤,从:相机标定、图像采集、图像标注、图像预处理、网络模型选择、网络模型训练、网络模型测试、网络模型优化、网络模型部署。方便后续复习与交流。

1.相机标定

1.1作用

1、去畸变(Distortion Correction):相机标定可以用于去除相机镜头畸变的效应,主要有径向畸变和切向畸变。径向畸变会导致图像中心的物体显得弯曲,而切向畸变会使图像中的物体看起来稍微倾斜或不在垂直或水平方向。通过相机标定,可以矫正这些畸变,使图像更准确地表示真实世界。

2、三维场景重建:相机标定使得从多个不同角度拍摄的图像可以精确地重建三维场景。通过知道相机的内部参数(如焦距、主点等)和外部参数(如相机的位置和方向),可以将多个图像中的特征点匹配并用于重建三维点云或三维模型。

3、定位和导航:相机标定对于机器人、自动驾驶汽车和其他自主导航系统非常重要。标定相机可以帮助这些系统理解自己在三维空间中的位置和方向,从而更好地导航和决策。

4、计算视差和深度:在立体视觉中,两个相机的相对位置需要准确标定,以计算物体的深度信息。这对于深度感知、避障和3D场景重建非常重要。

5、图像处理:相机标定可用于在图像处理中校准图像,以确保相机之间的一致性。这对于计算机视觉任务如目标检测、人脸识别和图像配准非常有用。

6、增强现实:在增强现实应用中,相机标定有助于将虚拟对象精确地叠加到现实世界中。为了实现这一点,需要知道相机的参数,以便将虚拟对象与现实世界进行精确对齐。

总之,相机标定是在计算机视觉和计算机图像处理中的关键步骤,它有助于提高图像和视觉数据的准确性,并为各种应用领域提供了更精确的信息,从而提高了算法的性能和可靠性。

1.2用到的工具

1、控制拍摄的python代码
2、MATLAB

1.3 操作步骤

步骤1:
先准备好一个images文件夹,文件夹里面创建两个文件夹,分别为l和r;

文件夹名可以自己取,创建好后在文件夹里面创建两个文件夹:l和r;

步骤2:
修改img_capture.py里面的代码并连接好双目相机运行(拍摄的照片是黑白色的);
在这里插入图片描述
具体代码为:

# OpenCV库,用于处理图像和视频。
import cv2
# 用于文件和目录操作。
import os

from stereo_config_200 import stereoCamera
class ImgCapture:
    # 保存图像文件的路径。
    SAVE_PATH = "E:\\desk\\Laboratory_Learning_Materials\\demo\\imgs\\"  # 自行修改并创建imgs文件夹,若运行标定采样程序则在其下再创建l和r两个文件夹
    # SAVE_PATH = "E:\\desk\\Laboratory_Learning_Materials\\demo\\photoImgs\\"

    # 用于检查文件夹是否为空,返回一个适当的起始索引。如果文件夹不为空,它会返回最后一个文件的索引加1,以作为新的文件名的起始数字。
    def file_isempty(self,file_dir):
        '''
        读取文件夹下所有文件的名字,并把他们用列表存储起来,如果列表不为空,返回最后一个列表元素+1数值,作为新名字命名起始数字
        :param file_dir: 待读取的文件路径
        :return: 返回值为0或列表最后一个元素的名字
        '''
        dir_path = file_dir
        datanames = os.listdir(dir_path)
        name_list = []
        start_int = 0
        for file_name in datanames:
            name_list.append(file_name)
        list_len = len(name_list)
        print("已采集照片{}".format(list_len))
        if list_len:
            start_int = list_len  # 因为文件是以int形式命名,所以可行
            return start_int
        else:
            return start_int

    # 用于"标定相机",捕捉图像并保存在左右相机文件夹中。
    # 按下's'键拍摄图像,按下'q'键退出。函数使用OpenCV的VideoCapture来捕获实时图像。
    # 在每次拍摄时,将图像保存到左/右文件夹,并将索引递增。
    # 用于标定相机,捕捉图像并保存在左右相机文件夹中。
    # 按下's'键拍摄图像,按下'q'键退出。函数使用OpenCV的VideoCapture来捕获实时图像。
    # 在每次拍摄时,将图像保存到左/右文件夹,并将索引递增。
    def for_calibration(self,start_index=0):
        print("Image Capture For Calibration, 's' to shot, 'q' to quit")
        # 这两行代码创建了两个视频捕获对象,分别代表两个摄像头。cap 表示第二个摄像头(1号),cap2 表示第一个摄像头(0号)
        cap = cv2.VideoCapture(1)  # 双usb时候再启用这套
        cap2 = cv2.VideoCapture(0)

        # # 设置相机分辨率
        # cap.set(3, 1280.0)  # 设置摄像头采集图像分辨率
        # cap.set(4, 720.0)  # 设置摄像头采集图像分辨率 高
        # # 设置相机分辨率
        # cap2.set(3, 1280.0)  # 设置摄像头采集图像分辨率
        # cap2.set(4, 720.0)  # 设置摄像头采集图像分辨率 高

        # config = stereoCamera()
        # i 和 j 用于跟踪图像的索引,i 用于左摄像头图像,j 用于右摄像头图像。
        i = start_index
        j = start_index
        img_num = 0
        # 进入一个无限循环,通过 cap 和 cap2 读取摄像头的图像帧。
        while (True):
            ret, frame = cap.read()
            ret2, frame2 = cap2.read()
            # 这两行代码将图像转换为灰度图像。matlab2020似乎只支持灰度图像,因此将图像转换为灰度以满足需求。
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # matlab2020双目标定只支持输入灰度图
            frame2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)  # 此处上三行是双USB用的
            # 在每次循环中,等待用户按键输入,cv2.waitKey(3000) 会等待 3000 毫秒(3秒),如果用户按下 'q' 键,就退出循环。
            k = cv2.waitKey(3000)  # 每隔N秒自动拍照
            if k == ord('q'):
                break
            # elif k == ord('s'):

            # 如果用户没有按下 'q' 键,就进入这个分支。
            # 首先打印 "start saving images"。
            # 然后,使用 cv2.imwrite 将灰度图像 frame 和 frame2 保存为文件。文件名根据 i 构建,以连续的数字作为文件名,例如,0_l.jpg, 1_l.jpg, 2_l.jpg 代表左摄像头图像,0_r.jpg, 1_r.jpg, 2_r.jpg 代表右摄像头图像。
            # i 和 j 递增,图像数量也递增,并打印已成功保存图像的消息。
            else:
                cv2.imwrite(self.SAVE_PATH + 'l\\' + str(i) + '_l.jpg', frame)  # 后续再改这两行中的l_frame就行
                i += 1
                cv2.imwrite(self.SAVE_PATH + 'r\\' + str(j) + '_r.jpg', frame2)
                j += 1
                img_num += 1
                # 每个相机拍到60张后停止拍摄
                if img_num % 60 == 0:
                    break
                print("saving images!,we have collected {} images!".format(i))
            # 在循环中,显示左右相机捕获的图像。
            cv2.imshow("left", frame)
            cv2.imshow("right", frame2)
        # 最后,释放摄像头资源,并关闭所有的 OpenCV 窗口。
        cap.release()
        cap2.release()
        cv2.destroyAllWindows()

    # 用于拍摄多余物图片,同样捕获图像,但这些图像在捕获后进行了畸变校正。
    # 保存的图像命名方式是0.jpg, 1.jpg, 2.jpg等。
    def for_training(self,start_index=0):
        print("Image Capture For Training, 's' to shot, 'q' to quit")
        config = stereoCamera()
        # 这两行代码创建了两个视频捕获对象,分别代表两个摄像头。cap表示第二个摄像头(1号),cap2表示第一个摄像头(0号)。
        cap = cv2.VideoCapture(1)
        cap2 = cv2.VideoCapture(0)

        # 用于设置相机的分辨率。如果需要特定的分辨率,可以修改参数。
        # cap.set(3, 1280.0)  # 设置摄像头采集图像分辨率
        # cap.set(4, 720.0) # 设置摄像头采集图像分辨率 高
        # 设置相机分辨率
        # cap2.set(3, 1280.0)  # 设置摄像头采集图像分辨率
        # cap2.set(4, 720.0) # 设置摄像头采集图像分辨率高

        # i和img_num用于跟踪图像的索引和已捕获的图像数量。
        i = start_index
        img_num = 0
        # 进入一个无限循环,通过 (左右摄像头)cap和cap2读取摄像头的图像帧。
        while (True):
            ret, frame = cap.read()
            ret2, frame2 = cap2.read()
            # 训练用照片就做畸变校正
            frame, frame2 = config.Rectify(frame, frame2)
            # 在每次循环中,等待用户按键输入,cv2.waitKey(5000) 会等待 5000 毫秒(5秒),如果用户按下 'q' 键,就退出循环。
            k = cv2.waitKey(5000)
            if k == ord('q'):
                break
            # elif k == ord('s'):

            # 如果用户没有按下 'q' 键,就进入这个分支。
            # 首先打印 "start saving images"。
            # 然后,使用 cv2.imwrite 将图像帧 frame 和 frame2 保存为文件。文件名根据 i 构建,以连续的数字作为文件名,例如,0.jpg, 1.jpg, 2.jpg,以此类推。
            # i递增,图像数量img_num也递增,每次递增2。
            # 如果已经收集了500张图像,就退出循环。
            else:
                print("start saving images")
                # 因定位部分对左右两张图片的识别结果都有很大依赖,而左右相机存在一定色差,故左右两张图都存
                cv2.imwrite(self.SAVE_PATH + str(i) + '.jpg', frame)
                i += 1
                cv2.imwrite(self.SAVE_PATH + str(i) + '.jpg', frame2)
                i += 1
                img_num += 2
                if img_num % 300 == 0:
                    break

            # 在循环中,打印已成功保存图像的消息,显示左右相机捕获的图像。
            print("saving images successfully!{} imgs have collected!".format(img_num))
            cv2.imshow("left", frame)
            cv2.imshow("right", frame2)

        # 最后,释放摄像头资源,并关闭所有的 OpenCV 窗口。
        cap.release()
        cap2.release()
        cv2.destroyAllWindows()

# obj = ImgCapture()
# start_num = 11000+obj.file_isempty(obj.SAVE_PATH)
# obj.for_calibration(start_index=start_num)
# obj.for_training(start_index=start_num)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152

1、存储路径改一下,改成步骤1里面创建好的images文件夹路径下
在这里插入图片描述

2、打开第一个函数,注释掉第二个函数,并运行python代码进行连续的拍摄

for_calibration函数用于相机标定
for_training函数用于多余物拍摄

步骤3:
将拍摄好的照片进行筛选,删掉一些比较模糊的,或者有阴影的照片(注意,l文件夹中删除了哪儿张照片,r文件夹中对应照片也要删除掉)
步骤4:
请用户自己使用MATLAB软件,点击matlab->APP->Stereo Camera Calibrator->Add Images导入图片,标定板栅格尺寸(Size of checkerboard square)为棋盘中每一个方格的长度,单位为毫米,畸变选项部分勾选Skew3 CoefficientsTangential Distortion,标定后导出参数到Worspace即可。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

步骤5:
运行后得到对应效果,平均重投影误差要在0.5以下,看看柱状图,如果大部分或者全部都在0.5以上,则这组照片不能用,要重新拍摄。如果只有几个高于0.5,则只需要右键删除这几个对应的照片即可。
在这里插入图片描述
在这里插入图片描述

(注:这里删除后,对应文件夹里的照片不会被删除)
步骤6:筛选完后点击绿色小箭头
在这里插入图片描述

步骤7:点击stereoParams得到想要的参数;
在这里插入图片描述
注意: 我们需要获取到的参数有:
1、左相机内参:stereoParams.CameraParameters1.IntrinsicMatrix
在这里插入图片描述

2、右相机内参:stereoParams.CameraParameters2.IntrinsicMatrix

在这里插入图片描述
3、左右相机畸变系数:stereoParams.CameraParameters1.RadialDistortion(K1,K2,k3)
stereoParams.CameraParameters1.TangentialDistortion(p1,p2)在这里插入图片描述
4、旋转矩阵: stereoParams.RotationOfCamera2
在这里插入图片描述

5、平移矩阵:stereoParams.TranslationOfCamera2
在这里插入图片描述

步骤8:将数据更新到stereo_config_200.py文件中对应位置(记得矩阵要转置)
可先在MATLAB控制台中输入如下代码,生成一个Excel文件,里面包含所需要的参数:
MATLAB代码:

rowName = cell(1,10);
rowName{1,1} = '平移矩阵';
rowName{1,2} = '旋转矩阵';
rowName{1,3} = '相机1内参矩阵';
rowName{1,4} = '相机1径向畸变';
rowName{1,5} = '相机1切向畸变';
rowName{1,6} = '相机2内参矩阵';
rowName{1,7} = '相机2径向畸变';
rowName{1,8} = '相机2切向畸变';
rowName{1,9} = '相机1畸变向量';
rowName{1,10} = '相机2畸变向量';
xlswrite('out.xlsx',rowName(1,1),1,'A1');
xlswrite('out.xlsx',rowName(1,2),1,'A2');
xlswrite('out.xlsx',rowName(1,3),1,'A5');
xlswrite('out.xlsx',rowName(1,4),1,'A8');
xlswrite('out.xlsx',rowName(1,5),1,'A9');
xlswrite('out.xlsx',rowName(1,6),1,'A10');
xlswrite('out.xlsx',rowName(1,7),1,'A13');
xlswrite('out.xlsx',rowName(1,8),1,'A14');
xlswrite('out.xlsx',rowName(1,9),1,'A15');
xlswrite('out.xlsx',rowName(1,10),1,'A16');
xlswrite('out.xlsx',stereoParams.TranslationOfCamera2,1,'B1');  % 平移矩阵
xlswrite('out.xlsx',stereoParams.RotationOfCamera2.',1,'B2');  % 旋转矩阵
xlswrite('out.xlsx',stereoParams.CameraParameters1.IntrinsicMatrix.',1,'B5');  % 相机1内参矩阵
xlswrite('out.xlsx',stereoParams.CameraParameters1.RadialDistortion,1,'B8');  % 相机1径向畸变(1,2,5)
xlswrite('out.xlsx',stereoParams.CameraParameters1.TangentialDistortion,1,'B9');  % 相机1切向畸变(3,4)
xlswrite('out.xlsx',stereoParams.CameraParameters2.IntrinsicMatrix.',1,'B10');  % 相机2内参矩阵
xlswrite('out.xlsx',stereoParams.CameraParameters2.RadialDistortion,1,'B13');  % 相机2径向畸变(1,2,5)
xlswrite('out.xlsx',stereoParams.CameraParameters2.TangentialDistortion,1,'B14');  % 相机2切向畸变(3,4)
xlswrite('out.xlsx',[stereoParams.CameraParameters1.RadialDistortion(1:2), stereoParams.CameraParameters1.TangentialDistortion,...
    stereoParams.CameraParameters1.RadialDistortion(3)],1,'B15');  % 相机1畸变向量
xlswrite('out.xlsx',[stereoParams.CameraParameters2.RadialDistortion(1:2), stereoParams.CameraParameters2.TangentialDistortion,...
    stereoParams.CameraParameters2.RadialDistortion(3)],1,'B16');  % 相机2畸变向量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

生成的Excel文件内容
该参数内容已经自动将旋转矩阵、相机1内参、相机2内参的矩阵进行了转置处理
在这里插入图片描述
将参数更新到stereo_config_200.py文件中对应位置

在这里插入图片描述

2.图像采集

2.1 作用

获取来自摄像机或其他图像源的图像或视频数据

2.2 操作步骤

把上述代码中或img_capture.py中的:# for_calibration(start_index=start_num)函数注释掉,把for_training(start_index=start_num)函数取消注释,再运行该python代码便可进行连续的多余物拍摄

3.图像预处理

3.1 作用

对图像进行各种处理,如去噪、增强、尺寸调整、标准化等,以准备数据用于机器学习模型的训练和推理。

4.图像数据集标注

4.1作用

为图像中的对象或区域添加标签、类别或其他元信息,以便训练和评估机器学习模型。

4.2 操作步骤

网上有很多数据集标注的工具,这里介绍的是Yolo_mark工具,该工具能够自动生成.txt的文本文件。Yolo_mark介绍
安装包:

步骤一:
先改一下:obj.data和obj.names里面的数据,然后将图片集全部放入img中
在这里插入图片描述
obj.data文件内容:
在这里插入图片描述
obj.name里面内容:
在这里插入图片描述

步骤二:双击yolo_mark.cmd开始标图
在这里插入图片描述

步骤三:标号后该文件下会自动生成.txt文件(注意0kb的是未标注的,可删除)
在这里插入图片描述
以上是数据集准备工作,接下来是用yolov5网络模型进行训练并生成对应多余物网络模型的操作参考文章,需要先去官网下载好相应的yolov5源码

5.网络模型选择

5.1 作用

选择适当的深度学习或机器学习模型结构,以解决特定的计算机视觉问题。

5.2 操作步骤

步骤一:
选择一个合适的神经网络模型,在yolov5目录下的model文件夹下是yolov5的模型配置文件,有n、s、m、l、x版本,逐渐增大(随着神经网络的结构变大,训练时间也是逐渐增大)。(这些我们可以理解成只是关联文件,用来关联train.py 和对应的神经网络的,后缀名为.pt 的文件才是权重文件(对应的神经网络)。所以这里我们来选择自己需要的配置文件,并修改其中的参数为我们自己的训练集参数就好了。
在这里插入图片描述
如何修改参数?
若选择yolov5s.yaml,则修改models文件夹下的yolov5s.yaml文件内容。
在这里插入图片描述
并在data文件夹下新建一个.yaml的文件,如命名成:mydata.yaml。
在这里插入图片描述

步骤二:
将第一项nc修改为自己的标注类别的数量就好了,其他的我们可以都不动。
在这里插入图片描述
修改data文件夹下的mydata.yaml文件里面的内容:
在这里插入图片描述

步骤三:
然后去官网下载对应模型的.pt文件,并放在yolov5文件夹路径下。
在这里插入图片描述

同时要在train.py中将参数修改为对应的网络模型,若选择mydata.yaml,则更改相应参数如下图:
在这里插入图片描述

6.网络模型训练

6.1作用

使用标记的图像数据来训练模型,使其学习从输入图像中提取特征并进行分类或预测。

6.2 操作步骤

步骤一:
将标好的图片跟TXT文件全部复制到这两个文件夹下:
在这里插入图片描述

步骤二:训练前先配置好相应参数:先修改一下mydata.yaml和train.py里的参数。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

步骤三: 运行train.py代码
可在cmd中运行
在这里插入图片描述
也可在pycharm中运行train.py

效果图:在这里插入图片描述

最后的结果在该路径下:
在这里插入图片描述

7.网络模型测试

7.1 作用

评估训练后的模型的性能,以确定其在新数据上的泛化能力和准确性

7.2 操作步骤

步骤1:先把训练好的权重文件(best.pt)复制到yolov5和my_utils文件夹下
(一般只放在yolov5文件夹路径下,这里的my_utils文件夹是我自己的,想要实现其他功能)
在这里插入图片描述
在这里插入图片描述
步骤2:修改detect.py里面的代码:
(主要是为了让路径匹配,匹配上我们刚训练好的best.pt文件和我们待测试的图像数据集的路径)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

步骤3:将待测试的图片放入该文件夹下:
在这里插入图片描述

步骤4:运行detect.py
运行后得到的结果在该文件夹下:

在这里插入图片描述
在这里插入图片描述

备注一:如何给多余物检测图片上加上多余物种类数量参考文章

步骤一:先在Write results处定义好记录多余物种类数量的变量
请添加图片描述
int(cls)表示类别的序号,通过
if int(cls) == 0: apple_count += 1
可以把下标为0的多余物数量加1
在这里插入图片描述
这里的下标是与data文件夹中自己定义的.yaml文件里的多余物顺序对应的。
步骤二:在if save_img:下面添加如下代码:
在这里插入图片描述
其中:

cv2.putText(im0, text, (180, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5)
  • 1

这段代码使用了 OpenCV 中的 putText 函数,在图像上添加了文本。每个参数的含义:

  • im0: 这是要添加文本的图像。
  • text: 这是要添加的文本内容。
  • (180, 50): 这是文本的起始位置坐标,即文本左下角的位置。
  • cv2.FONT_HERSHEY_SIMPLEX: 这是字体的类型,表示使用简单的字体样式。
  • 2: 这是文本的大小。
  • (0, 0, 255): 这是文本的颜色,这里是红色,用 BGR 格式表示。
  • 5: 这是文本的粗细。

备注二:如何检测视频

在data文件夹下创建一个video文件夹,把要检测的视频放入里面
在这里插入图片描述
修改detect.py里面的代码:把images改成video
在这里插入图片描述
运行detect.py代码。

8.网络模型部署及实时监测

进入camera.py文件和my_detect.py下,修改一些参数:在这里插入图片描述
(1)更改camera.py文件中的LABELS为自己标注时所用到的labels,修改下图部分以连接或断开服务器:
在这里插入图片描述
(2)my_detect.py文件里的ROOT要修改为自己下载的yolov5源码文件中train.py所对应的的路径,即刚才测试时,把best.pt复制到的路径下。
在这里插入图片描述
注:(当左右相机反了时,修改第54-55行的cv2.VideoCapture;当相机硬件支持但运行程序后清晰度欠佳时,修改第68-69行的W和H为相机支持的最高分辨率。)
然后运行camera.py,即可开始检测。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/292256?site
推荐阅读
相关标签
  

闽ICP备14008679号