正文
42
))
def
correct_colours
(
im1
,
im2
,
landmarks1
)
:
blur_amount
=
COLOUR_CORRECT_BLUR_FRAC
*
numpy
.
linalg
.
norm
(
numpy
.
mean
(
landmarks1
[
LEFT_EYE_POINTS
],
axis
=
0
)
-
numpy
.
mean
(
landmarks1
[
RIGHT_EYE_POINTS
],
axis
=
0
))
blur_amount
=
int
(
blur_amount
)
if
blur_amount
%
2
==
0
:
blur_amount
+=
1
im1_blur
=
cv2
.
GaussianBlur
(
im1
,
(
blur_amount
,
blur_amount
),
0
)
im2_blur
=
cv2
.
GaussianBlur
(
im2
,
(
blur_amount
,
blur_amount
),
0
)
# Avoid divide-by-zero errors.
im2_blur
+=
128
*
(
im2_blur
&
lt
;
=
1.0
)
return
(
im2
.
astype
(
numpy
.
float64
)
*
im1_blur
.
astype
(
numpy
.
float64
)
/
im2_blur
.
astype
(
numpy
.
float64
))
结果如下:
此函数试图改变 im2 的颜色来适配 im1。它通过用 im2 除以 im2 的高斯模糊值,然后乘以im1的高斯模糊值。这里的想法是用RGB缩放校色,但并不是用所有图像的整体常数比例因子,每个像素都有自己的局部比例因子。
用这种方法两图像之间光线的差异只能在某种程度上被修正。例如,如果图像1是从一侧照亮,但图像2是被均匀照亮的,色彩校正后图像2也会出现未照亮一侧暗一些的问题。
也就是说,这是一个相当简陋的办法,而且解决问题的关键是一个适当的高斯核函数大小。如果太小,第一个图像的面部特征将显示在第二个图像中。过大,内核之外区域像素被覆盖,并发生变色。这里的内核用了一个0.6 *的瞳孔距离。
4.把第二张图像的特征混合在第一张图像中
用一个遮罩来选择图像2和图像1的哪些部分应该是最终显示的图像:
值为1(显示为白色)的地方为图像2应该显示出的区域,值为0(显示为黑色)的地方为图像1应该显示出的区域。值在0和1之间为图像1和图像2的混合区域。
这是生成上图的代码:
LEFT_EYE_POINTS
=
list
(
range
(
42
,
48
))
RIGHT_EYE_POINTS
=
list
(
range
(
36
,
42
))
LEFT_BROW_POINTS
=
list
(
range
(
22
,
27
))
RIGHT_BROW_POINTS
=
list
(
range
(
17
,
22
))
NOSE_POINTS
=
list
(
range
(
27
,
35
))
MOUTH_POINTS
=
list
(
range
(
48
,
61
))
OVERLAY_POINTS
=
[
LEFT_EYE_POINTS
+
RIGHT_EYE_POINTS
+
LEFT_BROW_POINTS
+
RIGHT_BROW_POINTS
,
NOSE_POINTS
+
MOUTH_POINTS
,
]
FEATHER_AMOUNT
=
11
def
draw_convex_hull
(
im
,
points
,
color
)
:
points
=
cv2
.
convexHull
(
points
)
cv2
.
fillConvexPoly
(
im
,
points
,
color
=
color
)
def
get_face_mask
(
im
,
landmarks
)
:
im
=
numpy
.
zeros
(
im
.
shape
[
:
2
],
dtype
=
numpy
.
float64
)
for
group
in
OVERLAY_POINTS
:
draw_convex_hull
(
im
,
landmarks
[
group
],
color
=
1
)
im
=
numpy
.
array
([
im
,
im
,
im
]).
transpose
((
1
,
2
,
0
))
im
=
(
cv2
.
GaussianBlur
(
im
,
(
FEATHER_AMOUNT
,
FEATHER_AMOUNT
),
0
)
&
gt
;
0
)
*
1.0
im
=
cv2
.
GaussianBlur
(
im
,
(
FEATHER_AMOUNT
,
FEATHER_AMOUNT
),