21类鸟类图像识别

1.实验要求:

现有不同种类的鸟,每一类有5张图,要求是对每一幅图中的鸟进行准确定位,即用bounding box将图中的鸟框出来。

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
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
import cv2
import numpy as np
import os


def preprocess_image(image_path):
# 读取图像并转换为灰度图
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 应用CLAHE增强对比度
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enhanced = clahe.apply(gray)

# 应用高斯模糊减少噪声
blurred = cv2.GaussianBlur(enhanced, (5, 5), 0)

return blurred


def detect_edges(image):
# 使用自适应阈值
thresh = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# 使用Canny边缘检测器检测边缘
edges = cv2.Canny(thresh, 50, 150)
return edges


def find_bounding_box(image, edges):
# 查找边缘图像中的轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
# 计算每个轮廓的边界框
x, y, w, h = cv2.boundingRect(contour)
area = cv2.contourArea(contour)
aspect_ratio = w / float(h)

# 过滤条件:面积大于500,长宽比在合理范围内(假设鸟类的长宽比在0.5到2之间)
if area > 500 and 0.5 < aspect_ratio < 2:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
return image


def save_image(image, output_path):
# 保存处理后的图像
cv2.imwrite(output_path, image)


def main(input_dir, output_dir):
# 如果输出目录不存在,则创建
if not os.path.exists(output_dir):
os.makedirs(output_dir)

# 获取输入目录中所有图像文件的路径
image_paths = [os.path.join(input_dir, img) for img in os.listdir(input_dir) if
img.endswith(('.png', '.jpg', '.jpeg'))]

for image_path in image_paths:
# 预处理图像并生成增强的灰度图
preprocessed_image = preprocess_image(image_path)
# 检测边缘
edges = detect_edges(preprocessed_image)
# 读取原始图像
original_image = cv2.imread(image_path)
# 根据边缘找到并绘制边界框
result_image = find_bounding_box(original_image, edges)

# 保存结果图像
output_path = os.path.join(output_dir, os.path.basename(image_path))
save_image(result_image, output_path)


if __name__ == "__main__":
input_dir = "images"
output_dir = "output"
main(input_dir, output_dir)

DSC_2530-1

DSC_3777

image-20240613115501466

可以看到识别的结果并不好,背景简单,图像清晰的可以正确识别,其他的识别准确率比较低,反复调试后没有更好的结果,引入预训练模型YOLOv5

image-20240613121349160

1
2
pip install opencv-python numpy torch torchvision

1
2
3
4
git clone https://github.com/ultralytics/yolov5
cd yolov5
pip install -r requirements.txt

导入需要的库

1
2
3
4
5
import torch
import cv2
import os
import matplotlib.pyplot as plt

加载预训练的YOLOv5模型

1
2
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True, trust_repo=True)

从文件夹中加载图像

1
2
3
4
5
6
7
8
def load_images_from_folder(folder):
images = []
for filename in os.listdir(folder):
img = cv2.imread(os.path.join(folder, filename))
if img is not None:
images.append((filename, img))
return images

使用YOLO模型进行鸟类检测

1
2
3
4
def detect_birds(image):
results = model(image)
return results

这个函数将图像输入YOLOv5模型,进行目标检测,并返回检测结果。

检查检测是否有效

1
2
3
4
def is_valid_detection(label, confidence, threshold=0.2):
valid_labels = [14, 18, 19, 0] # 鸟类的常见标签编号
return label in valid_labels and confidence >= threshold

在图像上绘制边界框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def draw_bounding_boxes(image, results, confidence_threshold=0.2):
labels, cords = results.xyxyn[0][:, -1], results.xyxyn[0][:, :-1]
x_shape, y_shape = image.shape[1], image.shape[0]

for i in range(len(labels)):
row = cords[i]
label = int(labels[i])
confidence = row[4]
print(f"Label: {label}, Confidence: {confidence}") # 调试输出
if is_valid_detection(label, confidence, confidence_threshold):
x1, y1, x2, y2 = int(row[0] * x_shape), int(row[1] * y_shape), int(row[2] * x_shape), int(row[3] * y_shape)
bgr = (0, 255, 0)
cv2.rectangle(image, (x1, y1), (x2, y2), bgr, 2)

return image

主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def main():
input_folder = 'images'
output_folder = 'output'

images = load_images_from_folder(input_folder)

for filename, image in images:
results = detect_birds(image)
image_with_boxes = draw_bounding_boxes(image, results)
save_image(image_with_boxes, filename, output_folder)
plt.imshow(cv2.cvtColor(image_with_boxes, cv2.COLOR_BGR2RGB))
plt.title(filename)
plt.show()

if __name__ == "__main__":
main()

DSC_2545-1

DSC_2931

DSC_3799-1

DSC_3830-1

DSC_3890-1

DSC_2571-1

DSC_5793

DSC_5785

DSC_3312-1

image-20240620122537307

YOLO(You Only Look Once)是一种实时对象检测系统,能够在单次前向传递中完成对象定位和分类任务。
YOLOv5 的模块
数据加载模块:负责加载和预处理数据,包括图像和标签文件。
模型定义模块:定义YOLOv5的模型结构,包括各层的定义和连接方式。
训练模块:负责模型的训练过程,包括前向传播、损失计算、反向传播和参数更新。
推理模块:负责使用训练好的模型进行预测,并输出检测结果。
后处理模块:负责对模型的输出进行处理,包括非极大值抑制(NMS)等,以得到最终的检测结果。

3.实验心得

在本次实验中,我通过图像处理技术和深度学习模型相结合的方法,成功实现了对鸟类图像的准确定位。实验初期尝试采用了传统的图像处理技术,包括灰度转换、CLAHE增强对比度、高斯模糊、Canny边缘检测等方法来实现目标检测,但在复杂背景下识别效果不佳。为了提高检测的准确性和鲁棒性,引入了预训练的YOLOv5模型,显著提升了鸟类定位的效果。最终实验结果表明,YOLOv5模型能够在多种复杂背景下准确定位鸟类,为实时对象检测提供了可靠的解决方案。

通过本次实验,我深刻体会到了图像处理技术与深度学习模型在目标检测任务中的应用与差异。传统图像处理方法虽然在处理简单背景时效果尚可,但在复杂场景中往往表现不足。而深度学习模型,特别是YOLOv5,凭借其强大的特征提取和实时检测能力,能够在多样化的背景和光照条件下准确检测目标。

此外,本次实验让我在实际操作中掌握了从数据预处理、模型加载与推理、结果后处理等完整的深度学习应用流程。通过对YOLOv5模型的应用,我进一步理解了深度学习模型的内部工作原理和优化方法,同时也认识到在模型训练与应用过程中,数据的质量和多样性对最终检测效果的重要性。

在实验过程中,我也遇到了一些挑战,比如在传统图像处理方法中难以应对复杂背景,以及如何选择合适的模型和参数来提高检测效果。通过不断调试和学习,我积累了更多的实践经验和解决问题的能力。