├── UFace
├── public
│ ├── images
│ │ ├── jz.png
│ │ └── face
│ │ │ ├── 1.jpg
│ │ │ └── timg.jpg
│ ├── files
│ │ ├── BI850i1k5ERRXh862wv2-jdl.jpg
│ │ ├── HqwCAAPIaJjHSyUEocoaUAJy.jpg
│ │ └── kQIVreuY3OtPDiUTu19eqNln.jpg
│ ├── stylesheets
│ │ └── style.css
│ └── js
│ │ └── index.js
├── views
│ ├── error.ejs
│ └── index.ejs
├── node_modules
│ └── baidu-ai
│ │ └── aip-node-sdk-1.1.0.zip
├── routes
│ ├── users.js
│ └── index.js
├── package.json
├── app.js
└── bin
│ └── www
└── README.md
/UFace/public/images/jz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/images/jz.png
--------------------------------------------------------------------------------
/UFace/public/images/face/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/images/face/1.jpg
--------------------------------------------------------------------------------
/UFace/views/error.ejs:
--------------------------------------------------------------------------------
1 |
<%= message %>
2 | <%= error.status %>
3 | <%= error.stack %>
4 |
--------------------------------------------------------------------------------
/UFace/public/images/face/timg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/images/face/timg.jpg
--------------------------------------------------------------------------------
/UFace/public/files/BI850i1k5ERRXh862wv2-jdl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/files/BI850i1k5ERRXh862wv2-jdl.jpg
--------------------------------------------------------------------------------
/UFace/public/files/HqwCAAPIaJjHSyUEocoaUAJy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/files/HqwCAAPIaJjHSyUEocoaUAJy.jpg
--------------------------------------------------------------------------------
/UFace/public/files/kQIVreuY3OtPDiUTu19eqNln.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/files/kQIVreuY3OtPDiUTu19eqNln.jpg
--------------------------------------------------------------------------------
/UFace/node_modules/baidu-ai/aip-node-sdk-1.1.0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/node_modules/baidu-ai/aip-node-sdk-1.1.0.zip
--------------------------------------------------------------------------------
/UFace/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
--------------------------------------------------------------------------------
/UFace/routes/users.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET users listing. */
5 | router.get('/', function(req, res, next) {
6 | res.send('respond with a resource');
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/UFace/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uface",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "dependencies": {
9 | "body-parser": "~1.17.1",
10 | "cookie-parser": "~1.4.3",
11 | "debug": "~2.6.3",
12 | "ejs": "~2.5.6",
13 | "express": "~4.15.2",
14 | "morgan": "~1.8.1",
15 | "serve-favicon": "~2.4.2",
16 | "multiparty": "latest"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/UFace/views/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= title %>
5 |
6 |
7 |
8 |
9 | <%= title %>
10 | Welcome to <%= title %>
11 |
15 |
16 |
17 |

18 |
![]()
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/UFace/public/js/index.js:
--------------------------------------------------------------------------------
1 | function uploadImg() {
2 | var formData = new FormData();
3 | formData.append("file", $("#upload")[0].files[0]);
4 | $.ajax({
5 | type: 'POST',
6 | url: './file/uploading',
7 | data: formData,
8 | processData: false,
9 | contentType: false,
10 | success: function(res) {
11 | var json = JSON.parse(res)
12 | if(json.result&&json.result.length>0) { //从后端获取到人脸检测到结果后,调用createFace函数,进行图片合成
13 | createFace(json);
14 | } else {
15 | alert("检测不到人脸,请上传符合规格的头像!")
16 | }
17 | }
18 | });
19 | };
20 |
21 | function createFace(data) {
22 | var jzimg = $('#jz')[0];
23 | var img = $('#target')[0];
24 | var canvas = $('#canvas')[0];
25 | var ctx = canvas.getContext('2d');
26 | var location = data.result[0]
27 | var sx = location.location.left,
28 | sy = location.location.top,
29 | swidth = location.location.width,
30 | sheight = location.location.height;
31 | img.src = data.imgSrc
32 | img.onload = function() { //异步
33 | ctx.drawImage(jzimg, 0, 0);
34 | ctx.drawImage(img, sx, sy, swidth, sheight, 210, 68, 70, 48);
35 | }
36 | };
--------------------------------------------------------------------------------
/UFace/app.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var path = require('path');
3 | var favicon = require('serve-favicon');
4 | var logger = require('morgan');
5 | var cookieParser = require('cookie-parser');
6 | var bodyParser = require('body-parser');
7 |
8 | var index = require('./routes/index');
9 | var users = require('./routes/users');
10 |
11 | var app = express();
12 |
13 | // view engine setup
14 | app.set('views', path.join(__dirname, 'views'));
15 | app.set('view engine', 'ejs');
16 |
17 | // uncomment after placing your favicon in /public
18 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
19 | app.use(logger('dev'));
20 | app.use(bodyParser.json());
21 | app.use(bodyParser.urlencoded({ extended: false }));
22 | app.use(cookieParser());
23 | app.use(express.static(path.join(__dirname, 'public')));
24 |
25 | app.use('/', index);
26 | app.use('/users', users);
27 |
28 | // catch 404 and forward to error handler
29 | app.use(function(req, res, next) {
30 | var err = new Error('Not Found');
31 | err.status = 404;
32 | next(err);
33 | });
34 |
35 | // error handler
36 | app.use(function(err, req, res, next) {
37 | // set locals, only providing error in development
38 | res.locals.message = err.message;
39 | res.locals.error = req.app.get('env') === 'development' ? err : {};
40 |
41 | // render the error page
42 | res.status(err.status || 500);
43 | res.render('error');
44 | });
45 |
46 | module.exports = app;
47 |
--------------------------------------------------------------------------------
/UFace/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET home page. */
5 | router.get('/', function(req, res, next) {
6 | res.render('index', { title: 'Express' });
7 | });
8 | router.post('/', function(req, res, next) {
9 | res.send('UFace post ok')
10 | });
11 |
12 |
13 | var AipFace = require("baidu-ai").face;
14 |
15 | var APP_ID = "9964551";
16 | var API_KEY = "fCTk95tO6MIKgROeBhBEigcD";
17 | var SECRET_KEY = "E8Ij9ftcDMhu5h2b898TzzYzem0161Dc";
18 | //这三个key记得替换为你申请的appid
19 |
20 | var client = new AipFace(APP_ID, API_KEY, SECRET_KEY);
21 |
22 | /*var fs = require('fs');
23 | var image = fs.readFileSync('./public/images/face/face.png');
24 | var base64Img = new Buffer(image).toString('base64');
25 |
26 | client.detect(base64Img).then(function(result) {
27 | console.log(JSON.stringify(result));
28 | });*/
29 |
30 | var multiparty = require('multiparty');
31 | var util=require('util');
32 | var fs = require('fs');
33 |
34 | router.post('/file/uploading', function(req, res, next) {
35 |
36 | var form = new multiparty.Form({
37 | uploadDir: './public/files/'
38 | });
39 |
40 | form.parse(req, function(err, fields, files) {
41 | var filesTmp = JSON.stringify(files, null, 2);
42 |
43 | if (err) {
44 | console.log('parse error: ' + err);
45 | } else {
46 | console.log('parse files: ' + filesTmp);
47 |
48 | var inputFile = files.file[0];
49 | var uploadedPath = inputFile.path;
50 |
51 | var image = fs.readFileSync(uploadedPath);
52 | var base64Img = new Buffer(image).toString('base64');
53 |
54 |
55 |
56 | client.detect(base64Img).then(function(result) {
57 | Object.assign(result, {
58 | imgSrc: uploadedPath.replace('public','').replace(/\\/g, '/')
59 | })
60 | res.send(JSON.stringify(result));
61 | });
62 |
63 | };
64 |
65 | });
66 |
67 | });
68 |
69 | module.exports = router;
70 |
--------------------------------------------------------------------------------
/UFace/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('uface:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # uface-baidu-ai
2 | 人民日报的换军装,利用了baidu-ai、canvas、node、express
3 |
4 | 主要参考:https://www.youyong.top/article/11597fcc6b4ee?yyfr=sf,这里大神有些小细节没有写,由于我还是小白,看了很久,才把代码全部写出来。因此写出了详细的步骤,有不懂的可以再私信我 bubucuovinci@163.com,目前只是写出了最简单的一部分,接下来再调整整体脸色。
5 |
6 | 环境搭建(主要来自https://www.youyong.top/article/11597fcc6b4ee?yyfr=sf,稍有补充):
7 | 1. express -e ejs UFace (没有express的需要事先安装),生成的package.json中最后加一个"multiparty": "latest",这个在最后上传图片(3.7步骤)的时候需要依赖。
8 | 2. 调通后端接口:
9 | 2.0 UFace目录下安装依赖文件,npm install,生成node_modules文件夹
10 | 2.1 找到 views/index.ejs 文件,添加
11 |
12 | 2.2 找到routes/index.js文件,添加
13 | router.post('/', function(req, res, next) {
14 | res.send('UFace post ok')
15 | });
16 |
17 | 2.3 终端输入 node bin/www
18 | 浏览器访问:http://localhost:3000/
19 |
20 | 2.4 打开开发者工具,在console里调试接口,输入:
21 | $.post("/", function(data) {
22 | console.log(data);
23 | });
24 | 看到控制台打印出:UFace post ok
25 | 自此,我们的前后端调通了。
26 | 3. 百度ai人脸识别环境补充
27 | 3.0 UFace/node_modules下面新建文件夹baidu-ai
28 | 3.1 下载node SDK压缩包,下载地址:http://ai.baidu.com/sdk#sdk-category-bfr
29 | 3.2 UFace/node_modules/baidu-ai下解压aip-node-sdk-1.1.0.zip,选择解压到当前文件夹即可,在该文件夹下npm install,安装sdk依赖库
30 | 3.3 在百度AI中申请好APPID;就是右上角的控制台处,然后页面下方点击人脸识别,创建应用或者管理应用。地址:https://console.bce.baidu.com/ai/?fromai=1#/ai/face/app/list
31 | 3.4 继续到routes/index.js文件中,加入
32 |
33 | var AipFace = require("baidu-ai").face;
34 |
35 | var APP_ID = "9964551";
36 | var API_KEY = "fCTk95tO6MIKgROeBhBEigcD";
37 | var SECRET_KEY = "E8Ij9ftcDMhu5h2b898TzzYzem0161Dc";
38 | //这三个key记得替换为你申请的appid
39 |
40 | var client = new AipFace(APP_ID, API_KEY, SECRET_KEY);
41 | (注意:routes中文件更改的话,node bin/www命令需重启)
42 | 3.5 上传本地的一张图片,调试下百度AI接口
43 |
44 | var fs = require('fs');
45 | var image = fs.readFileSync('./public/images/face/face.png');
46 | var base64Img = new Buffer(image).toString('base64');
47 |
48 | client.detect(base64Img).then(function(result) {
49 | console.log(JSON.stringify(result));
50 | });
51 | 终端打印出获取到的结果,接口获取成功。
52 | 3.6 找到 views/index.ejs 文件,添加
53 | 然后在javascripts中添加index.js文件,具体代码参看文件
54 | 3.7 找到routes/index.js文件,添加
55 | var multiparty = require('multiparty');
56 | var util=require('util');
57 | var fs = require('fs');
58 |
59 | router.post('/file/uploading', function(req, res, next) {
60 |
61 | var form = new multiparty.Form({
62 | uploadDir: './public/files/'
63 | });
64 |
65 | form.parse(req, function(err, fields, files) {
66 | var filesTmp = JSON.stringify(files, null, 2);
67 |
68 | if (err) {
69 | console.log('parse error: ' + err);
70 | } else {
71 | console.log('parse files: ' + filesTmp);
72 |
73 | var inputFile = files.file[0];
74 | var uploadedPath = inputFile.path;
75 |
76 | var image = fs.readFileSync(uploadedPath);
77 | var base64Img = new Buffer(image).toString('base64');
78 |
79 | client.detect(base64Img).then(function(result) {
80 | res.send(JSON.stringify(result));
81 | });
82 |
83 | };
84 |
85 | });
86 |
87 | });
88 | 3.8 UFace/public中新建files文件,存放生成的图片
89 | 3.9 UFace/public中我存放了一张脸部透明的军装照片,UFace/public/javascripts/index.js中参数是按照这张军装照片的写的,如果你想换照片,参数也需要更换。
90 | face文件夹中我存了两张大头贴,当然你也可以自己找图片。
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------