👏🏻 你好!欢迎访问IT教程网,0门教程,教程全部原创,计算机教程大全,全免费!

🔥 新增教程

《黑神话 悟空》游戏开发教程,共40节,完全免费,点击学习

《AI副业教程》,完全原创教程,点击学习

13 目标检测之Haar特征分类器

在上篇中,我们讨论了目标检测的概况,了解了目标检测的应用背景、常用方法以及当前技术的发展方向。本篇文章将深入探讨“Haar特征分类器”,它是一种经典的目标检测技术,广泛应用于人脸检测等场景。

什么是Haar特征分类器?

Haar特征分类器利用Haar特征来进行物体检测。Haar特征是由若干矩形区域的强度差形成的特征,它们能够有效捕捉图像中不同位置的纹理和亮度变化。这些特征在图像中提取出局部信息,可以用来区分目标和背景。

Haar特征的种类

Haar特征可以分为以下几类:

  1. 边缘特征:通过比较两个相邻矩形区域的亮度差来表征边缘。
  2. 线段特征:通过两个相邻矩形条带的强度差来检测线条。
  3. 中心对称特征:比较中心区域和外部区域的亮度,以寻找中心对称的形状。

每个Haar特征都是通过局部像素的加权和计算得出的,公式可以表示为:

$$
F(x,y,w,h) = \sum_{(x’,y’) \in R_1} I(x’,y’) - \sum_{(x’,y’) \in R_2} I(x’,y’)
$$

其中,$R_1$和$R_2$是两个矩形区域,$I(x’,y’)$是图像在点$(x’,y’)$的像素值。

Haar特征提取与分类器训练

在Haar特征分类器中,首先需要提取许多Haar特征,然后利用这些特征训练分类器。这通常通过AdaBoost算法来完成,该算法可以选择最优特征并训练强分类器。

OpenCV中的Haar特征分类器用法

OpenCV提供了一整套工具来使用Haar特征进行目标检测。以下是一个简单的步骤,展示如何使用OpenCV加载预训练的Haar分类器并检测图像中的目标(如人脸):

步骤1:加载Haar特征分类器

OpenCV自带了若干个训练好的Haar特征分类器,例如用于人脸检测的haarcascade_frontalface_default.xml。我们可以通过以下代码加载它:

1
2
3
4
import cv2

# 加载Haar特征分类器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

步骤2:读取图像并进行人脸检测

接下来,我们可以读取一张图像,并在图像中检测人脸:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 读取图像
image = cv2.imread('path_to_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

# 在图像上绘制矩形框
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)

# 显示结果
cv2.imshow('Detected Faces', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

参数解释

  • scaleFactor:在搜索过程中,每次图像尺寸缩小的比例,通常设置为1.1。
  • minNeighbors:检测目标的每个矩形框的最小邻居数。增加该值会减少误检。

实际案例

假设我们想要检测一组图像中的人脸,可以将上述代码封装在一个循环中,批量处理多张图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import os

image_folder = 'path_to_image_folder'

for filename in os.listdir(image_folder):
if filename.endswith('.jpg'):
img_path = os.path.join(image_folder, filename)
image = cv2.imread(img_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)

cv2.imshow('Detected Faces', image)
cv2.waitKey(0)

cv2.destroyAllWindows()

通过以上流程,我们可以快速实现对多张图像的人脸检测。

总结

Haar特征分类器是目标检测领域里一种经典且有效的方法。利用OpenCV,我们不仅可以方便地加载和使用预训练分类器,还可以灵活地应用于各种图像处理任务。通过Haar特征分类器的学习,我们也为后续的HOG特征与SVM方法奠定了基础,在下一篇文章中,我们将更深入地探讨这一主题。

希望本篇对你了解Haar特征分类器有所帮助,接下来我们将进入“目标检测之HOG特征与SVM”的讨论。

分享转发

14 目标检测之HOG特征与SVM

在前一篇中,我们探讨了Haar特征分类器在目标检测中的应用,了解了其工作原理及如何进行训练和检测。在这一篇中,我们将深入研究HOG特征(Histogram of Oriented Gradients)与SVM(支持向量机)的结合在目标检测中的应用。

HOG特征简介

HOG特征是一种有效的物体检测特征,尤其在行人检测上表现突出。HOG特征的基本思想是利用局部区域的梯度方向和幅度来描述目标的形状和特征。具体步骤如下:

  1. 预处理图像:通常会将图像转换为灰度图,并对其进行归一化处理。
  2. 计算梯度:通过Sobel算子计算图像的水平方向和垂直方向的梯度。
  3. 细分区域:将图像划分为小的单元格(例如,8x8像素),在每个单元格内计算梯度的方向直方图。
  4. 形成HOG描述符:将相邻的单元格组合成一个“块”,对块内的HOG特征进行归一化,形成最终的HOG特征描述符。

这样,HOG特征能够提供一个非常好的目标区域的描述。

SVM介绍

SVM(支持向量机)是一种监督学习模型,用于分类和回归。在目标检测中,我们使用SVM来分类通过HOG特征提取的样本。SVM尝试找到一个最佳的超平面,来分隔不同类别的数据点,并使用“支持向量”来定义这个超平面。

HOG特征与SVM结合的步骤

1. 数据准备

我们需要收集一个包含目标和非目标图像的数据集。例如,使用行人检测时,可以从公共数据集中获取带有行人的图像以及不带行人的图像。

2. 特征提取

使用OpenCV的HOGDescriptor类提取图像中的HOG特征。

1
2
3
4
5
6
7
8
9
10
import cv2

# 初始化HOG描述符
hog = cv2.HOGDescriptor()

# 读取图像
image = cv2.imread('person.jpg')

# 计算HOG特征
hog_features = hog.compute(image)

3. 创建训练数据

将提取的HOG特征与相应的标签(如行人:1,非行人:0)结合,形成训练数据集。

1
2
3
4
5
import numpy as np

# 假设我们有多个图像的HOG特征和标签
features = np.array([hog.compute(cv2.imread(img)) for img in image_paths])
labels = np.array([1 if 'person' in img else 0 for img in image_paths])

4. 训练SVM模型

使用OpenCV的ml.SVM进行模型训练。

1
2
3
4
5
6
7
8
# 创建SVM分类器
svm = cv2.ml.SVM_create()
svm.setKernel(cv2.ml.SVM_RBF) # RBF核
svm.setType(cv2.ml.SVM_C_SVC) # 分类类型
svm.setC(1) # 惩罚参数

# 训练SVM
svm.train(np.float32(features), cv2.ml.ROW_SAMPLE, np.int32(labels))

5. 模型评估

通过交叉验证或其他评价方法评估模型的性能,调整超参数以提高准确性。

6. 目标检测

对新图像进行检测时,首先提取HOG特征,然后使用训练好的SVM模型进行分类。

1
2
3
4
5
6
7
8
9
10
# 读取新图像并提取HOG特征
new_image = cv2.imread('test_image.jpg')
new_hog_features = hog.compute(new_image)

# 使用SVM进行预测
result = svm.predict(np.float32(new_hog_features.reshape(1, -1)))[1]
if result[0][0] == 1:
print("检测到目标!")
else:
print("未检测到目标。")

结果展示与总结

通过上述步骤,我们成功实现了使用HOG特征SVM进行目标检测。此方法在许多应用中具有良好的性能,尤其是在人脸识别、行人检测等领域。

在下一篇中,我们将探讨更先进的目标检测技术,包括YOLOSSD,进一步增强我们的目标检测能力。

希望这一篇教程能够帮助你理解HOG特征和SVM的基本概念与应用实践。通过结合具体的案例和代码,我们能够更好地掌握这一技术的实现。

分享转发

15 目标检测之YOLO与SSD

目标检测是计算机视觉中的一个重要任务,涉及到在图片或视频中识别和定位多个对象。近年来,随着深度学习技术的快速发展,基于深度学习的目标检测方法得到了广泛的应用。其中,YOLO(You Only Look Once)和 SSD(Single Shot MultiBox Detector)是两个非常流行且高效的方法。在本篇教程中,我们将详细探讨这两种检测算法,包括它们的原理、实现以及如何在 OpenCV 中使用它们。

YOLO(You Only Look Once)

YOLO 是一种基于卷积神经网络(CNN)的实时目标检测系统。这种方法的主要思想是将整个图像作为网络的输入,并在单个前向传播中同时进行目标的定位和分类。与传统的目标检测方法不同,YOLO 将检测问题转化为回归问题。

YOLO 的工作原理

YOLO 将输入图像划分为 S x S 的网格,每个网格负责预测一个边界框和对应的类概率。每个网格单元输出的信息包括:

  • 边界框的中心坐标 $(x, y)$
  • 边界框的宽度和高度 $(w, h)$
  • 某个类的置信度 $P(Class)$

最终,YOLO 会通过 Non-Maximum Suppression(NMS)来整理重叠的边界框,保留最高置信度的边框,得到最终的检测结果。

在 OpenCV 中实现 YOLO

下面是如何在 OpenCV 中使用 YOLO 进行目标检测的简单示例。

1. 下载 YOLO 模型

首先,你需要下载 YOLO 的权重和配置文件。你可以从 YOLO 官方 GitHub 页面下载:

  • yolov3.weights
  • yolov3.cfg
  • coco.names(类名文件)

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

# 加载 YOLO 模型
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]

# 加载类名
with open("coco.names", "r") as f:
classes = [line.strip() for line in f.readlines()]

# 加载图片
img = cv2.imread("image.jpg")
height, width, _ = img.shape

# 创建输入Blob
blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)

# 进行前向传播
outs = net.forward(output_layers)

# 解析输出
boxes = []
confidences = []
class_ids = []

for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5: # 设置阈值
# 获取边界框坐标
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)

# 边界框的左上角坐标
x = int(center_x - w / 2)
y = int(center_y - h / 2)

boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)

# 应用非极大抑制
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

# 绘制检测结果
for i in range(len(boxes)):
if i in indexes:
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
confidence = confidences[i]
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(img, f"{label} {round(confidence, 2)}", (x, y + 30), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 3)

# 显示结果
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上面的代码中,我们使用 OpenCV 的 dnn 模块来加载 YOLO 模型,进行目标检测并绘制出检测到的边界框和标签。

SSD(Single Shot MultiBox Detector)

SSD 是另一种流行的目标检测方法,能够以较高的速度和准确性进行检测。与 YOLO 相似,SSD 也将目标检测问题视为一个回归问题。

SSD 的工作原理

SSD 在不同的特征图上进行检测,并使用默认边界框进行预测。它通过在多层特征图上进行卷积操作,提取多尺度信息以提高检测效果。SSD 可以在添加较少的计算负担的情况下,达到较高的召回率和精度。

在 OpenCV 中实现 SSD

与 YOLO 类似,你同样可以在 OpenCV 中使用 SSD 模型进行目标检测。在运行 SSD 的代码之前,请确保你已经下载了对应的模型文件,比如 SSD MobileNet 或其他类型的 SSD 模型。

代码示例

import cv2

# 加载 SSD 模型
net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "mobilenet.caffemodel")

# 加载图片
img = cv2.imread("image.jpg")
height, width, _ = img.shape

# 创建输入Blob
blob = cv2.dnn.blobFromImage(img, 0.007843, (300, 300), 127.5)
net.setInput(blob)

# 进行前向传播
detections = net.forward()

# 解析输出
for i in range(detections.shape[2]):
    confidence = detections[0, 0, i, 2]
    if confidence > 0.5:  # 设置阈值
        class_id = int(detections[0, 0, i, 1])
        box = detections[0, 0, i, 3:7] * np.array([width, height, width, height])
        (startX, startY, endX, endY) = box.astype("int")

        # 绘制检测结果
        label

分享转发

16 视频处理之读取与处理视频流

在上篇教程中,我们讨论了目标检测的两个流行算法:YOLO和SSD。目标检测是计算机视觉中的一个重要应用,它使我们能够识别图像中的对象。然而,当我们需要处理动态视频流时,除了对象检测,还需要了解如何能够高效处理视频流。在本篇文章中,我们将深入探讨OpenCV如何读取和处理视频流。

一、读取视频流

在OpenCV中,可以使用cv2.VideoCapture类来读取视频流。该类可以处理来自文件、摄像头或其他视频源的输入。我们将以从摄像头读取视频流为例。

1. 从摄像头读取视频流

以下是一个简单的示例,演示如何打开摄像头并读取视频流:

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
import cv2

# 打开摄像头,0表示默认摄像头
cap = cv2.VideoCapture(0)

# 检查摄像头是否打开成功
if not cap.isOpened():
print("无法打开摄像头")
exit()

while True:
# 逐帧捕捉
ret, frame = cap.read()
if not ret:
print("无法获取视频帧")
break

# 显示视频帧
cv2.imshow('Camera', frame)

# 按'q'键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 释放摄像头资源
cap.release()
cv2.destroyAllWindows()

在上面的代码中,cv2.VideoCapture(0)用于打开默认摄像头。通过循环读取每一帧视频并使用cv2.imshow显示在窗口中,我们可以实时查看摄像头录制的视频流。

2. 从视频文件读取

如果希望从视频文件中读取,可以将cv2.VideoCapture的参数更改为视频文件的路径:

1
cap = cv2.VideoCapture('video.mp4')

3. 获取视频属性

使用cap.get()方法可以获取视频的属性,如帧率、宽度和高度等:

1
2
3
4
5
6
7
8
# 获取视频的帧率
fps = cap.get(cv2.CAP_PROP_FPS)
# 获取视频的宽度
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
# 获取视频的高度
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)

print(f'帧率: {fps}, 宽度: {width}, 高度: {height}')

二、处理视频流

在读取到视频流后,我们可以对每一帧应用多种图像处理技术,例如滤波、边缘检测、特征提取等。在这一部分,我们将介绍如何对视频流进行简单的处理。

1. 灰度处理

将每一帧转换为灰度图像是视频处理中的常见操作:

1
2
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('Gray Camera', gray_frame)

2. 边缘检测

使用Canny算法进行边缘检测:

1
2
edges = cv2.Canny(gray_frame, 100, 200)
cv2.imshow('Edges', edges)

3. 结合处理实例

将矩形框绘制到检测到的对象上,我们将演示如何结合上述处理进行简单的对象检测。例如,假设我们在视频流中要检测运动:

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
# 用于存储前一帧
prev_frame = None

while True:
ret, frame = cap.read()
if not ret:
break

# 转换为灰度图像
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# 计算前一帧与当前帧之间的差异
if prev_frame is not None:
diff_frame = cv2.absdiff(prev_frame, gray_frame)
_, thresh_frame = cv2.threshold(diff_frame, 30, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh_frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 在检测到的物体周围绘制矩形框
for contour in contours:
if cv2.contourArea(contour) < 500:
continue
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

cv2.imshow('Motion Detection', frame)

# 更新前一帧
prev_frame = gray_frame

if cv2.waitKey(1) & 0xFF == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

在这个示例中,我们定期对当前帧和前一帧之间的差异进行计算,并绘制出运动的边界框。这种简单的运动检测方法为之后更复杂的对象跟踪算法奠定了基础。

结论

在这一篇教程中,我们学习了如何使用OpenCV读取和处理视频流,不论是来自摄像头还是视频文件。我们展示了如何提取视频属性和进行基础图像处理。这些基本操作为后续的深入对象跟踪打下了基础。在下一篇文章中,我们将介绍如何在视频中实现对象跟踪,进一步提升我们的计算机视觉应用能力。

分享转发

17 视频处理之视频对象跟踪

在前一篇中,我们讨论了如何读取与处理视频流。现在,我们将深入研究如何在视频中进行对象跟踪。对象跟踪是计算机视觉中的一个重要任务,广泛应用于监控、自动驾驶、虚拟现实等领域。在本篇中,我们将通过案例和代码,展示如何使用 OpenCV 实现对象跟踪。

对象跟踪的基本原理

对象跟踪的主要目标是从序列帧中持续检测特定的对象,并跟踪其位置。通常,跟踪算法可以分为两类:

  1. 基于检测的跟踪:在每一帧中,使用对象检测算法检测对象,并将泰耐克位置进行匹配。
  2. 基于模型的跟踪:在第一帧中建立模型,然后基于运动模型预测对象的位置。

为了实现对象跟踪,我们将重点使用 OpenCV中的cv2.Tracker类,这提供了几种不同的跟踪算法,比如 KCF、MIL、CSRT 和 MOSSE。

使用 OpenCV 实现对象跟踪

接下来,我们将实现一个简单的对象跟踪案例。假设我们想在视频中跟踪一个移动的球体。

环境准备

首先,请确保安装了 OpenCV 库。如果您还没有安装,可以使用以下命令进行安装:

1
pip install opencv-python opencv-contrib-python

案例代码

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
import cv2

# 读取视频流
cap = cv2.VideoCapture('video.mp4')

# 读取第一帧
ret, frame = cap.read()

# 选择跟踪的对象 (手动选择)
bbox = cv2.selectROI("Tracking", frame, fromCenter=False, showCrosshair=True)

# 创建 KCF 跟踪器
tracker = cv2.TrackerKCF_create()
tracker.init(frame, bbox)

while True:
# 读取新帧
ret, frame = cap.read()
if not ret:
break

# 更新跟踪器
success, bbox = tracker.update(frame)

# 画出跟踪框
if success:
(x, y, w, h) = [int(v) for v in bbox]
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
else:
cv2.putText(frame, "Lost", (100, 100), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)

# 显示结果
cv2.imshow("Tracking", frame)

# 按 'q' 退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 清理资源
cap.release()
cv2.destroyAllWindows()

代码解释

  1. 视频捕捉:使用cv2.VideoCapture读取视频。可以替换 'video.mp4' 为您自己的视频路径。
  2. 选择 ROI(感兴趣区域):使用cv2.selectROI手动选择我们想要跟踪的对象。系统会在视频上弹出一个窗口来让您拖动鼠标创建框。
  3. 创建跟踪器:使用cv2.TrackerKCF_create()创建 KCF 跟踪器并初始化。
  4. 更新和显示:在循环中持续读取新帧,更新跟踪器,并在跟踪到的对象周围画出矩形框。如果跟踪丢失,屏幕上会显示“Lost”。
  5. 资源释放:按 ‘q’ 键退出,释放视频资源和关闭所有 OpenCV 窗口。

总结

在视频处理之对象跟踪中,我们通过创建一个简单的应用程序,实现了使用 OpenCV 跟踪一个移动对象的功能。这是许多计算机视觉应用的基础。接下来的一篇中,我们将探索更为复杂的“视频分析与处理”,进一步提升我们的视觉处理能力。希望您从中受益,期待在下篇文章中与您再见!

分享转发

18 视频处理之视频分析与处理

在前一篇文章中,我们探讨了视频对象跟踪的基本概念与实现方法。本篇将重点关注视频分析与处理的技术与应用,旨在帮助读者理解如何在视频流中提取有价值的信息,以及如何对视频进行各种处理操作。

视频分析概述

视频分析是从输入的视频流中提取关键信息的过程。它可以包括对象识别、动作识别、行为分析等多种任务。视频分析通常是实现智能监控、交通流量分析以及体育赛事分析等应用的核心技术。

常见的视频分析任务

  1. 对象检测:识别并定位视频帧中的特定对象。
  2. 行为识别:分析对象在视频中的行为模式。
  3. 场景理解:对视频中的场景进行语义分割和理解。

OpenCV中的视频分析工具

OpenCV为视频分析提供了一系列强大的工具和算法。以下是一些常用的功能:

  • 背景减除:识别视频流中的动态对象。
  • 特征提取和匹配:获取关键点并进行匹配分析。
  • 光流法:计算对象间相对运动。

背景减除

背景减除是一种常见的视频分析技术,用于在固定背景下识别动态对象。OpenCV中提供了多种背景减除算法,如MOG2KNN

以下是一个使用MOG2进行背景减除的示例代码:

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
import cv2

# 创建视频捕捉对象
cap = cv2.VideoCapture('video.mp4')

# 创建背景减除器
backSub = cv2.createBackgroundSubtractorMOG2()

while True:
ret, frame = cap.read()
if not ret:
break

# 应用背景减除
fgMask = backSub.apply(frame)

# 显示结果
cv2.imshow('Frame', frame)
cv2.imshow('FG Mask', fgMask)

keyboard = cv2.waitKey(30)
if keyboard == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

特征提取与匹配

特征提取技术被广泛用于视频分析中,尤其是在对象检测与识别中。OpenCV提供了多种特征检测算法,例如ORBSIFTSURF。下面是基于ORB算法进行特征提取与匹配的代码样例:

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
import cv2

# 读取参考图像和视频流
img1 = cv2.imread('object.jpg', 0) # 参考图像
cap = cv2.VideoCapture('video.mp4')

# 创建ORB检测器
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)

while True:
ret, frame = cap.read()
if not ret:
break

# 检测并计算特征
kp2, des2 = orb.detectAndCompute(frame, None)

# 使用BFMatcher进行特征匹配
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)

# 绘制匹配结果
frame_matches = cv2.drawMatches(img1, kp1, frame, kp2, matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

cv2.imshow('Matches', frame_matches)

keyboard = cv2.waitKey(30)
if keyboard == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

光流法

光流法用于计算图像序列中像素的运动。它非常适合用于跟踪移动对象。OpenCV提供calcOpticalFlowFarneback函数来实现光流计算。

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
import cv2

# 创建视频捕捉对象
cap = cv2.VideoCapture('video.mp4')

# 读取第一帧
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 获取初始角点
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)

# 创建掩膜图像用于绘制光流
mask = np.zeros_like(old_frame)

while True:
ret, frame = cap.read()
if not ret:
break

frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# 计算光流
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None)

# 选择确认为好的点
good_new = p1[st==1]
good_old = p0[st==1]

# 绘制光流
for i, (new, old) in enumerate(zip(good_new, good_old)):
a, b = new.ravel()
c, d = old.ravel()
mask = cv2.line(mask, (a, b), (c, d), (0, 255, 0), 2)
frame = cv2.circle(frame, (a, b), 5, (0, 0, 255), -1)

img = cv2.add(frame, mask)
cv2.imshow('Optical Flow', img)

# 更新新的旧帧和角点
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1, 1, 2)

keyboard = cv2.waitKey(30)
if keyboard == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

总结

在本篇中,我们讨论了视频分析的基本概念和常用技术,包括背景减除特征提取与匹配以及光流法。这些工具不仅适用于简单的对象跟踪任务,也为复杂的视频分析奠定了基础。

在下一篇文章中,我们将深入探讨如何与深度学习框架集成,以实现更复杂的视觉任务,如目标检测和分类。请继续关注我们的系列教程!

分享转发

19 深度学习与OpenCV之深度学习框架集成

在上一篇中,我们讨论了视频分析与处理的相关技术,了解了如何使用 OpenCV 进行视频的捕捉、处理和分析。在本篇中,我们将深入探讨如何将深度学习框架与 OpenCV 集成,以便您可以充分利用强大的深度学习工具来处理和分析图像和视频数据。

深度学习框架简介

在使用 OpenCV 进行深度学习任务时,您通常需要集成一个深度学习框架,例如 TensorFlowKerasPyTorch。这些框架提供了构建和训练深度学习模型的高级工具,而 OpenCV 则专注于图像和视频的处理。

神经网络的基本概念

一般来说,深度学习模型是通过神经网络来构建的。神经网络由多个层组成,包括输入层、隐藏层和输出层。每一层包含多个神经元,神经元之间的连接通过权重进行调节。

OpenCV中的深度学习模块

OpenCV 3.3 版本开始,OpenCV 提供了 dnn 模块用于深度学习模型的加载和推断。该模块支持多种深度学习框架的模型,包括 Caffe、TensorFlow 和 PyTorch 等。

安装OpenCV

首先,确保您安装了支持深度学习模块的 OpenCV。可以使用以下命令进行安装:

1
pip install opencv-python opencv-python-headless

加载深度学习模型

在本节中,我们将展示如何加载一个已训练的深度学习模型。这里我们将以一个使用 Caffe 训练的对象检测模型为例。

1. 确保模型文件可用

假设您有以下两个文件:

  • model.prototxt - 模型结构定义
  • model.caffemodel - 已训练的模型权重

2. 加载模型

借助 OpenCVdnn 模块,您可以使用以下代码加载模型:

1
2
3
4
import cv2

# 加载模型
net = cv2.dnn.readNetFromCaffe('model.prototxt', 'model.caffemodel')

3. 准备输入数据

为模型准备输入图像,通常需要对其进行预处理,例如 resize 和 normalization:

1
2
3
# 读取图像
image = cv2.imread('image.jpg')
blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size=(300, 300), swapRB=True, crop=False)

4. 推断

将处理后的图像输入到模型中进行前向传播以获得输出:

1
2
3
4
5
# 设置输入
net.setInput(blob)

# 进行推断
detections = net.forward()

可视化输出结果

获得推断结果后,您可能希望可视化检测结果。例如,将检测到的对象框绘制在原始图像上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.5: # 设定置信度阈值
idx = int(detections[0, 0, i, 1]) # 获取检测到的类别
box = detections[0, 0, i, 3:7] * np.array([image.shape[1], image.shape[0], image.shape[1], image.shape[0]])
(startX, startY, endX, endY) = box.astype("int")
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2)
text = f"Class: {idx}, Confidence: {confidence:.2f}"
cv2.putText(image, text, (startX, startY - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

# 显示结果
cv2.imshow("Output", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

小结

在这一部分中,我们学习了如何将深度学习框架与 OpenCV 集成,通过使用 OpenCVdnn 模块加载和推断深度学习模型。具体示例演示了如何对图像进行处理和可视化检测结果。

接下来的一篇文章我们将聚焦于如何使用学到的深度学习模型进行推断,让我们一同深入探索深度学习在实际应用中的魅力。

分享转发

20 深度学习与OpenCV之使用深度学习模型进行推断

在上一篇中,我们探讨了如何将深度学习框架与OpenCV进行集成,以便利用深度学习模型的强大能力。而在本篇中,我们将专注于如何使用已经训练好的深度学习模型进行推断,具体来说,就是如何利用OpenCV加载并进行推理,处理输入数据,并获取输出结果。

知识准备

在开始之前,确保你已经掌握以下内容:

  1. 深度学习的基本概念
  2. OpenCV库的基本使用
  3. 深度学习模型的训练与保存

在实际应用中,常见的深度学习框架如TensorFlow、PyTorch等都可以导出一个可供OpenCV使用的格式,比如.onnx.pb文件。

加载深度学习模型

在OpenCV中,我们可以使用cv2.dnn模块来加载和推断深度学习模型。以下是加载模型的基本步骤:

1
2
3
4
import cv2

# 加载模型
model = cv2.dnn.readNetFromONNX('your_model.onnx')

在这个例子中,我们使用readNetFromONNX方法来加载一个ONNX格式的模型。类似地,OpenCV还支持从Caffe、TensorFlow和Torch等格式加载模型。

输入数据的预处理

在推断之前,我们需要对输入数据进行适当的预处理。这通常包括缩放、归一化和调换通道顺序等。以下是一个常见的图像输入预处理过程:

1
2
3
4
5
image = cv2.imread('input_image.jpg')
blob = cv2.dnn.blobFromImage(image, scalefactor=1/255.0, size=(640, 640), swapRB=True)

# 设置输入
model.setInput(blob)

在上面的代码中:

  • 使用cv2.dnn.blobFromImage将输入图像转换为Blob对象。
  • scalefactor参数用于将图像像素值归一化到0到1之间。
  • size参数指定输入大小,需与模型的输入要求相匹配。
  • swapRB参数用于交换红色和蓝色通道,因为深度学习模型通常接受BGR顺序的图像。

进行推断

一旦输入数据准备好,我们就可以进行推断。使用forward方法来获取模型的输出:

1
output = model.forward()

output将包含模型的推理结果,通常是一些特征图或预测结果,具体取决于训练时的目标。

处理推理结果

根据模型的类型,处理输出的方式也会有所不同。假设我们正在进行一个目标检测任务,output可能是一个包含边框和类别信息的张量。接下来是一个简单的后处理过程,以提取检测结果:

1
2
3
4
5
6
7
8
for detection in output[0, 0]:
confidence = detection[2]
if confidence > 0.5:
x1 = int(detection[3] * image.shape[1])
y1 = int(detection[4] * image.shape[0])
x2 = int(detection[5] * image.shape[1])
y2 = int(detection[6] * image.shape[0])
cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 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
import cv2

# 加载模型
model = cv2.dnn.readNetFromONNX('your_model.onnx')

# 读取并处理图像
image = cv2.imread('input_image.jpg')
blob = cv2.dnn.blobFromImage(image, scalefactor=1/255.0, size=(640, 640), swapRB=True)

# 推断
model.setInput(blob)
output = model.forward()

# 处理输出
for detection in output[0, 0]:
confidence = detection[2]
if confidence > 0.5:
x1 = int(detection[3] * image.shape[1])
y1 = int(detection[4] * image.shape[0])
x2 = int(detection[5] * image.shape[1])
y2 = int(detection[6] * image.shape[0])
cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 2)

# 显示结果
cv2.imshow('Output', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

总结

在本篇中,我们学习了如何使用OpenCV进行深度学习模型的推断,包括如何加载模型、处理输入数据、执行推断并分析输出结果。这些步骤对于在实际应用中高效利用深度学习模型至关重要。

下一篇将深入探讨如何根据特定需求训练自定义深度学习模型,以更好地满足实际应用场景的要求。请继续关注!

分享转发

21 深度学习与 OpenCV 之训练自定义模型

在上一篇中,我们讨论了如何使用预训练的深度学习模型进行推断,此次我们将聚焦于如何使用 OpenCV 训练自定义模型。训练自定义模型允许我们针对特定任务优化模型性能。在深度学习的世界中,能够根据自己的需求创建和优化模型是一项重要的技能。本文将详细介绍训练自定义模型的步骤,并结合一个具体的案例,使这一过程更加清晰明了。

准备工作

数据集收集与预处理

在训练自定义模型之前,首先需要一个适合的训练数据集。假设我们的任务是对手写数字进行分类,我们可以使用“MNIST”数据集。MNIST 数据集包含 60,000 个手写数字的训练样本和 10,000 个测试样本。

数据预处理步骤:

  1. 下载数据集:

    可以从 MNIST官网 下载数据集,或者使用 Python 库直接加载。

    1
    2
    from keras.datasets import mnist
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
  2. 数据归一化:

    将图像数据归一化到 [0, 1] 范围内,有助于模型更有效地训练。

    1
    2
    x_train = x_train.astype('float32') / 255.0
    x_test = x_test.astype('float32') / 255.0
  3. 数据形状调整:

    OpenCV 和 Keras 常用的输入形状是 (样本数量, 高, 宽, 通道数),我们需要将数据调整为适当的形状。

    1
    2
    x_train = x_train.reshape(-1, 28, 28, 1)
    x_test = x_test.reshape(-1, 28, 28, 1)

创建模型

我们使用 Keras 构建一个简单的卷积神经网络(CNN)作为我们的自定义模型。该模型旨在识别手写数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

训练模型

模型构建完成后,我们可以开始训练模型。训练过程中会调整模型参数,以便更好地适应训练数据。

1
model.fit(x_train, y_train, epochs=10, batch_size=200, validation_split=0.2)
  • epochs:训练的轮数。
  • batch_size:每个训练步骤使用多少样本。

保存模型

训练完毕后,我们需要保存模型,以便后续使用。OpenCV 支持将 Keras 模型转换为其可用格式。

1
model.save('mnist_model.h5')

使用 OpenCV 进行推断

我们可以使用 OpenCV 加载并使用已经训练好的模型进行预测。首先,需将 Keras 模型转换为 OpenCV 使用的格式,使用以下代码:

1
2
3
4
5
6
7
8
9
10
import cv2
from keras.models import load_model

# 加载训练好的 Keras 模型
model = load_model('mnist_model.h5')

# 这里是将 Keras 模型转换为 OpenCV DNN 格式(后续可优化)
def keras_to_opencv(model_path):
net = cv2.dnn.readNetFromTensorflow(model_path)
return net

通过 OpenCV 进行推断,您可以处理图像并分类手写数字:

1
2
3
4
5
6
7
8
9
image = cv2.imread('手写数字样本.png', cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image, (28, 28))
image = image.astype('float32') / 255.0
image = image.reshape(-1, 28, 28, 1)

# 使用模型预测
pred = model.predict(image)
predicted_digit = np.argmax(pred)
print("预测的数字是: ", predicted_digit)

总结

通过本篇教程,我们学习了如何使用 OpenCV 训练自定义模型,并对模型进行了评估和推断。我们使用了经典的手写数字识别任务作为例子,展示了从数据收集到模型使用的完整流程。在下一篇中,我们将探讨一个实践项目——人脸识别,进一步拓展深度学习和 OpenCV 的应用。

通过这个系列教程,您已经掌握了 OpenCV 与深度学习的基本结合,希望在未来的项目中,您能熟练应用这些知识!

分享转发

22 人脸识别

在本篇教程中,我们将运用OpenCV进行一个实践项目:人脸识别。继上篇关于深度学习与OpenCV的内容后,我们将以深度学习模型为基础,构建一个能够实时识别并标记人脸的系统。这一项目不仅能够帮助你巩固深度学习与OpenCV的结合使用,也为后续的车牌识别项目打下基础。

项目背景

人脸识别是计算机视觉领域中的一个重要应用,它涉及到如何在人群中识别出个体的面孔。随着深度学习技术的发展,使用卷积神经网络(CNN)进行人脸识别已成为一种主流的方法。

准备工作

在开始之前,确保你已经安装了OpenCV以及必要的深度学习库。以下是安装所需包的命令:

1
pip install numpy opencv-python opencv-python-headless

如果你使用的是深度学习模型,例如 KerasTensorFlow,请确保这些库也已安装。

数据准备

对于项目,我们将使用已经训练好的模型进行人脸识别。可以使用 OpenCV 提供的 Haar Cascade 或者预训练的深度学习模型(如 FaceNet)。在这里,我们简单介绍如何使用 Haar Cascade 进行人脸检测。

我们需要准备一个 Haar Cascade 分类器文件,通常可以在 OpenCV 的安装目录中找到,例如:

1
opencv/data/haarcascades/haarcascade_frontalface_default.xml

代码实现

以下是人脸识别的基本代码示例:

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
import cv2

# 加载Haar Cascade分类器
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# 开启视频捕捉
cap = cv2.VideoCapture(0)

while True:
# 捕获视频中每一帧
ret, frame = cap.read()
if not ret:
break

# 将视频帧转换为灰度图
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# 检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

# 在检测到的人脸周围绘制矩形
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)

# 显示结果
cv2.imshow('Face Detection', frame)

# 按'q'键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 释放视频捕捉对象
cap.release()
cv2.destroyAllWindows()

代码解析

  1. 加载分类器: 首先,我们加载 Haar Cascade 分类器,这个分类器是一种基于特征的分类器,用于实时的人脸检测。

  2. 获取视频流: 使用 cv2.VideoCapture(0) 开启摄像头进行实时视频捕捉。

  3. 灰度转换: 使用 cv2.cvtColor 将每一帧图像转换为灰度图,以提高检测的效率。

  4. 人脸检测: 使用 detectMultiScale 方法检测人脸,并返回人脸的坐标和尺寸。

  5. 绘制矩形框: 针对检测到的人脸,在图像上绘制矩形框进行标记。

  6. 显示图像: 使用 cv2.imshow 来显示实时检测到的人脸视频。

扩展与改进

以上代码是一个基本的框架。可以进行一些扩展和改进,例如:

  • 集成深度学习模型: 结合深度学习框架,如 TensorFlowPyTorch,使用更高级的网络模型进行准确的人脸识别。
  • 人脸比对: 实现功能,允许用户添加他们自己的面孔,并在实时视频中与已知的人脸进行比对。
  • 识别多个特征: 除了人脸,还可以添加对眼睛、嘴巴等其他面部特征的实时识别。

结束语

本篇教程展示了如何使用OpenCV进行基础人脸识别项目。它为后面的车牌识别项目奠定了基础,两个项目虽然各自独立,但在计算机视觉和深度学习的应用上有很多相似之处。通过本次实践,你应该对如何搭建一个基本的人脸识别系统有了更深的理解。

在下一篇中,我们将探索另一项有趣且具有实际应用的项目:车牌识别。敬请期待!

分享转发

23 车牌识别

在前一篇文章中,我们探讨了人脸识别的基本原理和实现方法。本篇文章,我们将重点关注一个实用的计算机视觉项目——车牌识别。车牌识别是一项重要的应用,广泛用于交通监控、停车场管理和车辆追踪等场景。

项目目标

我们将实现一个简单的车牌识别系统,目标是从图片中自动检测车辆的车牌位置,并提取车牌上的字符信息。实现过程中,我们将使用 OpenCV 进行图像处理,并结合 Tesseract OCR 进行文字识别。

项目准备

在开始之前,请确保您已安装以下库:

  1. OpenCV:用于图像处理。
  2. Tesseract:OCR 引擎,用于文字识别。
  3. Pillow:用于处理图像。

可以通过以下命令安装所需的库:

1
pip install opencv-python pillow pytesseract

此外,您还需要安装 Tesseract OCR 引擎,并确保它的可执行文件路径已添加到系统环境变量中。

步骤一:图像预处理

首先,我们需要读取输入图像并对其进行预处理。这包括将图像转换为灰度图,应用 Gaussian Blur 以减少噪声,并进行边缘检测。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import cv2

# 读取图像
image = cv2.imread("car.jpg")

# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 高斯模糊
blurred = cv2.GaussianBlur(gray, (5, 5), 0)

# Canny 边缘检测
edges = cv2.Canny(blurred, 100, 200)

# 显示处理后的结果
cv2.imshow("Edges", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

步骤二:车牌区域检测

接下来,我们需要识别车牌所在的区域。一般来说,车牌的形状是长方形,我们可以使用轮廓检测进行区域提取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 轮廓检测
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
plate_contours = []

for cnt in contours:
# 计算轮廓的面积,并过滤掉小轮廓
if cv2.contourArea(cnt) > 500:
x, y, w, h = cv2.boundingRect(cnt)
aspect_ratio = float(w) / h
# 筛选出长方形区域
if 2 < aspect_ratio < 5:
plate_contours.append((x, y, w, h))

# 在原图上绘制检测到的车牌区域
for (x, y, w, h) in plate_contours:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 显示原图上的车牌检测结果
cv2.imshow("Detected Plates", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

步骤三:字符识别

一旦我们从图像中提取到车牌区域,接下来就可以使用 Tesseract 进行字符识别。

1
2
3
4
5
6
7
8
9
10
import pytesseract

# 假设我们只对第一个车牌区域感兴趣
if plate_contours:
x, y, w, h = plate_contours[0]
plate_image = gray[y:y + h, x:x + w]

# 进行OCR识别
text = pytesseract.image_to_string(plate_image, config='--psm 8')
print(f"识别到的车牌号码: {text.strip()}")

实际案例

通过以上步骤,我们可以实现一个简单的车牌识别系统。以下是一个完整的代码示例,整合了所有部分:

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
import cv2
import pytesseract

# 读取图像
image = cv2.imread("car.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 100, 200)

contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
plate_contours = []

for cnt in contours:
if cv2.contourArea(cnt) > 500:
x, y, w, h = cv2.boundingRect(cnt)
aspect_ratio = float(w) / h
if 2 < aspect_ratio < 5:
plate_contours.append((x, y, w, h))

for (x, y, w, h) in plate_contours:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

if plate_contours:
x, y, w, h = plate_contours[0]
plate_image = gray[y:y + h, x:x + w]
text = pytesseract.image_to_string(plate_image, config='--psm 8')
print(f"识别到的车牌号码: {text.strip()}")

cv2.imshow("Detected Plates", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

总结

通过本次实践项目,我们成功实现了一个车牌识别系统。我们利用了 OpenCV 进行图像处理和轮廓检测,并结合 Tesseract OCR 进行文字识别。车牌识别在实际应用中十分广泛,能够为智能交通系统和车辆管理提供便利。

接下来,我们将进入项目验收阶段,在下一篇文章中将探讨如何进行实时物体检测,你准备好了吗?

分享转发

24 实践项目之实时物体检测

在本篇教程中,我们将深入探讨如何利用 OpenCV 实现实时物体检测。这是继我们上篇教程“车牌识别”之后的一个进阶项目,旨在让您对计算机视觉的应用有更深刻的理解。

项目概述

实时物体检测是计算机视觉中的一个重要领域,广泛应用于监控、自动驾驶和人机交互等场景。本项目将使用 OpenCV 和一个预训练的深度学习模型,您可以实时检测视频流中的物体(如行人、汽车和动物)。

环境准备

在开始之前,请确保您的系统中已安装 OpenCV 和 NumPy库。您可以通过以下命令安装:

1
pip install opencv-python numpy

此外,我们将使用一个常见的深度学习模型:YOLO(You Only Look Once)。请下载 YOLOv3 权重文件和配置文件,它们可以在 YOLO 的 GitHub 页面YOLO 官网 上找到。

实现步骤

  1. 加载 YOLO 模型

首先,我们需要加载 YOLO 模型的配置文件和权重文件。接下来的代码片段展示了如何完成这一步。

1
2
3
4
5
6
7
8
9
import cv2
import numpy as np

# 加载 YOLO 模型
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")

# 获取层名称
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
  1. 启动视频流

接着,我们将使用 OpenCV 提供的 VideoCapture 类来捕获实时视频流。

1
2
3
4
5
6
7
8
9
10
# 启动视频流
cap = cv2.VideoCapture(0) # 0 表示默认摄像头

while True:
# 读取视频流
ret, frame = cap.read()
if not ret:
break

height, width, _ = frame.shape
  1. 进行物体检测

在获取每一帧后,我们将通过 YOLO 模型进行物体检测。以下代码段展示了如何处理输入并获取检测结果。

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
# 预处理输入数据
blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
detections = net.forward(output_layers)

boxes = []
confidences = []
class_ids = []

# 遍历检测结果
for detection in detections:
for obj in detection:
scores = obj[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5: # 置信度阈值
center_x = int(obj[0] * width)
center_y = int(obj[1] * height)
w = int(obj[2] * width)
h = int(obj[3] * height)

# 计算边界框
x = int(center_x - w / 2)
y = int(center_y - h / 2)

boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
  1. 绘制检测边框

通过 NMS(非极大值抑制)去除重复检测后,我们将根据检测结果绘制边界框。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 应用非极大值抑制
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

# 绘制边界框
for i in range(len(boxes)):
if i in indexes:
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
color = (0, 255, 0)
cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
cv2.putText(frame, label, (x, y + 30), cv2.FONT_HERSHEY_PLAIN, 3, color, 3)

# 显示结果
cv2.imshow("Real-time Object Detection", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
  1. 结束程序并释放资源

最后,我们要确保在完成检测后,正确释放视频流和窗口资源。

1
2
cap.release()
cv2.destroyAllWindows()

总结

通过本项目,我们学习了如何使用 OpenCV 和 YOLO 模型实现实时物体检测。此技术可以作为许多更加复杂应用的基础,比如自动驾驶、智能监控和机器人导航等。

在准备下一篇教程之前,您可以尝试修改阈值或添加更多的特征,以增强检测的效果和性能。感谢您的阅读,期待在下一篇关于“基于 OpenCV 的智能监控系统”的教程中与您再次相见!

分享转发