网站首页 > 技术文章 正文
人脸识别的整个领域都是我喜欢阅读的内容。自己实施面部识别系统会让您听起来像是托尼·斯塔克,您可以将它们用于各种不同的项目,例如自动锁门,或为您的办公室构建监控系统,仅举几例。
在本教程中,我们将使用一些现有的库在 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
结论
在本教程中,我们成功地构建了一个非常简单的人脸识别系统,可以处理静止图像。这有望成为本系列教程下一部分的基础,我们将在其中了解如何在视频流的实时上下文中执行此操作。
希望你喜欢这个教程,如果你喜欢,请在下面的评论部分告诉我!
猜你喜欢
- 2025-10-23 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
- 2025-10-23 [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
- 2025-10-23 超详细手把手搭建在ubuntu系统的FFmpeg环境
- 2025-10-23 Nginx运维之路(Docker多段构建新版本并增加第三方模
- 2025-10-23 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
- 2025-10-23 安卓手机安装Termux——搭建移动服务器
- 2025-10-23 ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
- 2025-10-23 Rust开发环境搭建指南:从安装到镜像配置的零坑实践
- 2024-08-13 Linux 内核学习1. 编译并启动一个最小化系统
- 2024-08-13 如何在 Ubuntu 22.04 下编译 StoneDB for MySQL 8.0 | StoneDB 使用教程 #1
- 最近发表
-
- 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
- [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
- 超详细手把手搭建在ubuntu系统的FFmpeg环境
- Nginx运维之路(Docker多段构建新版本并增加第三方模
- 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
- Go 人脸识别教程_piwigo人脸识别
- 安卓手机安装Termux——搭建移动服务器
- ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
- Rust开发环境搭建指南:从安装到镜像配置的零坑实践
- Windows系统安装VirtualBox构造本地Linux开发环境
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (77)
- vector线程安全吗 (73)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)