百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

深度学习 - 1、目标查找(深度目标检测)

haoteby 2025-03-17 18:18 29 浏览


深度学习步骤


我们用 TensorFlow 搭建和训练目标检测模型的代码,以便处理包含缺陷(NG样本)和正常(OK样本)的图片。我们将使用 TensorFlow 2Keras API 来实现。

下面,我将为您提供一个完整的代码示例,包括数据准备、模型搭建和训练过程。这个示例将演示如何处理有缺陷和无缺陷的样本,并在训练过程中正确地处理没有目标的图片。


1. 环境准备

首先,确保您已经安装了以下软件和库:

· Python 3.6+

· TensorFlow 2.x

· Pillow(用于图像处理)

· KerasCV(Keras 计算机视觉组件,包含目标检测模型)

使用以下命令安装必要的库:

bash

pip install tensorflow

pip install pillow

pip install keras-cv --upgrade


2. 数据准备

2.1 数据集组织

假设您的数据集按以下结构组织:

dataset/

├── images/

│ ├── img1.jpg

│ ├── img2.jpg

│ ├── img3.jpg

│ └── ...

├── annotations/

│ ├── img1.xml

│ ├── img2.xml

│ ├── img3.xml

│ └── ...

· images/ 文件夹:存放所有的图片,包括 OK 和 NG 样本。

· annotations/ 文件夹:存放对应的标注文件,格式为 Pascal VOC 的 XML 文件。

o 对于 OK 样本(无缺陷),对应的 XML 文件中 没有 <object> 标签

o 对于 NG 样本(有缺陷),XML 文件中包含缺陷的位置标注。

2.2 标注示例

· NG 样本(有缺陷)XML 文件示例

xml

img1.jpg

768

480

3

<object>

defect

100

150

200

250

</object>

· OK 样本(无缺陷)XML 文件示例

xml

img2.jpg

768

480

3

2.3 导入库

python

import os import xml.etree.ElementTree as ET import tensorflow as tf import numpy as np from PIL import Image import keras_cv from tensorflow import keras

2.4 定义参数和类别

python

# 定义图像尺寸

IMAGE_HEIGHT = 480

IMAGE_WIDTH = 768

# 定义类别列表(包括背景类)

CLASS_NAMES = ['bg', 'defect'] # 'bg' 表示背景类

NUM_CLASSES = len(CLASS_NAMES)

2.5 数据加载和解析

2.5.1 定义解析标注文件的函数

python

def parse_annotation(annotation_path):

tree = ET.parse(annotation_path)

root = tree.getroot()


filename = root.find('filename').text

size = root.find('size')

width = int(size.find('width').text)

height = int(size.find('height').text)


# 初始化边界框和类别列表

boxes = []

labels = []


# 查找所有的 object 标签

for obj in root.findall('object'):

name = obj.find('name').text

label = CLASS_NAMES.index(name)


bndbox = obj.find('bndbox')

xmin = int(bndbox.find('xmin').text) / width

ymin = int(bndbox.find('ymin').text) / height

xmax = int(bndbox.find('xmax').text) / width

ymax = int(bndbox.find('ymax').text) / height


boxes.append([ymin, xmin, ymax, xmax]) # 坐标格式为 y_min, x_min, y_max, x_max

labels.append(label)


return filename, boxes, labels

2.5.2 加载数据集

python

# 数据集路径

DATASET_PATH = 'dataset/' # 请根据实际情况调整路径

# 获取图像和标注文件列表

image_dir = os.path.join(DATASET_PATH, 'images')

annotation_dir = os.path.join(DATASET_PATH, 'annotations')


image_files = sorted(os.listdir(image_dir))

annotation_files = sorted(os.listdir(annotation_dir))

# 构建数据集列表

dataset = []

for annotation_file in annotation_files:

annotation_path = os.path.join(annotation_dir, annotation_file)

filename, boxes, labels = parse_annotation(annotation_path)

image_path = os.path.join(image_dir, filename)


data = {

'image_path': image_path,

'boxes': np.array(boxes, dtype=np.float32),

'labels': np.array(labels, dtype=np.int32)

}

dataset.append(data)

2.6 创建 TensorFlow Dataset

python

def load_data(data):

image = Image.open(data['image_path']).convert('RGB')

image = image.resize((IMAGE_WIDTH, IMAGE_HEIGHT))

image = np.array(image) / 255.0 # 归一化到 [0,1]


boxes = data['boxes']

labels = data['labels']


# 如果没有目标,boxes 和 labels 为空,需要特殊处理

if boxes.size == 0:

boxes = np.array([[0, 0, 0, 0]], dtype=np.float32)

labels = np.array([0], dtype=np.int32) # 背景类


return image, {'boxes': boxes, 'classes': labels}

# 构建 TensorFlow Dataset

images = []

targets = []

for data in dataset:

image, target = load_data(data)

images.append(image)

targets.append(target)

# 将列表转换为张量

images = np.array(images, dtype=np.float32)

boxes = [target['boxes'] for target in targets]

classes = [target['classes'] for target in targets]

2.7 创建数据生成器

由于每个样本的目标数量不同,我们需要创建一个生成器来提供数据,同时处理不同长度的边界框和类别。

python

def data_generator():

for img, bxs, cls in zip(images, boxes, classes):

yield img, {'boxes': bxs, 'classes': cls}

# 定义输出签名

output_signature = (

tf.TensorSpec(shape=(IMAGE_HEIGHT, IMAGE_WIDTH, 3), dtype=tf.float32),

{

'boxes': tf.TensorSpec(shape=(None, 4), dtype=tf.float32),

'classes': tf.TensorSpec(shape=(None,), dtype=tf.int32)

}

)

# 创建 Dataset

dataset = tf.data.Dataset.from_generator(

data_generator,

output_signature=output_signature

)

# 定义批大小和预取

BATCH_SIZE = 8

dataset = dataset.shuffle(1000).padded_batch(

BATCH_SIZE,

padding_values=(

tf.constant(0, dtype=tf.float32),

{

'boxes': tf.constant(0, dtype=tf.float32),

'classes': tf.constant(0, dtype=tf.int32)

}

),

drop_remainder=True

).prefetch(buffer_size=tf.data.AUTOTUNE)


3. 构建模型

3.1 使用 KerasCV 的 RetinaNet 模型

KerasCV 提供了预训练的目标检测模型,如 RetinaNet。我们可以使用预训练的 backbone,并根据我们的数据集进行微调。

python

from keras_cv.models import RetinaNet


model = RetinaNet(

classes=NUM_CLASSES, # 类别数量

bounding_box_format='yxyx', # 边界框格式

backbone='resnet50', # 预训练的主干网络

backbone_weights='imagenet', # 加载在 ImageNet 上预训练的权重

include_rescaling=False # 我们已经在数据加载时进行了归一化

)

3.2 编译模型

python

# 定义优化器和学习率

optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4)

# 编译模型

model.compile(optimizer=optimizer)


4. 模型训练

4.1 开始训练

python

EPOCHS = 10


history = model.fit(

dataset,

epochs=EPOCHS,

verbose=1

)


5. 模型评估与预测

5.1 预测并可视化结果

python

import matplotlib.pyplot as plt

def visualize_detections(image, y_pred, threshold=0.5):

boxes = y_pred['boxes'][0].numpy()

scores = y_pred['confidence'][0].numpy()

classes = y_pred['classes'][0].numpy()


# 过滤低于阈值的预测

idxs = scores > threshold

boxes = boxes[idxs]

scores = scores[idxs]

classes = classes[idxs]


plt.figure(figsize=(10, 10))

plt.imshow(image)

ax = plt.gca()


for box, score, cls in zip(boxes, scores, classes):

y_min, x_min, y_max, x_max = box


# 将坐标转换为图像尺寸

x_min *= IMAGE_WIDTH

x_max *= IMAGE_WIDTH

y_min *= IMAGE_HEIGHT

y_max *= IMAGE_HEIGHT


width = x_max - x_min

height = y_max - y_min


rect = plt.Rectangle((x_min, y_min), width, height,

fill=False, color='red', linewidth=2)

ax.add_patch(rect)

text = f'{CLASS_NAMES[cls]}: {score:.2f}'

ax.text(x_min, y_min - 10, text, color='red', fontsize=12)


plt.axis('off')

plt.show()

# 从数据集中获取一张测试图片

test_image, _ = next(iter(dataset.unbatch().take(1)))

test_image_np = test_image.numpy()

# 扩展维度以匹配模型输入

test_image_input = np.expand_dims(test_image_np, axis=0)

# 进行预测

y_pred = model.predict(test_image_input)

# 可视化检测结果

visualize_detections(test_image_np, y_pred, threshold=0.5)


6. 注意事项·

处理没有目标的图片:在数据准备时,对于没有目标的图片,我们将 boxes 设置为 [[0, 0, 0, 0]],classes 设置为 [0],其中 0 表示背景类。·

类别索引:在 KerasCV 中,类别索引从 0 开始,其中 0 通常表示背景类。因此,要确保在标注解析时正确地映射类别索引。

边界框格式:我们使用 yxyx 格式([y_min, x_min, y_max, x_max]),并且坐标值是相对于图像尺寸的归一化值(在 0 到 1 之间)。

批处理数据:由于每个样本的目标数量不同,我们使用 padded_batch 并指定 padding_values,以确保批数据形状一致。

训练超参数:可以根据实际情况调整批大小、学习率和训练轮数,以获得更好的模型性能。

·


7. 总结

通过以上步骤,我们成功地使用 TensorFlow 和 KerasCV 构建并训练了一个目标检测模型,该模型能够处理包含缺陷和没有缺陷的图片。关键在于正确地处理没有目标的图片,并确保数据格式和类别索引的一致性。

相关推荐

Python爬虫进阶教程(二):线程、协程

简介线程线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能...

A320-V2500发动机系统FADEC介绍(2)

目的全权数字发动机控制(FADEC)系统在所有飞行和运行阶段提供全范围发动机控制。...

三国志战棋版:玩家“二叔”用这套群DOT在比武中拿下31胜5负

声明:本文首发于今日头条,而后发布于“鼎叔闯三棋”的微信公众号、抖音、哔哩哔哩和小红书平台,如果在其他平台就是抄袭。...

真正的独一无二:Dot One 推出 DNA 定制系列 139英镑起

相信很多人在挑选衣物时有着这样的困扰,综合了性价比、面料等因素后好不容易找到了心仪的款式,还要担心是否会撞衫,不管是擦肩而过的陌生人还是身边的熟人,都令人尴尬。小部分人为此热衷于购买少量的古着或者限量...

崩铁:周年庆福利再升级,老角色加强时间确定,3.xdot体系反转

#埃安UT大一圈高级很多#...

Dotgo推出RBMHub,扩大了CPaaS提供商的覆盖范围和功能

据telecompaper网7月15日报道,用于商业消息传递的RichCommunicationServices(RCS)解决方案的领先提供商Dotgo宣布推出RBMHub。RBMHub的推出扩大了C...

深度解析:快照取消Dot职业的将何去何从

写在前面曾几何时,术士的出现便被冠以dot大师的名头,从远古时期的献祭腐蚀虹吸不如暗牧一个痛,到TBC上满dot=荣誉击杀+1,到wlk接近全暴击的冰晶腐蚀,再到CTM就算了吧MOP的各种变态吸x放...

星穹铁道:抽卡芙卡之前,你必须了解什么是dot!

卡妈终于上线了,可还是有很多人不明白什么是dot伤害,抽了卡妈直接玩起了直伤流,把一个持续伤害的引爆器玩成了打手,卡妈打dot伤害是远高于直伤的,有了卡妈的玩家一直了解dot,不然这卡妈就真被玩成四不...

游戏界的闪耀星辰陨落:悼念知名游戏博主″dotα牛娃″

无尽哀思!在数字时代浪潮中,游戏不仅是消遣娱乐的代名词,更是连接心灵的桥梁,构筑了无数人的青春回忆。在这片浩瀚无垠的游戏宇宙中,有这样一位博主,他以独特的风采、深邃的洞察力和无尽的热情,成为了玩家心中...

直击2017新加坡同性恋聚会Pink Dot,自由爱!

今年的“粉红点”又来啦~这个支持LGBT群体(男女同志、双性恋、跨性别等)群体的活动,从2009年起,已经在新加坡举办8年了!”这个非营利的同性恋权益活动,主要是希望大家了解到,不管一个人的性倾向或...

python-dotenv,一款超级实用处理环境变量python库

python-dotenv,一款超级实用处理环境变量python库python-dotenv概述:...

亚马逊语音助手毫无征兆发笑 诡异至极吓坏用户

来源:新华网美国电商亚马逊7日承诺,将更改名下“亚历克萨”语音系统设置,令它不会莫名发笑,免得吓坏用户。“亚历克萨”是亚马逊开发的语音助手软件,可服从用户语音指令完成对话、播放音乐等任务。依照原来设计...

2022最火英文网名男女生

精选好听英文昵称带翻译1.moveon(离开)2.Monster(怪物)3.Solo吉他手4.Finish.(散场)...

智能家具 RecycleDot 的出现给传统家具厂商带来新的挑战

从可穿戴手环、手表到智能衣服,智能硬件逐步渗透到每一个领域。最近有一对父子MikeSandru和JohnSandru在自家的车库中设计了一款智能家具RecycleDot,给日渐萧条的家具行...

欧洲通信卫星公司 OneWeb 敦促印度DoT尽早批准提供卫星宽带服务

据telecomtalk2月17日报道,欧洲通信卫星公司EutelsatOneWeb近日敦促印度电信部(DoT)尽快批准其在印度部署双地球站网关的计划,以便连接其近地轨道(LEO)全球卫星星座,并...