Created
March 18, 2014 01:54
-
-
Save agustinhaller/9612151 to your computer and use it in GitHub Desktop.
face-crop
This file contains hidden or 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
| {% extends "layout.html" %} | |
| {% block main_content %} | |
| <div class="test-content"> | |
| <div class="main-wrapper"> | |
| {# Slogan #} | |
| <div class="slogan-container row"> | |
| <h2 class="main-slogan">Face Crop TESTS</h2> | |
| </div> | |
| {# Call to action #} | |
| <div class="test-container row"> | |
| <h2>Canvas Magic</h2> | |
| <canvas id="magic-canvas" width="300" height="300"></canvas> | |
| <h2>Faces</h2> | |
| <br> | |
| <ul class="cropped-faces-list"> | |
| </ul> | |
| <h2>Original Images</h2> | |
| <br> | |
| {% if IMAGES|length > 0 %} | |
| <ul class="results-list"> | |
| {% for image in IMAGES %} | |
| {% include "templates/website/face-crop-image.html" with { IMAGE: image} %} | |
| {% endfor %} | |
| </ul> | |
| {% else %} | |
| {% endif %} | |
| </div> | |
| </div> | |
| </div> | |
| {% endblock %} | |
| {% block scripts_bottom %} | |
| <script type="text/javascript" src="http://{{ DOMAIN_BASE }}/static/js/vendor/JSFeat/jsfeat-min.js"></script> | |
| <script type="text/javascript" src="http://{{ DOMAIN_BASE }}/static/js/vendor/JSFeat/frontalface.js"></script> | |
| <script> | |
| // Here goes the magic! | |
| $(document).ready(function(){ | |
| // Vamos a tener que tener un canvas auxiliar en donde vamos a ir cargando las imagenes a medida que iteramos | |
| var magic_canvas = $("#magic-canvas")[0], | |
| canvas_context = magic_canvas.getContext('2d'), | |
| $original_images = $(".results-list > li.sample-item img"), | |
| max_work_size = 160, | |
| canvasWidth = magic_canvas.width, | |
| canvasHeight = magic_canvas.height, | |
| classifier = jsfeat.haar.frontalface; | |
| canvas_context.fillStyle = "rgb(0,255,0)"; | |
| canvas_context.strokeStyle = "rgb(0,255,0)"; | |
| // Iterate over the images and try to crop the faces | |
| $original_images.each(function(){ | |
| var $original_image = $(this), | |
| original_image = $original_image[0], | |
| $img_aux = $("<img/>", {"class":"img_aux"}), | |
| img_aux = $img_aux[0]; | |
| $img_aux.on({ | |
| "load" : function(event, data){ | |
| var img = $(this)[0], | |
| img_width = img.width, | |
| img_height = img.height; | |
| // debugger; | |
| console.log("image:", $original_image.attr("src")); | |
| // Set canvas width and height equals to the image sizes | |
| magic_canvas.setAttribute('width', img_width); | |
| magic_canvas.setAttribute('height', img_height); | |
| // Fill canvas with image data | |
| canvas_context.drawImage(img, 0, 0, img_width, img_height); | |
| // Do JSFeat magic face cropping | |
| var scale = Math.min(max_work_size/img_width, max_work_size/img_height); | |
| var w = (img_width*scale)|0; | |
| var h = (img_height*scale)|0; | |
| img_u8 = new jsfeat.matrix_t(w, h, jsfeat.U8_t | jsfeat.C1_t); | |
| edg = new jsfeat.matrix_t(w, h, jsfeat.U8_t | jsfeat.C1_t); | |
| work_canvas = document.createElement('canvas'); | |
| work_canvas.width = w; | |
| work_canvas.height = h; | |
| work_ctx = work_canvas.getContext('2d'); | |
| ii_sum = new Int32Array((w+1)*(h+1)); | |
| ii_sqsum = new Int32Array((w+1)*(h+1)); | |
| ii_tilted = new Int32Array((w+1)*(h+1)); | |
| ii_canny = new Int32Array((w+1)*(h+1)); | |
| options = function(){ | |
| this.min_scale = 2; | |
| this.scale_factor = 1.15; | |
| this.use_canny = false; | |
| this.edges_density = 0.13; | |
| this.equalize_histogram = true; | |
| }; | |
| work_ctx.drawImage(img, 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, img_u8.data); | |
| // possible options | |
| if(options.equalize_histogram) | |
| { | |
| jsfeat.imgproc.equalize_histogram(img_u8, img_u8); | |
| } | |
| jsfeat.imgproc.compute_integral_image(img_u8, ii_sum, ii_sqsum, classifier.tilted ? ii_tilted : null); | |
| if(options.use_canny) | |
| { | |
| jsfeat.imgproc.canny(img_u8, edg, 10, 50); | |
| jsfeat.imgproc.compute_integral_image(edg, ii_canny, null, null); | |
| } | |
| jsfeat.haar.edges_density = options.edges_density; | |
| var rects = jsfeat.haar.detect_multi_scale(ii_sum, ii_sqsum, ii_tilted, options.use_canny? ii_canny : null, img_u8.cols, img_u8.rows, classifier, options.scale_factor, options.min_scale); | |
| rects = jsfeat.haar.group_rectangles(rects, 1); | |
| // debugger; | |
| // draw_faces(canvas_context, rects, canvasWidth/img_u8.cols, 1); | |
| crop_faces(canvas_context, rects, img_width/img_u8.cols, 1, img); | |
| } | |
| }); | |
| // First we need to get base64 iamge in order to avoid cross origin issues | |
| $.ajax({ | |
| url: 'http://{{ DOMAIN_BASE }}/parse-image-url', | |
| data: { image_url: $original_image.attr("src") }, | |
| type: 'POST', | |
| success: function (result) { | |
| // debugger; | |
| var result_json = JSON.parse(result); | |
| if(result_json.result == "OK") | |
| { | |
| $img_aux.attr("src", result_json.image_base64); | |
| } | |
| else | |
| { | |
| } | |
| }, | |
| complete: function() | |
| { | |
| } | |
| }); | |
| function crop_faces(ctx, rects, sc, max, imageObj) | |
| { | |
| var on = rects.length; | |
| if(on && max) | |
| { | |
| jsfeat.math.qsort(rects, 0, on-1, function(a,b){return (b.confidence<a.confidence);}) | |
| } | |
| var n = max || on; | |
| n = Math.min(n, on); | |
| var r; | |
| for(var i = 0; i < n; ++i) | |
| { | |
| r = rects[i]; | |
| var pos_x = (r.x*sc)|0, | |
| pos_y = (r.y*sc)|0, | |
| crop_width = (r.width*sc)|0, | |
| crop_height = (r.height*sc)|0; | |
| ctx.strokeRect(pos_x, pos_y, crop_width, crop_height); | |
| // Now create a new auxiliar canvas to crop the image | |
| var $canvas_aux = $("<canvas/>", {"class":"canvas_aux"}), | |
| canvas_aux = $canvas_aux[0], | |
| // $img_aux = $("<img/>", {"class":"cropped_img"}), | |
| // img_aux = $img_aux[0], | |
| context_aux = canvas_aux.getContext('2d'); | |
| var dest_width = 200, | |
| dest_height = 200; | |
| canvas_aux.width = dest_width; | |
| canvas_aux.height = dest_height; | |
| context_aux.drawImage(imageObj, pos_x, pos_y, crop_width, crop_height, 0, 0, dest_width, dest_height); | |
| // Convert image to gray scale | |
| var image_data = context_aux.getImageData(0, 0, dest_width, dest_height); | |
| for(var y = 0; y < image_data.height; y++) | |
| { | |
| for(var x = 0; x < image_data.width; x++) | |
| { | |
| var i = (y * 4) * image_data.width + x * 4; | |
| var avg = (image_data.data[i] + image_data.data[i + 1] + image_data.data[i + 2]) / 3; | |
| image_data.data[i] = avg; | |
| image_data.data[i + 1] = avg; | |
| image_data.data[i + 2] = avg; | |
| } | |
| } | |
| context_aux.putImageData(image_data, 0, 0, 0, 0, image_data.width, image_data.height); | |
| // var gray_img = new jsfeat.matrix_t(dest_width, dest_height, jsfeat.U8_t | jsfeat.C1_t); | |
| // jsfeat.imgproc.grayscale(image_data.data, gray_img.data); | |
| // render result back to canvas | |
| // var data_u32 = new Uint32Array(image_data.data.buffer); | |
| // var alpha = (0xff << 24); | |
| // var i = img_u8.cols*img_u8.rows, pix = 0; | |
| // debugger; | |
| // while(--i >= 0) { | |
| // pix = img_u8.data[i]; | |
| // data_u32[i] = alpha | (pix << 16) | (pix << 8) | pix; | |
| // } | |
| // context_aux.putImageData(image_data, 0, 0); | |
| // debugger; | |
| // Now get image data from auxiliar context | |
| // var type = image_type, | |
| var type = "image/jpeg", | |
| // Compress image to 85% | |
| // compress_ratio = 0.85, | |
| compress_ratio = 1, | |
| cropped_image_data = canvas_aux.toDataURL(type, compress_ratio); | |
| // Now set the image data as image source | |
| // $img_aux.attr("src", cropped_image_data); | |
| $(".cropped-faces-list").append('<li><img src="'+cropped_image_data+'"/></li>'); | |
| } | |
| } | |
| }); | |
| }); | |
| </script> | |
| {% endblock %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment