小型人脸识别模型

这里主要是已经训练好的模型,并不是由我们自己进行训练。

我们在这里使用到了openCV和dlib两个软件包。

实现代码

import cv2
import dlib

# 加载 Dlib 的人脸检测器
detector = dlib.get_frontal_face_detector()

# 打开摄像头(默认摄像头,如果有多个摄像头可以修改参数)
cap = cv2.VideoCapture(0)

while True:
    # 读取一帧
    ret, frame = cap.read()

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

    # 在帧中检测人脸
    faces = detector(gray)

    # 绘制矩形框标注检测到的人脸
    for face in faces:
        x, y, w, h = face.left(), face.top(), face.width(), face.height()
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)

    # 显示结果帧
    cv2.imshow('Detected Faces', frame)

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

# 释放摄像头并关闭所有窗口
cap.release()
cv2.destroyAllWindows()

很短哈哈哈哈哈哈,所以其实效果也不是太好,但是很适合新手入门看一看,学一学

代码解释

(1)读取一帧

        在OpenCV中,cap.read() 是用于从视频捕获设备(比如摄像头)中读取一帧图像的方法。这个方法返回两个值:

  1. ret(返回值):一个布尔值,表示是否成功读取了一帧图像。如果成功读取,retTrue;如果没有读取到帧,retFalse

  2. frame:表示从视频流中读取到的图像帧。如果 retTrueframe 就是包含当前图像的 NumPy 数组。

在下面的代码片段中:

ret, frame = cap.read()

  cap 是通过 cv2.VideoCapture() 打开的视频捕获对象。这一行代码实际上是尝试从摄像头中读取一帧图像,并将成功与否的结果存储在 ret 中,图像数据存储在 frame 中。接下来,你可以对 frame 进行处理或显示。

        通常,在视频捕获的循环中,会使用类似的结构来连续读取视频流中的帧,以便进行实时处理、显示或分析。


(2)转换为灰度图提升性能

        这行代码是将彩色图像(BGR格式)转换为灰度图像。在计算机视觉中,灰度图像是只包含亮度信息的图像,每个像素只有一个数值,表示灰度级别。

        具体来说,`cv2.cvtColor` 是 OpenCV 中的一个函数,用于进行颜色空间转换。在这里,它将彩色图像 `frame` 从BGR(蓝绿红)颜色空间转换为灰度颜色空间。

```python
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
```

- `frame`:彩色图像的NumPy数组。
- `cv2.COLOR_BGR2GRAY`:表示颜色转换的标志。它指示 `cv2.cvtColor` 将图像从BGR颜色空间转换为灰度颜色空间。

        在灰度图像中,每个像素只有一个灰度值,范围通常是0到255,其中0表示黑色,255表示白色。灰度图像通常用于简化图像处理任务,减少计算量,并且在一些任务中仍然保留了足够的信息。在人脸检测等任务中,通常使用灰度图像来提高算法的运行速度。

(3)检测灰度图中的人脸

        在这行代码中,`detector(gray)` 使用 Dlib 库中的人脸检测器来检测灰度图像中的人脸。具体来说,`detector` 是通过 `dlib.get_frontal_face_detector()` 获得的 Dlib 人脸检测器对象。

```python
faces = detector(gray)
```

- `gray`:灰度图像,通常是通过 `cv2.cvtColor` 转换得到的。
- `detector`:Dlib 的人脸检测器对象。

        `detector(gray)` 返回一个包含检测到的人脸位置信息的 Dlib rectangles 对象。这个对象包含了一个或多个矩形区域,每个矩形表示一个检测到的人脸的位置。

        在后续的代码中,通过遍历 `faces` 中的矩形,可以获取每个人脸的位置(左上角和右下角的坐标),然后可以在图像上绘制矩形框来标记检测到的人脸。例如:

```python
for face in faces:
    x, y, w, h = face.left(), face.top(), face.width(), face.height()
    cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
```

这样就可以在图像中标记出检测到的人脸的位置。

(4)绘制人脸矩形

`cv2.rectangle` 是 OpenCV 中用于在图像上绘制矩形的函数。以下是它的一般形式:

```python
cv2.rectangle(image, start_point, end_point, color, thickness)
```

- `image`:要绘制矩形的图像。
- `start_point`:矩形的左上角坐标。
- `end_point`:矩形的右下角坐标。
- `color`:矩形的颜色,通常是一个三元组 (B, G, R),表示蓝、绿、红通道的颜色值。
- `thickness`:矩形的边框厚度(如果为负值,表示填充矩形内部)。

```python
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
```

- `frame`:图像,这通常是摄像头捕获的图像。
- `(x, y)`:矩形左上角的坐标,这是人脸检测器返回的人脸位置矩形的左上角坐标。
- `(x+w, y+h)`:矩形右下角的坐标,这是人脸检测器返回的人脸位置矩形的右下角坐标。
- `(255, 0, 0)`:蓝色,表示绘制的矩形边框的颜色。
- `2`:矩形边框的厚度。

因此,这一行代码的作用是在图像上标记检测到的人脸位置,绘制一个蓝色的矩形框,边框宽度为2个像素。

但是记住了

在 OpenCV 中,颜色通常以 BGR 的顺序(蓝绿红)表示,与 RGB 不同。

(5)显示结果

`cv2.imshow` 是 OpenCV 中用于显示图像的函数。以下是它的一般形式:

```python
cv2.imshow(window_name, image)
```

- `window_name`:显示图像的窗口的名称。
- `image`:要显示的图像。

我们的代码中:

```python
cv2.imshow('Detected Faces', frame)
```

- `'Detected Faces'`:窗口的名称,可以自定义。
- `frame`:要显示的图像,通常是摄像头捕获的图像,经过人脸检测并标记后的结果。

这一行代码的作用是在名为 `'Detected Faces'` 的窗口中显示经过人脸检测并标记后的图像。这样,你就可以可视化地看到摄像头捕获的图像,并且在图像上标记了检测到的人脸的位置。

(6)程序退出

这部分代码是用于等待用户按下键盘上的 'q' 键来退出程序的逻辑。解释如下:

- `cv2.waitKey(1)`:等待键盘输入,参数表示等待时间(单位为毫秒)。如果设为 0,则表示持续等待用户输入。如果设为 1,则表示等待 1 毫秒。

- `& 0xFF`:这是为了兼容不同操作系统上键盘输入的处理。在某些系统上,`cv2.waitKey()` 的返回值包含更多信息,而使用 `& 0xFF` 可以获取最低的8位(一个字节)。

- `== ord('q')`:检查用户输入的键是否是 'q'。`ord()` 函数返回字符的 ASCII 值。

如果用户按下 'q' 键,上述条件就为真,循环就会被中断,程序退出。

这是一种简单的方法来实现通过按 'q' 键来退出图像显示或视频播放等循环的操作。

(7)最后释放资源

        在使用 OpenCV 处理摄像头捕获或显示图像时,`cap.release()``cv2.destroyAllWindows()` 这两行是用于释放资源的重要步骤。如果不执行这些步骤,可能会导致程序在退出时没有正确释放摄像头资源或关闭图像窗口。

具体解释如下:

- `cap.release()`:释放通过 `cv2.VideoCapture` 打开的摄像头。这是为了确保在程序退出时释放摄像头资源,以便其他应用程序可以使用它。

- `cv2.destroyAllWindows()`:关闭所有通过 OpenCV 创建的窗口。如果你使用了 `cv2.imshow` 显示图像,这是确保在程序退出时关闭图像窗口的方法。如果没有调用这个函数,可能会导致程序退出后图像窗口仍然保持打开状态。

        虽然在一些简单的程序中,可能会省略这两行而不出现问题,但最好在程序中明确地释放资源,以确保程序运行的健壮性。

结束了但是我还有活

如果你的CPU多线程很厉害的话可以采用多线程运行

import cv2
import dlib
import time
import threading

# 加载 Dlib 的人脸检测器
detector = dlib.get_frontal_face_detector()

# 打开摄像头(默认摄像头,如果有多个摄像头可以修改参数)
cap = cv2.VideoCapture(0)

# 计算帧率的变量
start_time = time.time()
frame_count = 0
update_interval = 0.1  # 更新帧率的时间间隔(秒)

# 帧率的全局变量
fps = 0

# 锁,用于确保线程安全
lock = threading.Lock()

# 函数:人脸检测
def face_detection(frame):
    global fps, frame_count, start_time
    # 将帧转换为灰度图
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 在帧中检测人脸
    faces = detector(gray)

    # 绘制矩形框标注检测到的人脸
    for face in faces:
        x, y, w, h = face.left(), face.top(), face.width(), face.height()
        cv2.rectangle(frame, (x, y), (x + w, y + h), (238, 238, 0), 1)

    # 计算帧率
    with lock:
        frame_count += 1
        elapsed_time = time.time() - start_time
        if elapsed_time >= update_interval:
            fps = frame_count / elapsed_time
            frame_count = 0
            start_time = time.time()

# 函数:显示帧率
def display_fps(frame):
    with lock:
        cv2.putText(frame, "FPS: {:.2f}".format(fps), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

# 线程函数:处理视频帧
def process_frames():
    while True:
        # 读取一帧
        ret, frame = cap.read()

        # 调用人脸检测函数
        face_detection(frame)

        # 调用显示帧率函数
        display_fps(frame)

        # 显示结果
        cv2.imshow('Detected Faces', frame)

        # 等待一段时间,确保图像显示
        cv2.waitKey(30)

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

# 创建线程
processing_thread = threading.Thread(target=process_frames)

# 启动线程
processing_thread.start()

# 等待线程结束
processing_thread.join()

# 释放摄像头并关闭所有窗口
cap.release()
cv2.destroyAllWindows()

结语

这次真结束了

拜拜ヾ( ̄▽ ̄)Bye~Bye~

你可能感兴趣的:(AI学习之路,Python之路,opencv,人工智能,计算机视觉,人机交互)