Face Alignment with OpenCV and Python (original) (raw)
import
os
import
cv2
import
math
import
matplotlib.pyplot as pl
import
pandas as pd
from
PIL
import
Image
import
numpy as np
def
face_detection(img):
`` faces
=
face_detector.detectMultiScale(img,
1.1
,
4
)
`` if
(
len
(faces) <
=
0
):
`` img_gray
=
cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
`` return
img, img_gray
`` else
:
`` X, Y, W, H
=
faces[
0
]
`` img
=
img[
int
(Y):
int
(Y
+
H),
int
(X):
int
(X
+
W)]
`` return
img, cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
def
trignometry_for_distance(a, b):
`` return
math.sqrt(((b[
0
]
-
a[
0
])
*
(b[
0
]
-
a[
0
]))
+
\
`` ((b[
1
]
-
a[
1
])
*
(b[
1
]
-
a[
1
])))
def
Face_Alignment(img_path):
`` pl.imshow(cv2.imread(img_path)[:, :, ::
-
1
])
`` pl.show()
`` img_raw
=
cv2.imread(img_path).copy()
`` img, gray_img
=
face_detection(cv2.imread(img_path))
`` eyes
=
eye_detector.detectMultiScale(gray_img)
`` if
len
(eyes) >
=
2
:
`` eye
=
eyes[:,
2
]
`` container1
=
[]
`` for
i
in
range
(
0
,
len
(eye)):
`` container
=
(eye[i], i)
`` container1.append(container)
`` df
=
pd.DataFrame(container1, columns
=
[
`` "length"
,
"idx"
]).sort_values(by
=
[
'length'
])
`` eyes
=
eyes[df.idx.values[
0
:
2
]]
`` eye_1
=
eyes[
0
]
`` eye_2
=
eyes[
1
]
`` if
eye_1[
0
] > eye_2[
0
]:
`` left_eye
=
eye_2
`` right_eye
=
eye_1
`` else
:
`` left_eye
=
eye_1
`` right_eye
=
eye_2
`` right_eye_center
=
(
`` int
(right_eye[
0
]
+
(right_eye[
2
]
/
2
)),
`` int
(right_eye[
1
]
+
(right_eye[
3
]
/
2
)))
`` right_eye_x
=
right_eye_center[
0
]
`` right_eye_y
=
right_eye_center[
1
]
`` cv2.circle(img, right_eye_center,
2
, (
255
,
0
,
0
),
3
)
`` left_eye_center
=
(
`` int
(left_eye[
0
]
+
(left_eye[
2
]
/
2
)),
`` int
(left_eye[
1
]
+
(left_eye[
3
]
/
2
)))
`` left_eye_x
=
left_eye_center[
0
]
`` left_eye_y
=
left_eye_center[
1
]
`` cv2.circle(img, left_eye_center,
2
, (
255
,
0
,
0
),
3
)
`` if
left_eye_y > right_eye_y:
`` print
(
"Rotate image to clock direction"
)
`` point_3rd
=
(right_eye_x, left_eye_y)
`` direction
=
-
1
`` else
:
`` print
(
"Rotate to inverse clock direction"
)
`` point_3rd
=
(left_eye_x, right_eye_y)
`` direction
=
1
`` cv2.circle(img, point_3rd,
2
, (
255
,
0
,
0
),
2
)
`` a
=
trignometry_for_distance(left_eye_center,
`` point_3rd)
`` b
=
trignometry_for_distance(right_eye_center,
`` point_3rd)
`` c
=
trignometry_for_distance(right_eye_center,
`` left_eye_center)
`` cos_a
=
(b
*
b
+
c
*
c
-
a
*
a)
/
(
2
*
b
*
c)
`` angle
=
(np.arccos(cos_a)
*
180
)
/
math.pi
`` if
direction
=
=
-
1
:
`` angle
=
90
-
angle
`` else
:
`` angle
=
-
(
90
-
angle)
`` new_img
=
Image.fromarray(img_raw)
`` new_img
=
np.array(new_img.rotate(direction
*
angle))
`` return
new_img
opencv_home
=
cv2.__file__
folders
=
opencv_home.split(os.path.sep)[
0
:
-
1
]
path
=
folders[
0
]
for
folder
in
folders[
1
:]:
`` path
=
path
+
"/"
+
folder
path_for_face
=
path
+
"/data/haarcascade_frontalface_default.xml"
path_for_eyes
=
path
+
"/data/haarcascade_eye.xml"
path_for_nose
=
path
+
"/data/haarcascade_mcs_nose.xml"
if
os.path.isfile(path_for_face) !
=
True
:
`` raise
ValueError(
`` "opencv is not installed pls install using pip install opencv "
,
`` detector_path,
" violated."
)
face_detector
=
cv2.CascadeClassifier(path_for_face)
eye_detector
=
cv2.CascadeClassifier(path_for_eyes)
nose_detector
=
cv2.CascadeClassifier(path_for_nose)
test_set
=
[
"pic.png"
]
for
i
in
test_set:
`` alignedFace
=
Face_Alignment(i)
`` pl.imshow(alignedFace[:, :, ::
-
1
])
`` pl.show()
`` img, gray_img
=
face_detection(alignedFace)
`` pl.imshow(img[:, :, ::
-
1
])
`` pl.show()