机器学习数据获取、处理及图像增强教程及代码实现

搭建机器学习的环境只是机器学习的第一步(搭建环境具体请移步:https://blog.csdn.net/yeahxbf/article/details/124617009),机器学习的关键在于数据的收集与处理,下面我以基于yolov5的图像识别机器学习为例来介绍数据是如何采集并处理的。

1.数据的收集
图像学习最重要的数据就是图片,比较容易获取图像数据的方式就是使用python爬虫程序,下面附上代码。

import requests
import re
import os
import time
headers = {
   'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'}
name = input('您要爬取什么图片')
num = 0
num_1 = 0
num_2 = 0
x = input('您要爬取几张呢?,输入1等于60张图片。')
list_1 = []
for i in range(int(x)):
    name_1 = os.getcwd()
    name_2 = os.path.join(name_1,f"{
     name}")
    url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word='+name+'&pn='+str(i*30)
    res = requests.get(url,headers=headers)
    htlm_1 = res.content.decode()
    a = re.findall('"objURL":"(.*?)",',htlm_1)
    if not os.path.exists(name_2):
        os.makedirs(name_2)
    for b in a:
        try:
            b_1 = re.findall('https:(.*?)&',b)
            b_2 = ''.join(b_1)
            if b_2 not in list_1:
                num = num +1
                img = requests.get(b)
                f = open(os.path.join(name_1,f"{
     name}",name+str(num)+'.jpg'),'ab')
                print('---------正在下载第'+str(num)+'张图片----------')
                f.write(img.content)
                f.close()
                list_1.append(b_2)
            elif b_2 in list_1:
                num_1 = num_1 + 1 
                continue
        except Exception as e:
            print('---------第'+str(num)+'张图片无法下载----------')
            num_2 = num_2 +1
            continue
print('下载完成,总共下载{}张,成功下载:{}张,重复下载:{}张,下载失败:{}张'.format(num+num_1+num_2,num,num_1,num_2))

PS:这里可以根据自己的需求将url对应的网址进行更换。

2.数据的处理
我们收集到的数据有很多是无用的,或者错误的,我们在打标前首先要进行一下初步的过滤,即将无用的数据先自己删除,但是我们不可能保证完全删除干净,所以在打标时仍然会出现有的图片不符合要求,进而没有打标的情况。这会导致图片的数量与标签的数量不一致,不一一对应。为解决这种情况,可以使用以下的代码:

import os

train_images_path_old = r'D:\VOC2007\JPEGImages'
train_images_path_new = r'D:\dataup\img'
train_labels_path_old = r'D:\VOC2007\Annotations'
train_labels_path_new = r'D:\dataup\xml'

os.chdir(train_images_path_old)
os.chdir(train_labels_path_old)
list_images = os.listdir(train_images_path_old)
list_labels = os.listdir(train_labels_path_old)
images_number = 0  # 图片后面加的序号
labels_number = 0  # 图片后面加的序号,用一个就行
for images_list_num in range(0, len(list_images)):  # 先遍历图片序号,再检测标签需要是否与之对应,之后改成一样的名字

    for labels_list_num in range(0, len(list_labels)):
        images_old_name = list_images[images_list_num]
        labels_old_name = list_labels[labels_list_num]
        if (images_old_name[:-3] == labels_old_name[:-3]):
            print("图片文件与标签已经对应,对应的序号为:%d" % (images_number))
            # old_name = list_images[images_list_num]
            images_number = images_number + 1
            new_name = 'new' + '-' + str(images_number)
            try:
                os.renames(str(train_images_path_old) + '\\' + str(images_old_name),  # 存图片
                           str(train_images_path_new) + '\\' + str(new_name) + '.jpg')
                os.renames(str(train_labels_path_old) + '\\' + str(labels_old_name),  # 存标签
                           str(train_labels_path_new) + '\\' + str(new_name) + '.xml')
            except (FileNotFoundError):
                print("目录或文件不存在")
        else:
            print("图片与标签不对应")
print("所有文件均改名完毕")

PS:把图片和标签的路径改为自己的,然后运行即可。运行完后没有图片对应的标签和没有标签对应的图片会被筛出,标签和图片一一对应的会被转移到新的目标文件夹,并重新命名。

3.数据的增强
我们将数据筛选完毕后,会发现我们的数据集可能不够庞大(尤其在面对一些稀有的数据时),这时我们可以采取图像增强的方式,将一张图片通过速度,亮度,添加噪声等方式进行处理,形成多张照片并在新生成的照片上保留原来的标签。这样数据就可以成倍扩大。代码如下:

# -*- coding=utf-8 -*-

# 包括:
#     1. 裁剪(需改变bbox)
#     2. 平移(需改变bbox)
#     3. 改变亮度
#     4. 加噪声
#     5. 旋转角度(需要改变bbox)
#     6. 镜像(需要改变bbox)
#     7. cutout
# 注意:
#     random.seed(),相同的seed,产生的随机数是一样的!!

import sys
#
# ros_path = '/opt/ros/kinetic/lib/python2.7/dist-packages'
#
# if ros_path in sys.path:
#     sys.path.remove(ros_path)

import cv2
import time
import random
import os
import math
import numpy as np
from skimage.util import random_noise
from skimage import exposure
# -*- coding=utf-8 -*-
import xml.etree.ElementTree as ET

# 从xml文件中提取bounding box信息, 格式为[[x_min, y_min, x_max, y_max, name]]
def parse_xml(xml_path):
    '''
    输入:
        xml_path: xml的文件路径
    输出:
        从xml文件中提取bounding box信息, 格式为[[x_min, y_min, x_max, y_max, name]]
    '''
    tree = ET.parse(xml_path)
    root = tree.getroot()
    objs = root.findall('object')
    coords = list()
    for ix, obj in enumerate(objs):
        name = obj.find('name').text
        box = obj.find('bndbox')
        x_min = int(float(box[0].text))
        y_min = int(float(box[1].text))
        x_max = int(float(box[2].text))
        y_max = int(float(box[3].text))
        coords.append([x_min
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yeahxbf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值