python - 如何使用 Opencv 缩小/扩展面部特征?
问题描述
我正在尝试编写一个应用程序,使用 opencv 和 dlib 使部分面部图像变大或变小。我使用shape_predictor_68_face_landmarks.dat
. 在下面的函数中,tmp
变量应该以这样一种方式进行转换,即在图像上缩放鼻子或左眼。
def visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):
# create two copies of the input image -- one for the
# overlay and one for the final output image
overlay = image.copy()
output = image.copy()
# if the colors list is None, initialize it with a unique
# color for each facial landmark region
if colors is None:
colors = [(19, 199, 109), (79, 76, 240), (230, 159, 23),
(168, 100, 168), (158, 163, 32),
(163, 38, 32), (180, 42, 220)]
# loop over the facial landmark regions individually
for (i, name) in enumerate(FACIAL_LANDMARKS_INDEXES.keys()):
# grab the (x, y)-coordinates associated with the
# face landmark
(j, k) = FACIAL_LANDMARKS_INDEXES[name]
pts = shape[j:k]
facial_features_cordinates[name] = pts
if name != "Jaw" and name == "Left_Eye" or name == "Nose":
minX = min(pts[:,0])
maxX = max(pts[:,0])
minY = min(pts[:,1])
maxY = max(pts[:,1])
rect = []
rect.append([minX, minY])
rect.append([minX, maxY])
rect.append([maxX, minY])
rect.append([maxX, maxY])
rect = np.array(rect)
hull = cv2.convexHull(rect)
# print(hull)
# output = cv2.resize(overlay, dsize)
# print(overlay[minX:maxX,minY:maxX,:])
tmp = overlay[minY:maxY, minX:maxX, :]
print(tmp.shape)
s = 2
Affine_Mat_w = [s, 0, tmp.shape[0]/2.0 - s*tmp.shape[0]/2.0]
Affine_Mat_h = [0, s, tmp.shape[1]/2.0 - s*tmp.shape[1]/2.0]
M = np.c_[ Affine_Mat_w, Affine_Mat_h].T
tmp = cv2.warpAffine(tmp, M, (tmp.shape[1], tmp.shape[0]))
overlay[minY:maxY, minX:maxX, :] = tmp
return overlay
解决方案
更新 #1
pinch and bulge distortion
在眼睛和鼻子周围少量沿着面部标志应用可能会提供不错的结果,而无需转向其他方法。虽然如果它影响更大的区域,它也有可能会明显扭曲眼镜。这些应该有帮助,
- 使用 Python OpenCV 的挤压/膨胀变形
- 图像变形 - 凸起效果算法
- https://math.stackexchange.com/questions/266250/explanation-of-this-image-warping-bulge-filter-algorithm
- 桶形/枕形失真的公式
我不确定如何单独在 opencv 中做到这一点,而不会看起来不自然。以下是基于我自己的探索的一般解释。如果我犯了任何错误,请随时纠正我。
3D 网格
我认为当前的面部美化方法(例如 Android 相机上的方法)的一种方法是将 3d 面部网格或整个头部模型对齐到原始面部之上。
它使用面部标志提取面部纹理,并将它们与相应的 3d 网格对齐,并应用纹理。这样可以调整 3d 网格,并且纹理将遵循面部几何形状。可能还有其他步骤,例如将结果传递给另一个网络,涉及后处理以使其看起来更自然。
Mediapipe Face Mesh也可能会有所帮助,因为它提供了密集的 3D 人脸地标和3D 人脸模型、UV 可视化、坐标。这是关于媒体管道中面的 UV 展开的讨论。
来自https://github.com/YadiraF/DECA的示例。
来自https://github.com/sicxu/Deep3DFaceRecon_pytorch的示例。
GAN
另一种方法是使用 GAN 来编辑面部特征、应用照明、化妆等。
来自https://github.com/run-youngjoo/SC-FEGAN的示例。
另一个例子,https://github.com/genforce/idinvert_pytorch。
推荐阅读
- python - 在 python 刮板中使用装饰器时遇到问题
- c# - 使用 ItemTemplate 时如何删除 ListView 悬停效果
- matlab - 绘制分段连续函数
- java - 计算数组列表中的重复项
- apache-spark - 从 SparkSession.read() 获取“org.apache.spark.sql.AnalysisException:路径不存在”
- kotlin - 通过某些条件初始化两个或多个 val 的 Kotlin 规范方法
- video - 更改 USB 摄像头的比特率
- react-native - android上的React Native,上传到Play商店时没有捆绑图像
- java - 如何 LocalDateTime 但使用服务器时间或互联网时间?
- jenkins - 如果存在合并冲突,Jenkins Pipeline Multibranch 不会运行后期步骤