|
@ -25,7 +25,7 @@ void ofYolo::ParseOutput(float* &output_tensors, std::vector<BoxfWithLandmarks> |
|
|
face.box.y1 = cy - h / 2; |
|
|
face.box.y1 = cy - h / 2; |
|
|
face.box.x2 = cx + w / 2; |
|
|
face.box.x2 = cx + w / 2; |
|
|
face.box.y2 = cy + h / 2; |
|
|
face.box.y2 = cy + h / 2; |
|
|
face.box.score = cls_conf; |
|
|
face.box.score = cls_conf * obj_conf; |
|
|
face.box.label_text = "face"; |
|
|
face.box.label_text = "face"; |
|
|
|
|
|
|
|
|
// Extract landmarks
|
|
|
// Extract landmarks
|
|
@ -44,13 +44,59 @@ void ofYolo::ParseOutput(float* &output_tensors, std::vector<BoxfWithLandmarks> |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Simple helper for drawing boxes given x1, y1, x2, y2 coordinates.
|
|
|
// Simple helper for drawing boxes given x1, y1, x2, y2 coordinates.
|
|
|
void ofYolo::DrawBox(std::vector<BoxfWithLandmarks> &detected_faces){ |
|
|
void ofYolo::DrawBox(std::vector<BoxfWithLandmarks> &detected_faces, int limit){ |
|
|
|
|
|
int count = 0; |
|
|
for (const auto &face : detected_faces) { |
|
|
for (const auto &face : detected_faces) { |
|
|
|
|
|
if (count >= limit) break; |
|
|
ofPushStyle(); |
|
|
ofPushStyle(); |
|
|
ofNoFill(); |
|
|
ofNoFill(); |
|
|
ofSetColor(ofColor::cyan); |
|
|
ofSetColor(ofColor::red); |
|
|
ofDrawRectangle(face.box.x1, face.box.y1, ((face.box.x2) - (face.box.x1)), face.box.y2 - face.box.y1); |
|
|
float width = face.box.x2 - face.box.x1; |
|
|
|
|
|
float height = face.box.y2 - face.box.y1; |
|
|
|
|
|
float side = std::max(width, height); |
|
|
|
|
|
|
|
|
|
|
|
// Center of the box
|
|
|
|
|
|
float centerX = (face.box.x1 + face.box.x2) / 2.0f; |
|
|
|
|
|
float centerY = (face.box.y1 + face.box.y2) / 2.0f; |
|
|
|
|
|
|
|
|
|
|
|
// Top-left corner of the square
|
|
|
|
|
|
float x = centerX - side / 2.0f; |
|
|
|
|
|
float y = centerY - side / 2.0f; |
|
|
|
|
|
|
|
|
|
|
|
ofDrawRectangle(x, y, side, side); |
|
|
|
|
|
ofPopStyle(); |
|
|
|
|
|
count++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ofYolo::DrawBoxLabels(const std::vector<BoxfWithLandmarks>& detected_faces, int limit) { |
|
|
|
|
|
int count = 0; |
|
|
|
|
|
for (const auto& face : detected_faces) { |
|
|
|
|
|
if (count >= limit) break; |
|
|
|
|
|
float width = face.box.x2 - face.box.x1; |
|
|
|
|
|
float height = face.box.y2 - face.box.y1; |
|
|
|
|
|
float side = std::max(width, height); |
|
|
|
|
|
|
|
|
|
|
|
float centerX = (face.box.x1 + face.box.x2) / 2.0f; |
|
|
|
|
|
float centerY = (face.box.y1 + face.box.y2) / 2.0f; |
|
|
|
|
|
float x = centerX - side / 2.0f; |
|
|
|
|
|
float y = centerY - side / 2.0f; |
|
|
|
|
|
|
|
|
|
|
|
float margin = 4.0f; |
|
|
|
|
|
float textX = x + side - margin; |
|
|
|
|
|
float textY = y + margin + 12; |
|
|
|
|
|
|
|
|
|
|
|
std::string label = "Score: " + ofToString(face.box.score, 2) + |
|
|
|
|
|
"\n" + face.emotion.getDominantEmotion(); |
|
|
|
|
|
|
|
|
|
|
|
// Calculate bounding box width for right alignment
|
|
|
|
|
|
ofRectangle bbox = ofBitmapFont().getBoundingBox(label, 0, 0); |
|
|
|
|
|
|
|
|
|
|
|
ofPushStyle(); |
|
|
|
|
|
ofSetColor(ofColor::yellow); |
|
|
|
|
|
ofDrawBitmapStringHighlight(label, textX - bbox.getWidth(), textY); |
|
|
ofPopStyle(); |
|
|
ofPopStyle(); |
|
|
|
|
|
count++; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -170,6 +216,7 @@ void ofYolo::CropFaceToImage(ofImage &inputImage, BoxfWithLandmarks &face, ofIma |
|
|
void ofYolo::SortDetectedFaces(std::vector<BoxfWithLandmarks> &detectedFaces){ |
|
|
void ofYolo::SortDetectedFaces(std::vector<BoxfWithLandmarks> &detectedFaces){ |
|
|
std::sort(detectedFaces.begin(), detectedFaces.end(), |
|
|
std::sort(detectedFaces.begin(), detectedFaces.end(), |
|
|
[](const BoxfWithLandmarks &a, const BoxfWithLandmarks &b) { |
|
|
[](const BoxfWithLandmarks &a, const BoxfWithLandmarks &b) { |
|
|
return a.box.center.x > b.box.center.x; // Sort in descending order
|
|
|
//return a.box.center.x > b.box.center.x; // Sort in descending order
|
|
|
|
|
|
return a.box.score > b.box.score; |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |