Skip to content

Commit

Permalink
fix the order of retrieving landmarks; unify landmark colors as non o…
Browse files Browse the repository at this point in the history
…pencv_dnn version
  • Loading branch information
fengyuentau committed Jun 29, 2021
1 parent f9cc94f commit 7798154
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 37 deletions.
8 changes: 4 additions & 4 deletions opencv_dnn/cpp/face_def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ typedef struct Landmarks_5 {
cv::Point2f right_eye;
// left eye
cv::Point2f left_eye;
// mouth left
cv::Point2f mouth_left;
// nose
// nose tip
cv::Point2f nose_tip;
// mouth right
cv::Point2f mouth_right;
// mouth left
cv::Point2f mouth_left;
} Landmarks_5;

typedef struct Face {
Expand All @@ -27,4 +27,4 @@ typedef struct Face {
float score;
} Face;

#endif
#endif
26 changes: 13 additions & 13 deletions opencv_dnn/cpp/priorbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,26 +96,26 @@ std::vector<Face> PriorBox::decode(const cv::Mat& loc,
face.bbox_tlwh = { x1, y1, w, h };

// get landmarks, loc->[right_eye, left_eye, mouth_left, nose, mouth_right]
float x_re = (priors[i].x + loc_v[i*14+ 4] * variance[0] * priors[i].width) * out_w;
float x_re = (priors[i].x + loc_v[i*14+ 4] * variance[0] * priors[i].width) * out_w;
float y_re = (priors[i].y + loc_v[i*14+ 5] * variance[0] * priors[i].height) * out_h;
float x_le = (priors[i].x + loc_v[i*14+ 6] * variance[0] * priors[i].width) * out_w;
float x_le = (priors[i].x + loc_v[i*14+ 6] * variance[0] * priors[i].width) * out_w;
float y_le = (priors[i].y + loc_v[i*14+ 7] * variance[0] * priors[i].height) * out_h;
float x_ml = (priors[i].x + loc_v[i*14+ 8] * variance[0] * priors[i].width) * out_w;
float y_ml = (priors[i].y + loc_v[i*14+ 9] * variance[0] * priors[i].height) * out_h;
float x_n = (priors[i].x + loc_v[i*14+10] * variance[0] * priors[i].width) * out_w;
float y_n = (priors[i].y + loc_v[i*14+11] * variance[0] * priors[i].height) * out_h;
float x_mr = (priors[i].x + loc_v[i*14+12] * variance[0] * priors[i].width) * out_w;
float y_mr = (priors[i].y + loc_v[i*14+13] * variance[0] * priors[i].height) * out_h;
float x_n = (priors[i].x + loc_v[i*14+ 8] * variance[0] * priors[i].width) * out_w;
float y_n = (priors[i].y + loc_v[i*14+ 9] * variance[0] * priors[i].height) * out_h;
float x_mr = (priors[i].x + loc_v[i*14+10] * variance[0] * priors[i].width) * out_w;
float y_mr = (priors[i].y + loc_v[i*14+11] * variance[0] * priors[i].height) * out_h;
float x_ml = (priors[i].x + loc_v[i*14+12] * variance[0] * priors[i].width) * out_w;
float y_ml = (priors[i].y + loc_v[i*14+13] * variance[0] * priors[i].height) * out_h;
face.landmarks = {
{x_re, y_re}, // right eye
{x_le, y_le}, // left eye
{x_ml, y_ml}, // mouth left
{x_re, y_re}, // right eye
{x_le, y_le}, // left eye
{x_n, y_n }, // nose
{x_mr, y_mr} // mouth right
{x_mr, y_mr}, // mouth right
{x_ml, y_ml} // mouth left
};

dets.push_back(face);
}

return dets;
}
}
22 changes: 11 additions & 11 deletions opencv_dnn/cpp/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ void draw(cv::Mat& img,
const cv::Scalar bbox_color = { 0, 255, 0};
const cv::Scalar text_color = {255, 255, 255};
const std::vector<cv::Scalar> landmarks_color = {
{255, 0, 0}, // left eye
{ 0, 0, 255}, // right eye
{ 0, 255, 255}, // mouth left
{255, 255, 0}, // nose
{ 0, 255, 0} // mouth right
{255, 0, 0}, // right eye
{ 0, 0, 255}, // left eye
{ 0, 255, 0}, // nose
{255, 0, 255}, // mouth right
{ 0, 255, 255} // mouth left
};

for (auto i = 0; i < faces.size(); ++i) {
Expand All @@ -33,10 +33,10 @@ void draw(cv::Mat& img,
text_color);
// draw landmarks
const int radius = 2;
cv::circle(img, cv::Point(faces[i].landmarks.left_eye), radius, landmarks_color[0], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.right_eye), radius, landmarks_color[1], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.mouth_left), radius, landmarks_color[2], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.nose_tip), radius, landmarks_color[3], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.mouth_right), radius, landmarks_color[4], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.right_eye), radius, landmarks_color[0], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.left_eye), radius, landmarks_color[1], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.nose_tip), radius, landmarks_color[2], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.mouth_right), radius, landmarks_color[3], thickness);
cv::circle(img, cv::Point(faces[i].landmarks.mouth_left), radius, landmarks_color[4], thickness);
}
}
}
4 changes: 2 additions & 2 deletions opencv_dnn/python/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def str2bool(v: str) -> bool:

# Draw boudning boxes and landmarks on the original image
img_res = draw(
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB),
img=img,
bboxes=dets[:, :4],
landmarks=np.reshape(dets[:, 4:14], (-1, 5, 2)),
scores=dets[:, -1]
Expand All @@ -113,4 +113,4 @@ def str2bool(v: str) -> bool:
cv2.waitKey(0)
cv2.destroyAllWindows()
# Save the result image
cv2.imwrite(args.save, img_res)
cv2.imwrite(args.save, img_res)
17 changes: 10 additions & 7 deletions opencv_dnn/python/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
def draw(img: np.ndarray, bboxes: np.ndarray, landmarks: np.ndarray, scores: np.ndarray) -> np.ndarray:
'''
This function draws bounding boxes and landmarks on the image and return the result.
Parameters:
bboxes - bboxes of shape [n, 5]. 'n' for number of bboxes, '5' for coordinate and confidence
bboxes - bboxes of shape [n, 5]. 'n' for number of bboxes, '5' for coordinate and confidence
(x1, y1, x2, y2, c).
landmarks - landmarks of shape [n, 5, 2]. 'n' for number of bboxes, '5' for 5 landmarks
(two for eyes center, one for nose tip, two for mouth corners), '2' for coordinate
Expand All @@ -17,9 +17,6 @@ def draw(img: np.ndarray, bboxes: np.ndarray, landmarks: np.ndarray, scores: np.
img - image with bounding boxes and landmarks drawn
'''

# convert BGR to RGB for correct color display
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# draw bounding boxes
if bboxes is not None:
color = (0, 255, 0)
Expand All @@ -33,9 +30,15 @@ def draw(img: np.ndarray, bboxes: np.ndarray, landmarks: np.ndarray, scores: np.
if landmarks is not None:
radius = 2
thickness = 2
color = [(255, 0, 0), (0, 0, 255), (0, 255, 255), (255, 255, 0), (0, 255, 0)]
color = [
(255, 0, 0), # right eye
( 0, 0, 255), # left eye
( 0, 255, 0), # nose tip
(255, 0, 255), # mouth right
( 0, 255, 255) # mouth left
]
for idx in range(landmarks.shape[0]):
face_landmarks = landmarks[idx].astype(np.int)
for idx, landmark in enumerate(face_landmarks):
cv2.circle(img, (int(landmark[0]), int(landmark[1])), radius, color[idx], thickness)
return img
return img

0 comments on commit 7798154

Please sign in to comment.