This article is considered as an advanced step in implementing face recognition with HTML5. Based on face recognition, we will use pure JavaScript to implement the following functions:
- Recognize and Mark faces and facial features
From the content in this article, you will realize that javascript can do much better than you think.
Demo
I. Implementation
1. Face Recognition
Face.com has multiple API interfaces including detection and recognition. According to the Article "Implementing face recognition with HTML5", we can upload images and obtain the detection results. The results are as follows:
Returned Parameters
For more information about the returned parameters, see callback.
The code for uploading images and requesting interfaces is as follows.
Function buildrequest (imgsrc) {<br/> document. getelementbyid ("detect "). disabled = true; <br/> document. getelementbyid ("beauty "). disabled = true; </P> <p> var canvas = document. getelementbyid ('canvas '); <br/> var CTX = canvas. getcontext ('2d '); </P> <p> var imgobj = new image (); <br/> imgobj. src = imgsrc; <br/> canvas. width = imgobj. width; <br/> canvas. height = imgobj. height; <br/> CTX. drawimage (I Mgobj, 0, 0); <br/> var imgpixels = CTX. getimagedata (0, 0, canvas. width, canvas. height); </P> <p> document. getelementbyid ("bigimg "). style. width = imgobj. width; </P> <p> var DATA = canvas. todataurl ('image/JPEG ', 1.0); <br/> newblob = datauritoblob (data); </P> <p> var formdata = new formdata (); <br/> formdata. append ("api_key", "your key"); <br/> formdata. append ("api_secret", "Your Secret"); <br/> F Ormdata. append ("FILENAME", "avatar.jpg"); </P> <p> formdata. append ("file", newblob); </P> <p> $. ajax ({<br/> URL: 'http: // api.face.com/faces/detect.json? Attributes = age_est, gender, mood, smiling, glas', <br/> data: formdata, <br/> cache: false, <br/> contenttype: false, <br/> processdata: false, <br/> datatype: "JSON", <br/> type: 'post', <br/> success: function (data) {<br/> handleresult (data. photos [0]); <br/>}< br/>}); <br/>}
Face tagging
We will mark the facial feature and face based on the facial recognition results. There are two tagging Methods: canvas-Based Drawing and div-based tagging. The following uses the second method. The principle is to draw a 3*3 Div on each vertex. the background color of the DIV is red and the absolute position is used. The facial feature value returned by the API is the percentage value of the point where the width and height are located. Therefore, you must convert the value first.
The method for adding a facial feature is as follows:
Function drawfacial (data) {<br/> var width = data. width; <br/> var Height = data. height; </P> <p> var points = ["eye_left", "eye_right", "mouth_left", "mouth_center", "mouth_right", "nose ", "ear_left", "ear_right"]; </P> <p> for (VAR I = 0; I <points. length; I ++) {<br/> var DIV = document. createelement ('div '); <br/> Div. style. width = "3px"; <br/> Div. style. height = "3px"; <br/> Div. style. backgroundco Lor = "red"; <br/> Div. style. position = "absolute"; <br/> Div. classname = "facepoint"; </P> <p> VaR values = data. tags [0] [points [I]; </P> <p> If (values! = NULL) {<br/> var left_x = values. x; <br/> Div. style. left = left_x * width/100-1 + "PX"; <br/> var left_y = values. y; <br/> Div. style. top = left_y * Height/100-1 + "PX"; </P> <p> document. body. appendchild (DIV); <br/>}< br/>}
The method to mark a face area is as follows:
Function drawface (data) {<br/> var width = data. width; <br/> var Height = data. height; </P> <p> var facewidth = data. tags [0]. width * width/100; <br/> var faceheight = data. tags [0]. height * Height/100; <br/> var facecenter = data. tags [0]. center; </P> <p> var DIV = document. createelement ('div '); <br/> Div. style. width = facewidth + "PX"; <br/> Div. style. height = faceheight + "PX"; <br/> Div. style. bordercolor = "red"; <br/> Div. style. borderwidth = "1px"; <br/> Div. style. borderstyle = "dotted"; <br/> Div. style. position = "absolute"; <br/> Div. classname = "facebox"; </P> <p> Div. style. left = facecenter. x * width/100-facewidth/2-1 + "PX"; <br/> Div. style. top = facecenter. y * Height/100-faceheight/2-1 + "PX"; </P> <p> document. body. appendchild (DIV); <br/>}
From the results, face.com's detection results are very accurate.
Face beauty
For the face, we use two kinds of overlapping effects for beauty, which are to increase the brightness and blur, so that the face can look white and the skin is better.
1. Increase brightness
Adding brightness is actually very simple. You only need to add a fixed value on the RGB channel of the pixel. The Code is as follows:
VaR imgpixels = CTX. getimagedata (faceleft, facetop, facewidth, faceheight); </P> <p> var DATA = imgpixels. data; <br/> adjustment = 5; </P> <p> for (VAR I = 0; I <data. length; I + = 4) {<br/> data [I] + = adjustment; <br/> data [I + 1] + = adjustment; <br/> data [I + 2] + = adjustment; <br/>}
2. Add the blur effect
The Blur effect is complex. We usually use mean blur and Gaussian blur. In html5rocks, there is a great article "image filterswith canvas", which contains various image processing effects. We can directly apply the fuzzy effects (that is, the mean blur of 3x3 ).
Source image
Sharpen
Sopell Filter
The Code is as follows:
VaR filters ={}; </P> <p> filters. convolute = function (pixels, weights, opaque) {<br/> var side = math. round (math. SQRT (weights. length); <br/> var halfside = math. floor (side/2); <br/> var src = pixels. data; <br/> var Sw = pixels. width; <br/> var SH = pixels. height; <br/> // pad output by the convolution matrix <br/> var W = Sw; <br/> var H = sh; <br/> var output = filters. createimagedata (W, H); <br/> Var DST = output. Data; <br/> // go through the destination image pixels <br/> var alphafac = opaque? 1: 0; <br/> for (var y = 0; y <p; y ++) {<br/> for (VAR x = 0; x <W; X ++) {<br/> var Sy = y; <br/> var SX = x; <br/> var dstoff = (y * w + x) * 4; <br/> // calculate the weighed sum of the source image pixels that <br/> // fall under the convolution matrix <br/> var r = 0, G = 0, B = 0, a = 0; <br/> for (VAR Cy = 0; CY <side; CY ++) {<br/> for (VAR Cx = 0; CX <side; CX ++) {<br/> var SCY = SY + cy-halfside; <br/> var SCX = SX + cx-halfside; <br/> If (SCY> = 0 & SCY <sh & SCX> = 0 & SCX <SW) {<br/> var srcoff = (SCY * SW + SCX) * 4; <br/> var Wt = weights [CY * side + cx]; <br/> r + = SRC [srcoff] * wt; <br/> G + = SRC [srcoff + 1] * wt; <br/> B + = SRC [srcoff + 2] * wt; <br/> A + = SRC [srcoff + 3] * wt; <br/>}< br/> DST [dstoff] = r; <br/> DST [dstoff + 1] = g; <br/> DST [dstoff + 2] = B; <br/> DST [dstoff + 3] = a + alphafac * (255-a ); <br/>}< br/> return output; <br/>}; </P> <p> filters. tmpcanvas = document. createelement ('canvas '); <br/> filters. tmpctx = filters. tmpcanvas. getcontext ('2d '); </P> <p> filters. createimagedata = function (W, h) {<br/> return this. tmpctx. createimagedata (W, H); <br/> };
The code for adding two effects to the image in the canvas is as follows:
VaR width = data. width; <br/> var Height = data. height; </P> <p> var facewidth = data. tags [0]. width * width/100; <br/> var faceheight = data. tags [0]. height * Height/100; <br/> var facecenter = data. tags [0]. center; </P> <p> var faceleft = facecenter. x * width/100-facewidth/2; <br/> var facetop = facecenter. y * Height/100-faceheight/2; </P> <p> var canvas = document. getelementbyid ('canvas '); <br/> var CTX = canvas. getcontext ('2d '); <br/> var imgpixels = CTX. getimagedata (faceleft, facetop, facewidth, faceheight); </P> <p> var DATA = imgpixels. data; <br/> adjustment = 5; </P> <p> for (VAR I = 0; I <data. length; I + = 4) {<br/> data [I] + = adjustment; <br/> data [I + 1] + = adjustment; <br/> data [I + 2] + = adjustment; <br/>}< br/> imgpixels = filters. convolute (imgpixels, [1/9, 1/9, 1/9, <br/> 1/9, 1/9, 1/9, 1/9, 1/9], 1 ); </P> <p> CTX. putimagedata (imgpixels, faceleft, facetop, 1, 1, facewidth-3, faceheight-3 );
In this way, we have completed all the code. Is it quite a sense of accomplishment? It seems that we have completed a very novel and cool job.
Ii. Thinking
1. Are there other ways to implement beauty filters?
Previously, I introduced css3 filters, which have two methods: blur and brightness adjustment. You can easily add filter effects to images and learn about them in the article "Meet css3 filter.
2. What beauty effects can we achieve?
1) Remove the redeye
After detecting the eye position, we can use a filter within a certain range to convert the red in this range to black, so as to achieve the effect of removing the red eye.
2) Eye enlargement
After detecting the eye position, we can also use certain algorithms to achieve eye enlargement. To experience this effect, you can download the Baidu magic graph client.
Baidu magic map-powerful image processing client
3) virtual background
The background blur effect is basically the opposite of the effect we mentioned in this article.
3. Can the effects in the text be optimized?
For example, can I change the beauty area in the text into an elliptical shape closer to the face shape? In fact, it is not difficult. If you are interested, you can think deeply and implement it.
4. What other functions can we accomplish in addition to beauty?
Face.com provides three demonstration functions: Face tag, scene photo, and face search. For application developers, there is no lack of creativity. For example, parameters returned by face.com image moderation include the image rotation angle, we can use this parameter to enable automatic rotation of images in batches (I recently understood the convenience and necessity of this feature when organizing travel photos ). Or Weibo-based image and love matching apps? I look forward to the emergence of more creative and useful idea.
Additional reading
- Meet css3 Filter
- How to Use HTML5 to upload photos
- Create a grayscale gradient effect for a cool image using HTML5
This article is from Jiang Yujie's blog. For more information, see.