Last active
March 15, 2019 15:27
-
-
Save liberize/6672f53abfa871ba520c28d37365a939 to your computer and use it in GitHub Desktop.
pico full angle detection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace { | |
const int MAX_DETS = 5; | |
const float SCALE_FACTOR = 1.1f; | |
const float STRIDE_FACTOR = 0.1f; | |
const float QUALITY_THRESH = 10.0f; | |
const float ANGLE_STEP = 45.0f; | |
} | |
struct PicoObject { | |
float row; | |
float col; | |
float size; | |
float quality; | |
}; | |
void PicoFaceDetector::DoDetect(const Image &img, const cv::Rect2f &roi, std::vector<Face> &faces, | |
int minSize, int maxSize) | |
{ | |
if (cascade_ == NULL) { | |
return; | |
} | |
cv::Mat gray = cvext::empty(roi) ? img.gray : cvext::roi(img.gray, roi); | |
if (maxSize == 0) { | |
maxSize = std::min(gray.cols, gray.rows); | |
} | |
const int NUM_ANGLES = 360.0f / ANGLE_STEP; | |
PicoObject rcsq[NUM_ANGLES * MAX_DETS] = {0}; | |
int ndets[NUM_ANGLES] = {0}; | |
cvext::parallel_for(0, NUM_ANGLES, [&](int r) { | |
ndets[r] = find_objects((float *)&rcsq[r * MAX_DETS], MAX_DETS, cascade_, r * ANGLE_STEP / 360.0f, | |
gray.data, gray.rows, gray.cols, (int)gray.step[0], | |
SCALE_FACTOR, STRIDE_FACTOR, minSize, maxSize); | |
}); | |
int total = ndets[0]; | |
int idx[NUM_ANGLES * MAX_DETS] = {0}; | |
for (int i = 1; i < NUM_ANGLES; i++) { | |
for (int j = 0; j < ndets[i]; j++, total++) { | |
rcsq[total] = rcsq[i * MAX_DETS + j]; | |
idx[total] = i; | |
} | |
} | |
float qs[NUM_ANGLES * MAX_DETS] = {0}; | |
for (int i = 0; i < total; i++) { | |
qs[i] = rcsq[i].quality; | |
} | |
int cc[NUM_ANGLES * MAX_DETS] = {0}; | |
int remain = cluster_detections((float *)rcsq, total, cc); | |
for (int i = 0; i < remain; i++) { | |
if (rcsq[i].quality < QUALITY_THRESH) { | |
continue; | |
} | |
float sumqs[NUM_ANGLES] = {0}; | |
for (int j = 0; j < total; j++) { | |
if (cc[j] == i + 1) { | |
sumqs[idx[j]] += qs[j]; | |
} | |
} | |
float maxqs = 0, angle = 0; | |
for (int j = 0; j < NUM_ANGLES; j++) { | |
if (sumqs[j] > maxqs) { | |
maxqs = sumqs[j]; | |
angle = j * ANGLE_STEP; | |
} | |
} | |
cv::Point2f center(rcsq[i].col + roi.x, rcsq[i].row + roi.y); | |
// face rect is a little too up, fix it by move center point down | |
cvext::move(center, rcsq[i].size / 10, angle); | |
cv::Rect2f rect(center.x - rcsq[i].size / 2, center.y - rcsq[i].size / 2, rcsq[i].size, rcsq[i].size); | |
faces.emplace_back(img, rect); | |
faces.back().pose.roll = angle; | |
faces.back().score = rcsq[i].quality; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment