-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated jsfeat, always use working canvas for face detection, add opt…
…ions for controlling detection
- Loading branch information
1 parent
9ff0c47
commit b44cc23
Showing
6 changed files
with
175 additions
and
176 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,68 @@ | ||
// simple wrapper for jsfeat face detector | ||
// requires jsfeat | ||
|
||
var jsfeat_face = function(image) { | ||
|
||
var img_u8,work_canvas,work_ctx,ii_sum,ii_sqsum,ii_tilted,edg; | ||
|
||
var w = image.width; | ||
var h = image.height; | ||
|
||
if (image.tagName == 'VIDEO' || image.tagName == 'IMG') { | ||
work_canvas = document.createElement('canvas'); | ||
work_canvas.height = h; | ||
work_canvas.width = w; | ||
work_ctx = work_canvas.getContext('2d'); | ||
} else if (image.tagName == 'CANVAS') { | ||
work_ctx = image.getContext('2d'); | ||
} | ||
|
||
img_u8 = new jsfeat.matrix_t(w, h, jsfeat.U8_t | jsfeat.C1_t); | ||
ii_sum = new Int32Array((w+1)*(h+1)); | ||
ii_sqsum = new Int32Array((w+1)*(h+1)); | ||
ii_tilted = new Int32Array((w+1)*(h+1)); | ||
|
||
var jsfeat_face = function(video, maxWorkSize) { | ||
var videoWidth = video.width; | ||
var videoHeight = video.height; | ||
|
||
var classifier = jsfeat.haar.frontalface; | ||
|
||
this.findFace = function (minScale) { | ||
if (image.tagName == 'VIDEO' || image.tagName == 'IMG') { | ||
work_ctx.drawImage(image, 0, 0); | ||
} | ||
var imageData = work_ctx.getImageData(0, 0, w, h); | ||
|
||
jsfeat.imgproc.grayscale(imageData.data, img_u8.data); | ||
|
||
jsfeat.imgproc.equalize_histogram(img_u8, img_u8); | ||
|
||
jsfeat.imgproc.compute_integral_image(img_u8, ii_sum, ii_sqsum, null); | ||
|
||
var rects = jsfeat.haar.detect_multi_scale(ii_sum, ii_sqsum, ii_tilted, null, img_u8.cols, img_u8.rows, classifier, 1.15, minScale); | ||
|
||
var scale = Math.min(maxWorkSize/videoWidth, maxWorkSize/videoHeight); | ||
var w = (videoWidth*scale)|0; | ||
var h = (videoHeight*scale)|0; | ||
|
||
var img_u8 = new jsfeat.matrix_t(w, h, jsfeat.U8_t | jsfeat.C1_t); | ||
var edg = new jsfeat.matrix_t(w, h, jsfeat.U8_t | jsfeat.C1_t); | ||
var work_canvas = document.createElement('canvas'); | ||
work_canvas.width = w; | ||
work_canvas.height = h; | ||
var work_ctx = work_canvas.getContext('2d'); | ||
var ii_sum = new Int32Array((w+1)*(h+1)); | ||
var ii_sqsum = new Int32Array((w+1)*(h+1)); | ||
var ii_tilted = new Int32Array((w+1)*(h+1)); | ||
var ii_canny = new Int32Array((w+1)*(h+1)); | ||
|
||
this.findFace = function (params) { | ||
work_ctx.drawImage(video, 0, 0, work_canvas.width, work_canvas.height); | ||
var imageData = work_ctx.getImageData(0, 0, work_canvas.width, work_canvas.height); | ||
|
||
jsfeat.imgproc.grayscale(imageData.data, work_canvas.width, work_canvas.height, img_u8); | ||
|
||
// possible params | ||
if(params.equalizeHistogram) { | ||
jsfeat.imgproc.equalize_histogram(img_u8, img_u8); | ||
} | ||
//jsfeat.imgproc.gaussian_blur(img_u8, img_u8, 3); | ||
|
||
jsfeat.imgproc.compute_integral_image(img_u8, ii_sum, ii_sqsum, classifier.tilted ? ii_tilted : null); | ||
|
||
if(params.useCanny) { | ||
jsfeat.imgproc.canny(img_u8, edg, 10, 50); | ||
jsfeat.imgproc.compute_integral_image(edg, ii_canny, null, null); | ||
} | ||
|
||
jsfeat.haar.edgesDensity = params.edgesDensity; | ||
var rects = jsfeat.haar.detect_multi_scale(ii_sum, ii_sqsum, ii_tilted, params.useCanny? ii_canny : null, img_u8.cols, img_u8.rows, classifier, params.scaleFactor, params.minScale); | ||
rects = jsfeat.haar.group_rectangles(rects, 1); | ||
|
||
var rl = rects.length; | ||
|
||
if (rl > 0) { | ||
var best = rects[0]; | ||
for (var i = 1;i < rl;i++) { | ||
if (rects[i].neighbors > best.neighbors) { | ||
best = rects[i] | ||
} else if (rects[i].neighbors == best.neighbors) { | ||
if (rects[i].confidence > best.confidence) best = rects[i]; | ||
} | ||
} | ||
return [best]; | ||
} else { | ||
|
||
if(rl == 0) { | ||
return false; | ||
} | ||
|
||
var best = rects[0]; | ||
for (var i = 1; i < rl; i++) { | ||
if (rects[i].neighbors > best.neighbors) { | ||
best = rects[i] | ||
} else if (rects[i].neighbors == best.neighbors) { | ||
// if (rects[i].width > best.width) best = rects[i]; // use biggest rect | ||
if (rects[i].confidence > best.confidence) best = rects[i]; // use most confident rect | ||
} | ||
} | ||
|
||
var sc = videoWidth / img_u8.cols; | ||
best.x = (best.x*sc)|0; | ||
best.y = (best.y*sc)|0; | ||
best.width = (best.width*sc)|0; | ||
best.height = (best.height*sc)|0; | ||
|
||
return best; | ||
} | ||
|
||
} |
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