OpenCV人脸检测与三角剖分绘制

小白学视觉

共 3310字,需浏览 7分钟

 ·

2022-03-16 04:51

点击上方小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

 

一:三角剖分概念(Triangulation)

 三角剖分最早是俄国数学家Delaunay提出来的,而他获得博士学位时候的老师是Georgy Voronoy,是维诺图概念的提出者,而且维诺是马尔可夫的学生,就是很难懂的马尔可夫链的鼻祖。所以三角剖分又常常被冠以Delaunay Triangulation。其基本思想就是对任意多的点,分割为多个三角形,任意一个三角形的外接圆都不应该包含其它顶点,如果包含则继续寻找组合,直到所有点满足此条件,最终得到的多个三角形就是三角剖分,三角剖分在人脸特征迁移、人脸合成与交换、图像合成与分割等方面应用广泛,最常见的就是通过三角剖分实现合成显示如下:

 

二:OpenCV中相关API支持

Subdiv2D对象是OpenCV中用来生成三角剖分,并且获取三角剖分全部三角形的工具类,主要方法如下:

  1. - Subdiv2D subdiv // 定义三角剖分

  2. - initDelaunay (Rect rect) // 初始化三角剖分对象

  3. - subdiv.insert(Point2f); // 插入三角剖分的顶点

  4. - subdiv.getTriangleList(std::vector< Vec6f> &triangleList); // 获取三角形数据 

三:OpenCV基于人脸的三角剖分实现

现在很多人脸识别演示场景都支持实时绘制人脸的三角剖分之后的全部三角形,感觉是非常的帅,特别是大屏投影显示,笔者就在一些人工智能的展会上看到大厂的这种展示。利用OpenCV的HAAR级联检测器实现人脸检测,然后基于人脸检测结果通过LBF人脸Landmark检测器实现人脸68个特征点的拟合,然后根据拟合的68个点调用Subdiv2D类的相关API就可以生成人脸三角剖分,最后绘制即可。相关步骤代码如下:

1.人脸检测

  1. CascadeClassifier face_detector(harr_file);

  2. vector<Rect> faces;

  3. face_detector.detectMultiScale(gray, faces, 1.02, 1, 0, Size(20, 20), Size(300, 300));

  4. for(size_t t = 0; t < faces.size(); t++) {

  5.    rectangle(src, faces[t], Scalar(0, 0, 255), 2, 8, 0);

  6. }

2.Landmark特征点提取

  1. // 创建LBF landmark 检测器

  2. Ptr<FacemarkLBF> facemark = FacemarkLBF::create(params);


  3. // 加载模型数据

  4. facemark->loadModel("D:/vcprojects/images/lbfmodel.yaml");

  5. cout << "Loaded model"<< endl;


  6. // 提取人脸landmark-68个特征点

  7. vector<vector<Point2f>> landmarks;

  8. facemark->fit(src, faces, landmarks);

3.三角剖分生成与绘制

  1. // 创建剖分三角形生成器

  2. Subdiv2D subdiv;

  3. subdiv.initDelaunay(rect);


  4. // 添加与绘制特征点

  5. for(int i = 0; i < shapes.size(); i++) {

  6.    subdiv.insert(shapes[i]);

  7.    circle(result, shapes[i], 2, Scalar(0, 0, 255), -1, 8, 0);

  8. }


  9. // 生成剖分三角形

  10. vector<Vec6f> triangleList;

  11. subdiv.getTriangleList(triangleList);

  12. vector<Point> pt(3);


  13. // 绘制剖分三角形

  14. for(size_t i = 0; i < triangleList.size(); i++)

  15. {

  16.    Vec6f t = triangleList[i];

  17.    pt[0] = Point(cvRound(t[0]), cvRound(t[1]));

  18.    pt[1] = Point(cvRound(t[2]), cvRound(t[3]));

  19.    pt[2] = Point(cvRound(t[4]), cvRound(t[5]));


  20.    // 使用随机颜色,绘制三角形

  21.    if(rect.contains(pt[0]) && rect.contains(pt[1]) && rect.contains(pt[2]))

  22.    {

  23.        line(result, pt[0], pt[1], Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256)), 1, LINE_AA, 0);

  24.        line(result, pt[1], pt[2], Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256)), 1, LINE_AA, 0);

  25.        line(result, pt[2], pt[0], Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256)), 1, LINE_AA, 0);

  26.    }

  27. }

输入原图

人脸检测结果

三角剖分绘制


下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲
小白学视觉公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲
小白学视觉公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群


欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~


浏览 62
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报