计算机系统应用教程网站

网站首页 > 技术文章 正文

Go 人脸识别教程

btikc 2025-01-09 10:48:06 技术文章 48 ℃ 0 评论

人脸识别的整个领域都是我喜欢阅读的内容。自己实施面部识别系统会让您听起来像是托尼·斯塔克,您可以将它们用于各种不同的项目,例如自动锁门,或为您的办公室构建监控系统,仅举几例。

在本教程中,我们将使用一些现有的库在 Go 中构建我们自己的、非常简单的基于人脸识别的系统。我们将从对静止图像进行简单的人脸识别开始,看看它是如何工作的,然后我们将对此进行扩展,以研究本迷你系列第 2 部分中视频源的实时人脸识别。

Kagami/go-face 包


作为本教程的基础,我们将使用包含 dlib 机器学习工具包的 kagami/go-face包!

注意 - Kagami 实际上写了关于他是如何编写这个包的。这绝对是一个有趣的阅读,你可以在这里找到它:https : //hackernoon.com/face-recognition-with-go-676a555b8a7e

dlib 工具包

Dlib 工具包是用 C++ 构建的,在人脸和对象识别/检测方面都令人难以置信。根据其文档,它在 Wild 基准测试中检测标记人脸的准确率约为 99.4%,这令人难以置信,这也是许多其他第三方库将其用作基础的原因。

注意 -我在之前的教程中介绍了 Dlib 工具包的 Python 库 - face_recognition。如果您想查看本教程的 Python 等价物,请看这里: Python 中的人脸识别简介

设置

我不会撒谎,启动并运行它比你的标准 Go 包更痛苦。您需要在您的机器上安装pkg-config和dlib。如果您在 MacOS 上运行,那么这是命令:

$ brew install pkg-config dlib
$ sed -i '' 's/^Libs: .*/& -lblas -llapack/' /usr/local/lib/pkgconfig/dlib-1.pc

入门

我们首先需要下载kagami/go-face可以使用以下go get命令完成的包:

$ go get -u github.com/Kagami/go-face

go-face-recognition在 GOPATH 目录中创建一个名为的新目录。在这个目录中创建一个名为 的新文件main.go,这是我们所有源代码将驻留的地方。

完成此操作后,您需要从TutorialEdge/go-face-recognition-tutorial 存储 库中的image/ 目录中 获取文件。最简单的方法是将 repo 克隆到另一个目录中,然后将图像目录复制到您当前的工作目录中:

$ git clone https://github.com/TutorialEdge/go-face-recognition-tutorial.git

一旦成功克隆,我们就有了.dat启动人脸识别程序所需的两个文件。您还应该看到其他.jpg文件的列表,其中包含一些漫威复仇者的面孔。

package main

import (
    "fmt"

    "github.com/Kagami/go-face"
)

const dataDir = "testdata"

func main() {
    fmt.Println("Facial Recognition System v0.01")

    rec, err := face.NewRecognizer(dataDir)
    if err != nil {
        fmt.Println("Cannot initialize recognizer")
    }
    defer rec.Close()

    fmt.Println("Recognizer Initialized")
}

好的,所以如果我们此时尝试运行我们的程序,我们应该在程序的输出中看到 Facial Recognition System v0.01和Recognizer Initialized。我们已经成功地设置了我们需要的一切,以便进行一些很酷的高级面部识别!

计算图片中的人脸

我们对这个包的第一个真正的测试将是测试我们是否可以准确地计算一张照片中的人脸数量。出于本教程的目的,我将使用这张照片:

正如你所看到的,没有什么特别的,只有托尼斯塔克孤独的脸。

因此,我们现在需要扩展我们现有的程序,以便能够分析该图像,然后计算该图像中的人脸数量:

package main

import (
    "fmt"
    "log"
    "path/filepath"

    "github.com/Kagami/go-face"
)

const dataDir = "testdata"

func main() {
    fmt.Println("Facial Recognition System v0.01")

    rec, err := face.NewRecognizer(dataDir)
    if err != nil {
        fmt.Println("Cannot initialize recognizer")
    }
    defer rec.Close()

    fmt.Println("Recognizer Initialized")

    // we create the path to our image with filepath.Join
    avengersImage := filepath.Join(dataDir, "tony-stark.jpg")

    // we then call RecognizeFile passing in the path
    // to our file to retrieve the number of faces and any
    // potential errors
    faces, err := rec.RecognizeFile(avengersImage)
    if err != nil {
        log.Fatalf("Can't recognize: %v", err)
    }
    // we print out the number of faces in our image
    fmt.Println("Number of Faces in Image: ", len(faces))

}

当我们运行它时,我们应该看到以下输出:

$ go run main.go
Facial Recognition System v0.01
Recognizer Initialized
Number of Faces in Image:  1

太棒了,我们已经能够分析图像并确定图像包含一个人的脸。让我们尝试一个更复杂的图像,其中包含更多复仇者联盟:

当我们更新第 24 行时:

avengersImage := filepath.Join(dataDir, "avengers-01.jpg")

并重新运行我们的程序,您应该看到我们的程序能够确定这个新图像中有 2 个人。

识别面孔:

太好了,所以我们能够计算图像中的面孔数量,现在如何实际确定这些人是谁?

为此,我们需要一些参考照片。例如,如果我们希望能够从照片中识别出托尼·斯塔克,我们需要标有他名字的示例照片。然后识别软件将能够分析照片中与他相似的面孔并将它们匹配在一起。

因此,让我们avengers-02.jpg将我们的图像作为 Tony Stark 的参考图像,然后看看我们是否可以识别此图像是否包含他的脸:

avengersImage := filepath.Join(dataDir, "avengers-02.jpeg")

faces, err := rec.RecognizeFile(avengersImage)
if err != nil {
    log.Fatalf("Can't recognize: %v", err)
}
fmt.Println("Number of Faces in Image: ", len(faces))

var samples []face.Descriptor
var avengers []int32
for i, f := range faces {
    samples = append(samples, f.Descriptor)
    // Each face is unique on that image so goes to its own category.
    avengers = append(avengers, int32(i))
}
// Name the categories, i.e. people on the image.
labels := []string{
    "Dr Strange",
    "Tony Stark",
    "Bruce Banner",
    "Wong",
}
// Pass samples to the recognizer.
rec.SetSamples(samples, avengers)

所以,在上面的代码中,我们已经按照从左到右的顺序遍历了所有的人脸,并用适当的名字标记了它们。然后,我们的识别系统可以使用这些参考样本来尝试对后续文件执行自己的面部识别。

让我们尝试使用我们现有的 Tony Stark 图像测试我们的识别系统,看看它是否能够根据它从avengers-02.jpeg文件生成的面部描述符来识别它:

// Now let's try to classify some not yet known image.
testTonyStark := filepath.Join(dataDir, "tony-stark.jpg")
tonyStark, err := rec.RecognizeSingleFile(testTonyStark)
if err != nil {
    log.Fatalf("Can't recognize: %v", err)
}
if tonyStark == nil {
    log.Fatalf("Not a single face on the image")
}
avengerID := rec.Classify(tonyStark.Descriptor)
if avengerID < 0 {
    log.Fatalf("Can't classify")
}

fmt.Println(avengerID)
fmt.Println(labels[avengerID])

现在让我们尝试验证这不是侥幸,并尝试查看我们的图像识别系统是否适用于 Strange 博士的图像。

testDrStrange := filepath.Join(dataDir, "dr-strange.jpg")
drStrange, err := rec.RecognizeSingleFile(testDrStrange)
if err != nil {
    log.Fatalf("Can't recognize: %v", err)
}
if drStrange == nil {
    log.Fatalf("Not a single face on the image")
}
avengerID = rec.Classify(drStrange.Descriptor)
if avengerID < 0 {
    log.Fatalf("Can't classify")
}

最后,让我们使用 Wong 的图像来尝试一下:

testWong := filepath.Join(dataDir, "wong.jpg")
wong, err := rec.RecognizeSingleFile(testWong)
if err != nil {
    log.Fatalf("Can't recognize: %v", err)
}
if wong == nil {
    log.Fatalf("Not a single face on the image")
}
avengerID = rec.Classify(wong.Descriptor)
if avengerID < 0 {
    log.Fatalf("Can't classify")
}
fmt.Println(avengerID)
fmt.Println(labels[avengerID])

当你一起运行这一切时,你应该看到以下输出:

$ go run main.go
Facial Recognition System v0.01
Recognizer Initialized
Number of Faces in Image:  4
1
Tony Stark
0
Dr Strange
3
Wong

太棒了,我们设法建立了一个非常简单的人脸识别系统,使我们能够识别各种不同的复仇者联盟。

挑战:在所有复仇者联盟上建立一些参考文件,并尝试将人脸识别代码片段提取为可重用的功能

完整的源代码:

本教程的完整源代码可以在 Github 中找到: Tutorialedge/go-face-recognition-tutorial

结论

在本教程中,我们成功地构建了一个非常简单的人脸识别系统,可以处理静止图像。这有望成为本系列教程下一部分的基础,我们将在其中了解如何在视频流的实时上下文中执行此操作。

希望你喜欢这个教程,如果你喜欢,请在下面的评论部分告诉我!



本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表