dlib 是一个功能强大、跨平台的纯 C++ 库,专为机器学习和计算机视觉设计。它由 Davis King 开发并维护,以其简洁的 API、高性能和易用性而闻名。编译依赖 C++ 编译器和构建工具 CMake,C++ 编译器需要支持 C++14。OpenCV(全称:Open Source Computer Vision Library,开源计算机视觉库)是一个功能强大、跨平台的开源计算机视觉和机器学习库。它由 Intel 于 1999 年发起开发,现在由社区广泛维护,是全球最流行的计算机视觉工具之一。dlib 本身不依赖 OpenCV,OpenCV 是可选的 "协作库" 而非必选依赖;只有当你需要在 dlib 和 OpenCV 之间做图像格式互转、或用 OpenCV 处理图片 / 视频时,才需要引入 OpenCV。简单来说:OpenCV 是一个"图像采集器",dlib 是一个"智能分析器"。你可以只用其中一个,也可以把它们组合起来,但 dlib 不需要 OpenCV 才能工作。
📌 dlib 的主要功能模块
| 模块 | 功能 |
|---|---|
| 人脸识别 | 人脸检测(HOG + SVM)、人脸特征点定位(68点)、人脸识别(深度学习模型) |
| 图像处理 | 图像旋转、缩放、滤波、边缘检测等 |
| 机器学习 | 支持向量机(SVM)、决策树、随机森林、神经网络(DNN)等 |
| 优化算法 | 非线性优化、全局优化(如贝叶斯优化) |
| 信号处理 | 数字滤波、频域分析 |
| 通用工具 | 多线程、日志系统、文件 I/O |
📌 opencv 的主要功能模块
| 功能类别 | 主要应用 |
|---|---|
| 图像处理 | 图像读写、色彩空间转换、滤波、几何变换 |
| 视频分析 | 视频捕获、运动检测、目标跟踪 |
| 特征工程 | 关键点检测、特征描述、特征匹配 |
| 目标识别 | 人脸检测、物体检测、模板匹配 |
| 3D视觉 | 相机标定、立体视觉、三维重建 |
| 机器学习 | SVM, KNN, 决策树等传统算法 |
| 深度学习 | 加载和运行深度神经网络模型 |
| UI交互 | 显示图像、响应用户输入 |
安装 dlib
直接从源码编译。
shell
# 克隆dlib源码(也可直接下载release包)
git clone https://github.com/davisking/dlib.git
cd dlib
# 编译并安装dlib(生成静态库)
mkdir build && cd build
cmake .. -DDLIB_USE_CUDA=OFF # 无GPU则关闭CUDA,加速编译
make -j4
sudo make install
cd ../..
安装 OpenCV
📌 方法一:使用包管理器(推荐,适用于 Linux / macOS)
- Ubuntu / Debian
安装 OpenCV 开发库(不含 Python 绑定)
shell
sudo apt update
sudo apt install libopencv-dev
如果需要更多模块(如 video, imgproc, highgui)
shell
sudo apt install libopencv-imgproc-dev libopencv-highgui-dev libopencv-video-dev
✅ 这会安装:
- 头文件(.h 文件)
- 静态库(.a)和共享库(.so)
- 命令行工具(如 opencv_version)
- CentOS / RHEL / Fedora
使用 yum 或 dnf
shell
sudo yum install opencv-devel # CentOS 7
或
shell
sudo dnf install opencv-devel # Fedora / CentOS 8+
- macOS (Homebrew)
安装 OpenCV,并避免安装 Python 绑定
shell
brew install opencv --without-python
```shell
⚠️ 注意:macOS 上默认可能仍会安装 Python 绑定,建议使用 --build-from-source 并自定义配置。
📌 方法二:从源码编译(最灵活,支持定制)
如果想完全控制 OpenCV 的构建(如启用 GPU、优化性能、选择模块等),推荐从源码编译。
步骤:
1. 安装依赖项
```shell
# Ubuntu 示例
sudo apt update
sudo apt install build-essential cmake git libgtk-3-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
- 下载 OpenCV 源码
shell
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 4.9.0 # 或最新稳定版
- 创建构建目录并配置
shell
mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D BUILD_opencv_python3=OFF # 关闭 Python 绑定
-D BUILD_EXAMPLES=OFF # 不编译示例
-D INSTALL_CXX_MODULES=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
..
- 编译和安装
shell
make -j$(nproc)
sudo make install
- 验证
shell
# 检查是否安装成功
pkg-config --libs opencv4
# 或查看版本
opencv_version
🔧 如何在 C++ 程序中使用 OpenCV?
示例代码(main.cpp):
c++
include
include
int main() {
std::cout << "OpenCV version: " << CV_VERSION << std::endl;
return 0;
}
编译命令:
shell
g++ main.cpp -o test pkg-config --cflags --libs opencv4
✅ 成功输出版本号即表示安装正确。
完整人脸马赛克打码示例代码
新建文件 face_blur_dlib.cpp,粘贴以下代码(包含人脸检测 + 马赛克 + 高斯模糊核心逻辑):
c++
#include <dlib/opencv.h>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/gui_widgets.h>
#include <opencv2/opencv.hpp>
#include <iostream>
// 马赛克打码函数:对指定区域进行像素化
void mosaicBlur(cv::Mat& img, const dlib::rectangle& face_rect, int block_size = 10) {
// 将dlib的矩形转换为OpenCV的Rect
cv::Rect cv_rect(face_rect.left(), face_rect.top(),
face_rect.width(), face_rect.height());
// 提取人脸区域
cv::Mat face_region = img(cv_rect);
int h = face_region.rows;
int w = face_region.cols;
// 缩小后放大,实现马赛克效果
cv::Mat small;
cv::resize(face_region, small, cv::Size(w/block_size, h/block_size), 0, 0, cv::INTER_LINEAR);
cv::resize(small, face_region, cv::Size(w, h), 0, 0, cv::INTER_NEAREST);
// 将处理后的区域放回原图
face_region.copyTo(img(cv_rect));
}
// 高斯模糊打码函数:对指定区域进行高斯模糊
void gaussianBlur(cv::Mat& img, const dlib::rectangle& face_rect, int blur_size = 25) {
// 确保模糊核为奇数(OpenCV要求)
if (blur_size % 2 == 0) blur_size += 1;
// 转换dlib矩形到OpenCV Rect
cv::Rect cv_rect(face_rect.left(), face_rect.top(),
face_rect.width(), face_rect.height());
// 对人脸区域执行高斯模糊
cv::GaussianBlur(img(cv_rect), img(cv_rect), cv::Size(blur_size, blur_size), 0);
}
int main(int argc, char** argv) {
// 命令行参数检查
if (argc != 4) {
std::cerr << "用法:./face_blur_dlib <输入图片路径> <输出图片路径> <打码类型(mosaic/gaussian)>" << std::endl;
std::cerr << "示例:./face_blur_dlib input.jpg output.jpg mosaic" << std::endl;
return 1;
}
// 1. 初始化dlib人脸检测器
dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();
// 2. 读取图片(OpenCV格式)
cv::Mat img = cv::imread(argv[1]);
if (img.empty()) {
std::cerr << "错误:无法读取图片 " << argv[1] << std::endl;
return 1;
}
// 3. 转换图片格式(OpenCV → dlib),用于人脸检测
dlib::cv_image<dlib::bgr_pixel> dlib_img(img);
// 检测所有人脸
std::vector<dlib::rectangle> faces = detector(dlib_img);
if (faces.empty()) {
std::cout << "警告:未检测到人脸,直接保存原图片" << std::endl;
cv::imwrite(argv[2], img);
return 0;
}
std::cout << "检测到 " << faces.size() << " 个人脸,开始打码..." << std::endl;
// 4. 根据指定类型执行打码
std::string blur_type = argv[3];
for (auto& face : faces) {
if (blur_type == "mosaic") {
mosaicBlur(img, face, 15); // 马赛克块大小15,可调整
} else if (blur_type == "gaussian") {
gaussianBlur(img, face, 35); // 高斯模糊核大小35,可调整
} else {
std::cerr << "错误:不支持的打码类型,仅支持 mosaic/gaussian" << std::endl;
return 1;
}
}
// 5. 保存打码后的图片
if (cv::imwrite(argv[2], img)) {
std::cout << "成功:打码后的图片已保存至 " << argv[2] << std::endl;
} else {
std::cerr << "错误:无法保存图片 " << argv[2] << std::endl;
return 1;
}
return 0;
}
编译命令:
shell
g++ -std=c++14 face_blur_dlib.cpp -o face_blur_dlib `pkg-config --cflags --libs dlib-1 opencv4` -lpthread
运行示例:
shell
# 马赛克打码
./face_blur_dlib input_face.jpg output_mosaic.jpg mosaic
# 高斯模糊打码
./face_blur_dlib input_face.jpg output_gaussian.jpg gaussian
完整人脸戴口罩打码示例代码
新建文件face_add_mask.cpp,粘贴以下代码(支持矩形口罩和贴合面部的多边形口罩两种效果):
c++
#include <dlib/opencv.h>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/shape_predictor.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
// 贴合面部的多边形口罩绘制(基于68个特征点)
void drawFitMask(cv::Mat& img, const dlib::full_object_detection& shape,
const cv::Scalar& color = cv::Scalar(20, 100, 200), float alpha = 0.8) {
// 提取口罩覆盖的特征点索引(68点中:3-13列脸颊,33鼻子下,57下巴)
std::vector<int> mask_points_idx = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, // 脸颊外侧
33, // 鼻子下方
57, // 下巴
33, // 鼻子下方(回退)
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 // 另一侧脸颊
};
// 转换特征点为OpenCV的Point数组
std::vector<cv::Point> mask_contour;
for (int idx : mask_points_idx) {
int x = shape.part(idx).x();
int y = shape.part(idx).y();
mask_contour.push_back(cv::Point(x, y));
}
// 创建口罩图层(带透明度)
cv::Mat mask_layer = img.clone();
// 填充口罩多边形
cv::fillPoly(mask_layer, std::vector<std::vector<cv::Point>>{mask_contour}, color);
// 叠加图层(透明度融合)
cv::addWeighted(mask_layer, alpha, img, 1 - alpha, 0, img);
// 绘制口罩轮廓(可选)
cv::polylines(img, mask_contour, true, cv::Scalar(0, 0, 0), 2);
}
// 简单矩形口罩绘制(适合快速实现)
void drawRectMask(cv::Mat& img, const dlib::rectangle& face_rect,
const cv::Scalar& color = cv::Scalar(20, 100, 200), float alpha = 0.8) {
// 计算口罩矩形(覆盖口鼻区域:人脸高度的下半部分)
int mask_top = face_rect.top() + face_rect.height() / 3;
int mask_bottom = face_rect.bottom();
cv::Rect mask_rect(face_rect.left(), mask_top, face_rect.width(), mask_bottom - mask_top);
// 带透明度绘制矩形口罩
cv::Mat mask_layer = img.clone();
cv::rectangle(mask_layer, mask_rect, color, -1); // -1表示填充
cv::addWeighted(mask_layer, alpha, img, 1 - alpha, 0, img);
// 绘制口罩边框
cv::rectangle(img, mask_rect, cv::Scalar(0, 0, 0), 2);
}
int main(int argc, char** argv) {
// 命令行参数检查
if (argc != 5) {
std::cerr << "用法:./face_add_mask <输入图片> <输出图片> <模型路径> <口罩类型(fit/rect)>" << std::endl;
std::cerr << "示例:./face_add_mask input.jpg output.jpg shape_predictor_68.dat fit" << std::endl;
return 1;
}
// 1. 初始化dlib检测器和特征点预测器
dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();
dlib::shape_predictor predictor;
try {
dlib::deserialize(argv[3]) >> predictor; // 加载特征点模型
} catch (std::exception& e) {
std::cerr << "加载特征点模型失败:" << e.what() << std::endl;
std::cerr << "请确认模型文件路径正确,或重新下载模型" << std::endl;
return 1;
}
// 2. 读取图片
cv::Mat img = cv::imread(argv[1]);
if (img.empty()) {
std::cerr << "无法读取图片:" << argv[1] << std::endl;
return 1;
}
// 3. 检测人脸并提取特征点
dlib::cv_image<dlib::bgr_pixel> dlib_img(img);
std::vector<dlib::rectangle> faces = detector(dlib_img);
if (faces.empty()) {
std::cout << "未检测到人脸,直接保存原图片" << std::endl;
cv::imwrite(argv[2], img);
return 0;
}
std::cout << "检测到 " << faces.size() << " 个人脸,开始添加口罩..." << std::endl;
// 4. 为每个人脸添加口罩
std::string mask_type = argv[4];
for (auto& face : faces) {
if (mask_type == "fit") {
// 提取68个特征点,绘制贴合口罩
dlib::full_object_detection shape = predictor(dlib_img, face);
drawFitMask(img, shape);
} else if (mask_type == "rect") {
// 绘制简单矩形口罩
drawRectMask(img, face);
} else {
std::cerr << "不支持的口罩类型,仅支持 fit/rect" << std::endl;
return 1;
}
}
// 5. 保存结果
if (cv::imwrite(argv[2], img)) {
std::cout << "成功:添加口罩后的图片已保存至 " << argv[2] << std::endl;
} else {
std::cerr << "无法保存图片:" << argv[2] << std::endl;
return 1;
}
return 0;
}
编译命令:
shell
g++ -std=c++14 face_add_mask.cpp -o face_add_mask `pkg-config --cflags --libs dlib-1 opencv4` -lpthread
运行示例:
shell
# 方式1:贴合面部的多边形口罩
./face_add_mask input_face.jpg output_fit_mask.jpg shape_predictor_68.dat fit
# 方式2:简单矩形口罩(无需特征点模型?不,代码里统一加载,rect模式也能用)
./face_add_mask input_face.jpg output_rect_mask.jpg shape_predictor_68.dat rect
可从 https://github.com/italojs/facial-landmarks-recognition/blob/master/shape_predictor_68_face_landmarks.dat 下载 shape_predictor_68.dat 。
核心代码解释:
- 特征点模型加载:
c++
dlib::deserialize(argv[3]) >> predictor;
shape_predictor是 dlib 的特征点预测器,输入人脸矩形后,可输出 68 个精准的面部特征点(眼睛、鼻子、嘴巴、下巴等)。
- 贴合口罩绘制逻辑:
- 选取 68 个特征点中 "脸颊→鼻子下→下巴" 的关键点,组成闭合多边形,模拟口罩的贴合轮廓;
- 通过cv::addWeighted设置透明度(alpha=0.8),让口罩看起来更真实,而非完全遮挡。
- 矩形口罩逻辑:
简化版实现,直接取人脸矩形的下半部分(口鼻区域)绘制矩形,无需特征点,适合快速验证。
扩展方向:
-
调整color参数修改口罩颜色(如蓝色cv::Scalar(200, 100, 20));
-
调整alpha参数修改口罩透明度(0~1,值越小越透明);
-
增加口罩纹理(加载口罩图片,按轮廓贴上去,效果更逼真)。
❗ 常见问题解答
| 问题 | 解决方案 |
|---|---|
| cannot find -lopencv_core | 确保已安装 libopencv-dev,或检查 pkg-config 是否能找到 OpenCV |
| No package 'opencv' found | 系统没有 pkg-config,或未正确安装 OpenCV 开发包 |
想要 GUI 功能(如 imshow) 需要 libopencv-highgui-dev 和 libgtk-3-dev。
📦 总结
| 目标 | 方法 |
|---|---|
| 仅需 C++ 库(无 Python) | sudo apt install libopencv-dev |
| 自定义编译(高性能/定制) | 从源码编译,关闭 BUILD_opencv_python3 |
| 避免 Python 绑定 | 在 cmake 中设置 -D BUILD_opencv_python3=OFF |
✅ 最终建议:
安装 OpenCV 开发库(Ubuntu)
shell
sudo apt install libopencv-dev libopencv-imgproc-dev libopencv-highgui-dev
验证安装,执行:
shell
pkg-config --cflags --libs dlib-1 opencv4 # 若 OpenCV 是 3.x 则用opencv
能输出头文件和库路径即说明安装成功。
text
# pkg-config --cflags --libs dlib-1 opencv4
-I/usr/local/include -I/usr/include/opencv4 -L/usr/local/lib64 -ldlib -lopencv_gapi -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_cvv -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_hfs -lopencv_img_hash -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_shape -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_highgui -lopencv_datasets -lopencv_text -lopencv_plot -lopencv_ml -lopencv_videostab -lopencv_videoio -lopencv_wechat_qrcode -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core