marlenezw's picture
changing face alignment and removing its docker file.
22257c4
raw
history blame
No virus
9.93 kB
import numpy as np
import cv2
import matplotlib.pyplot as plt
import os
import random
def closest_node(xy, pts):
#search the list of nodes for the one closest to node, return the name
dist_2 = np.sqrt(np.sum((pts - np.array(xy).reshape((-1, 2)))**2, axis=1))
if (dist_2[np.argmin(dist_2)] > 20):
return -1
return np.argmin(dist_2)
def draw_landmarks(img, pts, pc=(0,0,255), radius=2, lc=(0,255,0), thickness=2):
for i in range(0, 16):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (0, 255, 0), thickness)
for i in range(17, 21):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (255, 0, 0), thickness)
for i in range(22, 26):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (255, 0, 0), thickness)
for i in range(27, 35):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (255, 255, 0), thickness)
for i in range(36, 41):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (255, 0, 255), thickness)
for i in range(42, 47):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (255, 0, 255), thickness)
for i in range(48, 59):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (255, 128, 0), thickness)
for i in range(60, 67):
cv2.line(img, (int(pts[i, 0]), int(pts[i, 1])),
(int(pts[i+1, 0]), int(pts[i+1, 1])), (255, 128, 128), thickness)
cv2.line(img, (int(pts[48, 0]), int(pts[48, 1])),
(int(pts[59, 0]), int(pts[59, 1])), (255, 128, 0), thickness)
cv2.line(img, (int(pts[60, 0]), int(pts[60, 1])),
(int(pts[67, 0]), int(pts[67, 1])), (255, 128, 128), thickness)
for i in range(68):
cv2.circle(img, (int(pts[i, 0]), int(pts[i, 1])), radius, pc, -1)
def norm_anno(ROOT_DIR, CH, param=[0.75, 0.35, 0.6, 0.6], show=True):
face_tmp = np.loadtxt(os.path.join(ROOT_DIR, CH + '_face_open_mouth.txt')) # .reshape(1, 204)
try:
face_tmp = face_tmp.reshape(68, 3)
except:
print('annotated face is not in correct size = [68 x 3]')
exit(0)
scale = 1.6 / (face_tmp[0, 0] - face_tmp[16, 0])
shift = - 0.5 * (face_tmp[0, 0:2] + face_tmp[16, 0:2])
face_tmp[:, 0:2] = (face_tmp[:, 0:2] + shift) * scale
face_std = np.loadtxt(os.path.join(ROOT_DIR, 'STD_FACE_LANDMARKS.txt'))
face_std = face_std.reshape(68, 3)
face_tmp[:, -1] = face_std[:, -1]
face_tmp[:, 0:2] = -face_tmp[:, 0:2]
np.savetxt(os.path.join(ROOT_DIR, CH + '_face_open_mouth_norm.txt'), face_tmp, fmt='%.4f')
np.savetxt(os.path.join(ROOT_DIR, CH + '_scale_shift.txt'), np.array([scale, shift[0], shift[1]]), fmt='%.10f')
# Force the frame to close mouth
face_tmp[49:54, 1] = param[0] * face_tmp[49:54, 1] + (1-param[0]) * face_tmp[59:54:-1, 1]
face_tmp[59:54:-1, 1] = param[1] * face_tmp[49:54, 1] + (1-param[1]) * face_tmp[59:54:-1, 1]
face_tmp[61:64, 1] = param[2] * face_tmp[61:64, 1] + (1-param[2]) * face_tmp[67:64:-1, 1]
face_tmp[67:64:-1, 1] = param[3] * face_tmp[61:64, 1] + (1-param[3]) * face_tmp[67:64:-1, 1]
face_tmp[61:64, 0] = 0.6 * face_tmp[61:64, 0] + 0.4 * face_tmp[67:64:-1, 0]
face_tmp[67:64:-1, 0] = 0.6 * face_tmp[61:64, 0] + 0.4 * face_tmp[67:64:-1, 0]
np.savetxt(os.path.join(ROOT_DIR, CH + '_face_close_mouth.txt'), face_tmp, fmt='%.4f')
std_face_id = np.loadtxt(os.path.join(ROOT_DIR, CH + '_face_close_mouth.txt')) # .reshape(1, 204)
std_face_id = std_face_id.reshape(68, 3)
def vis_landmark_on_plt(fl, x_offset=0.0, show_now=True):
def draw_curve(shape, idx_list, loop=False, x_offset=0.0, c=None):
for i in idx_list:
plt.plot((shape[i, 0] + x_offset, shape[i + 1, 0] + x_offset), (-shape[i, 1], -shape[i + 1, 1]), c=c)
if (loop):
plt.plot((shape[idx_list[0], 0] + x_offset, shape[idx_list[-1] + 1, 0] + x_offset),
(-shape[idx_list[0], 1], -shape[idx_list[-1] + 1, 1]), c=c)
draw_curve(fl, list(range(0, 16)), x_offset=x_offset) # jaw
draw_curve(fl, list(range(17, 21)), x_offset=x_offset) # eye brow
draw_curve(fl, list(range(22, 26)), x_offset=x_offset)
draw_curve(fl, list(range(27, 35)), x_offset=x_offset) # nose
draw_curve(fl, list(range(36, 41)), loop=True, x_offset=x_offset) # eyes
draw_curve(fl, list(range(42, 47)), loop=True, x_offset=x_offset)
draw_curve(fl, list(range(48, 59)), loop=True, x_offset=x_offset, c='b') # mouth
draw_curve(fl, list(range(60, 67)), loop=True, x_offset=x_offset, c='r')
draw_curve(fl, list(range(60, 64)), loop=False, x_offset=x_offset, c='g')
if (show_now):
plt.show()
vis_landmark_on_plt(std_face_id, show_now=show)
# Check if a point is inside a rectangle
def rect_contains(rect, point):
if point[0] < rect[0]:
return False
elif point[1] < rect[1]:
return False
elif point[0] > rect[2]:
return False
elif point[1] > rect[3]:
return False
return True
# Draw a point
def draw_point(img, p, color):
cv2.circle(img, p, 2, color, -1, cv2.LINE_AA, 0)
# Draw delaunay triangles
def draw_delaunay(img, subdiv, delaunay_color):
triangleList = subdiv.getTriangleList();
size = img.shape
r = (0, 0, size[1], size[0])
for t in triangleList:
pt1 = (t[0], t[1])
pt2 = (t[2], t[3])
pt3 = (t[4], t[5])
if rect_contains(r, pt1) and rect_contains(r, pt2) and rect_contains(r, pt3):
cv2.line(img, pt1, pt2, delaunay_color, 1, cv2.LINE_AA, 0)
cv2.line(img, pt2, pt3, delaunay_color, 1, cv2.LINE_AA, 0)
cv2.line(img, pt3, pt1, delaunay_color, 1, cv2.LINE_AA, 0)
# Draw voronoi diagram
def draw_voronoi(img, subdiv):
(facets, centers) = subdiv.getVoronoiFacetList([])
for i in range(0, len(facets)):
ifacet_arr = []
for f in facets[i]:
ifacet_arr.append(f)
ifacet = np.array(ifacet_arr, np.int)
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
cv2.fillConvexPoly(img, ifacet, color, cv2.LINE_AA, 0)
ifacets = np.array([ifacet])
cv2.polylines(img, ifacets, True, (0, 0, 0), 1, cv2.LINE_AA, 0)
cv2.circle(img, (centers[i][0], centers[i][1]), 3, (0, 0, 0), -1, cv2.LINE_AA, 0)
print("end of draw_voronoi")
def delauney_tri(ROOT_DIR, test_data, INNER_ONLY=False):
# Define window names
win_delaunay = "Delaunay Triangulation"
cv2.namedWindow(win_delaunay, cv2.WINDOW_NORMAL)
win_voronoi = "Voronoi Diagram"
# Turn on animation while drawing triangles
animate = True
# Define colors for drawing.
delaunay_color = (255, 255, 255)
points_color = (0, 0, 255)
# Read in the image.
if (os.path.exists(os.path.join(ROOT_DIR, test_data))):
img = cv2.imread(os.path.join(ROOT_DIR, test_data))
else:
print('not file founded.')
exit(0)
CH = test_data[:-4]
# Keep a copy around
img_orig = img.copy()
# Rectangle to be used with Subdiv2D
size = img.shape
rect = (0, 0, size[1], size[0])
# Create an array of points.
points = []
# Create an instance of Subdiv2D
subdiv = cv2.Subdiv2D(rect)
h = size[1] - 1
w = size[0] - 1
# Read in the points from a text file
file = np.loadtxt(os.path.join(ROOT_DIR, CH + '_face_open_mouth.txt'))
file = file.reshape(68, 3)
for i in range(file.shape[0]):
if(INNER_ONLY):
if(i >= 48 and i <= 59): ############## for inner lip only
continue
line = file[i]
x, y, z = line
points.append((int(float(x)), int(float(y))))
points.append((0, 0))
points.append((0, w // 4))
points.append((0, w // 2))
points.append((0, w // 4 * 3))
points.append((0, w))
points.append((h // 2, w))
points.append((h, w))
points.append((h, w // 2))
points.append((h, 0))
points.append((h // 4, 0))
points.append((h // 2, 0))
points.append((h // 4*3, 0))
# Insert points into subdiv
for p in points:
print(p)
subdiv.insert(p)
# Show animation
if animate:
img_copy = img_orig.copy()
# Draw delaunay triangles
draw_delaunay(img_copy, subdiv, (255, 255, 0))
cv2.imshow(win_delaunay, img_copy)
cv2.waitKey(100)
# Draw delaunay triangles
draw_delaunay(img, subdiv, (255, 255, 0))
triangleList = subdiv.getTriangleList()
p_dict = {} # Initialize empty dictionary.
index = 0
# Draw points
for p in points:
# draw_point(img, p, (0, 0, 255))
p_dict[p] = index
index = index + 1
# Allocate space for voronoi Diagram
img_voronoi = np.zeros(img.shape, dtype=img.dtype)
# Draw voronoi diagram
draw_voronoi(img_voronoi, subdiv)
# Show results
cv2.imshow(win_delaunay, img)
print("Press any key to quit...")
cv2.waitKey(0)
new_tri = [];
for line in triangleList:
p1 = (line[0], line[1])
p2 = (line[2], line[3])
p3 = (line[4], line[5])
try:
p1_index = p_dict[p1]
p2_index = p_dict[p2]
p3_index = p_dict[p3]
except:
continue
new_tri.append((p1_index, p2_index, p3_index))
print(new_tri)
a = np.array(new_tri).astype(int)
np.savetxt(os.path.join(ROOT_DIR, CH + '_delauney_tri.txt'), a, fmt='%d')