#import "../template.typ": *

#show: project.with(
  title: "6",
  authors: ("absolutex",),
)

= 机器视觉实践 六


== 实验目的

人脸亮牙

+ 增加牙齿区域的亮度和对比度
+ 要求图像亮牙算法具有实时性
+ 要求在实现图像亮牙的同时，保持其它相邻区域（如嘴唇和牙龈）的颜色和对比度不变

== 实验代码

本次实验复用了之前的亮度调整代码，使图片可以在两侧对比查看差异。

具体的原理是

1. 先用 opencv 的 CascadeClassifier 获取脸部区域的图像。我本来想直接使用第三方的 HaarCascades mouth.xml 作为提取级联分类器，结果效果不是很好，而且 opencv 官方只提供了 haarcascade_frontalface_default.xml 作为脸部分类器。所以我选择先提取脸部，然后再调整框选矩形区域，将区域集中在嘴的部分。
2. 然后再逐像素判断牙齿区域的像素。在 RGB 三像素的 max 和 min 中，取 `min >= 13 && max - min <= 60 && max < 120` 的像素，即判断为牙齿区域。这个式子是我从一张现有图片上总结的，但是此计算公式在其他亮度的图片下可能并不适用。
3. 对每个像素的 R，G，B，分别乘以 R，G，B 因子作为新的像素。三个 RGB 因子需要尽可能相同以降低色差，但也可以适当进行微调。代码中使用 R 1.4, G 1.5, B 1.5 作为乘数因子。

实验的 GUI 框架使用浏览器前端，引入了 opencv.js 作为图像处理的绑定。


#include_code("../src/tooth/index.html")

== 实验结果与心得

#figure(
  image("res.jpeg", width: 50%),
  caption: [效果图],
)

图像分为可拖动的两部分，左边是未处理的图像，右边是处理后的图像，使用红框框选出嘴部区域，并实现亮牙。

亮牙的效果不错，并且图像其他地方的对比度没有变化。但是在嘴唇边缘有一些细小的像素也被加亮了，显得比较突兀，这是因为牙齿检测的算法不够优秀导致的。

还有，在测试过程中发现，如果牙齿框选区域过大，脖子的阴影部分被框选后也会加亮，这不是预期的效果。因此如果需要针对更多的图像 实现亮牙，嘴部区域检测算法也需要加强。