Created
November 23, 2016 15:20
-
-
Save PonDad/ecc0db7cd024cd3a6c13622a535a1b4f to your computer and use it in GitHub Desktop.
PonBot - face recognition
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
var express = require("express"); | |
var app = express(); | |
var path = require("path"); | |
var server = require('http').Server(app); | |
var io = require('socket.io')(server); | |
var fs = require('fs'); | |
var request = require('request'); | |
var five = require('johnny-five'); | |
var exec = require('child_process').exec; | |
var OpenJTalk = require('openjtalk'); | |
var mei = new OpenJTalk({ htsvoice: '/home/pi/ponbot04/node_modules/openjtalk/voice/mei/mei_happy.htsvoice' }); | |
var MeCab = new require('mecab-async') | |
var mecab = new MeCab(); | |
var array = []; | |
var reply = []; | |
var cv = require('opencv'); | |
var indico = require('indico.io'); | |
indico.apiKey = <API_KEY>; | |
var COLOR = [255, 255, 255]; // default red | |
var thickness = 2; // default 1 | |
server.listen(3000, function () { | |
console.log('listening on *:3000'); | |
}); | |
app.use(express.static(__dirname + '/public')); | |
app.get('/', function(req, res) { | |
res.sendFile(path.join(__dirname + '/index.html')); | |
}); | |
io.sockets.on('connection', function(socket) { | |
socket.on('chat_message', function(data) { | |
MeCab.command = "mecab -d /usr/lib/mecab/dic/mecab-ipadic-neologd" | |
MeCab.parseFormat(data, function(err, morphs) { | |
if (err) throw err; | |
morphs.map(function(morph) { | |
if (morph.lexical === '感動詞') { | |
array.push(morph.original); | |
reply = '!' | |
console.log(array); | |
io.emit('msg','shutter'); | |
} | |
if (morph.compound === '固有名詞') { | |
array.push(morph.original); | |
reply = 'っていいね。' | |
console.log(array); | |
io.emit('msg','action'); | |
} | |
if (morph.lexical === '形容詞' | morph.compound === '自立') { | |
array.push(morph.original); | |
console.log(array); | |
reply = 'よね。' | |
io.emit('msg','action'); | |
} | |
}); | |
if(array.length <= 0){ | |
bot_reply = 'そうなんだ。' ; | |
}else{ | |
bot_reply = array[Math.floor(Math.random() * array.length)] + reply; | |
} | |
mei.talk(bot_reply); | |
array = []; | |
reply = []; | |
}); | |
}); | |
socket.on('shutter', function () { | |
var raspistill = exec('raspistill -o ./public/images/output.jpg -h 480 -w 640 -t 100 -n'); | |
raspistill.on('close', function () { | |
console.log('写真を撮りました'); | |
}); | |
setTimeout(function () { | |
cv.readImage('./public/images/output.jpg', function(err, im) { | |
if (err) throw err; | |
if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size'); | |
im.detectObject('./node_modules/opencv/data/haarcascade_frontalface_alt2.xml', {}, function(err, faces) { | |
if (err) throw err; | |
for (var i = 0; i < faces.length; i++) { | |
face = faces[i]; | |
im.rectangle([face.x - 30, face.y - 30], [face.width + 60, face.height + 60], COLOR, 2); | |
} | |
im.save('./public/images/face.jpg'); | |
console.log('顔認識しました'); | |
fs.readFile('./public/images/face.jpg', function(err, buf){ | |
io.emit('image', { image: true, buffer: buf.toString('base64')}); | |
console.log('画像を送信します…'); | |
}); | |
}); | |
}); | |
cv.readImage('./public/images/output.jpg', function(err, im) { | |
if (err) throw err; | |
if (im.size()[0] > 0 && im.size()[1] > 0){ | |
im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){ | |
if (err) throw err; | |
if (!faces.length) return console.log("No Faces"); | |
var face = faces[0]; | |
var ims = im.size(); | |
var im2 = im.roi(face.x - 30, face.y - 30, face.width + 60, face.height + 60) | |
/* | |
im.adjustROI( | |
-face.y | |
, (face.y + face.height) - ims[0] | |
, -face.x | |
, (face.x + face.width) - ims[1]) | |
*/ | |
im2.save('./public/images/face_2.jpg') | |
console.log('顔認証を切り出しました'); | |
var filename = "./public/images/face_2.jpg" | |
var facepp = exec('curl -X POST "https://apicn.faceplusplus.com/recognition/identify?api_key=<API_KEY>&api_secret=<API_SECRET&group_name=pulp_fiction" -F "img=@' + filename + '"', | |
function (error, res) { | |
console.log(res) | |
var identify = JSON.parse(res) | |
var a = identify.face | |
var b = [] | |
var c = [] | |
for (var i = 0; i < a.length; i++) { | |
for (var j = 0; j < a[i]["candidate"].length; j++) { | |
b.push(a[i]["candidate"][j].person_name); | |
c.push(a[i]["candidate"][j].confidence); | |
}; | |
}; | |
if(c[0] > 10){ | |
console.log(b[0]) | |
console.log(c[0]) | |
io.sockets.emit('msg3', b[0] + ' : ' + c[0]); | |
io.emit('msg','action'); | |
if(b[0] === 'samuel'){ | |
mei.talk('サミュエル'); | |
}else if(b[0] === 'travolta'){ | |
mei.talk('トラボルタ'); | |
}else if(b[0] === 'pon_dad'){ | |
mei.talk('ポンダッド'); | |
} | |
} | |
var response = function(res) { | |
console.log(res); | |
var emotion =[res.Angry, res.Sad, res.Neutral, res.Surprise, res.Fear, res.Happy]; | |
var max_emotion = Math.max.apply(null, emotion); | |
if(max_emotion === res.Angry){ | |
console.log('angry : '+ res.Angry); | |
io.sockets.emit('msg2', 'angry : '+ res.Angry); | |
mei.talk('怒ってるの'); | |
}else if(max_emotion === res.Sad){ | |
console.log('sad : '+ res.Sad); | |
io.sockets.emit('msg2', 'sad : '+ res.Sad); | |
mei.talk('つまんないね'); | |
}else if(max_emotion === res.Neutral){ | |
console.log('neutral : '+ res.Neutral); | |
io.sockets.emit('msg2', 'neutral : '+ res.Neutral); | |
mei.talk('いいね'); | |
}else if(max_emotion === res.Surprise){ | |
console.log('surprise : '+ res.Surprise); | |
io.sockets.emit('msg2', 'surprise : '+ res.Surprise); | |
mei.talk('おどろいたね'); | |
}else if(max_emotion === res.Fear){ | |
console.log('fear : ' + res.Fear); | |
io.sockets.emit('msg2', 'fear : '+ res.Fear); | |
mei.talk('怖いね'); | |
}else if(max_emotion === res.Happy){ | |
console.log('happy : '+ res.Happy); | |
io.sockets.emit('msg2', 'happy : '+ res.Happy); | |
mei.talk('楽しいね'); | |
} | |
} | |
var logError = function(err) { console.log(err); } | |
var filename = "./public/images/face_2.jpg"; | |
fs.readFile(filename, function(err, data) { | |
base64data = new Buffer(data).toString('base64'); | |
indico.fer(base64data) | |
.then(response) | |
.catch(logError); | |
}); | |
if (error !== null) { | |
console.log('exec error: ' + error); | |
} | |
}); | |
}) | |
} else { | |
console.log("Camera didn't return image") | |
} | |
}); | |
}, 3000); | |
}); | |
}); | |
board = new five.Board(); | |
board.on("ready", function() { | |
var a = new five.Motor({ | |
controller: "GROVE_I2C_MOTOR_DRIVER", | |
pin: "A", | |
}); | |
var b = new five.Motor({ | |
controller: "GROVE_I2C_MOTOR_DRIVER", | |
pin: "B", | |
}); | |
/* | |
var proximity = new five.Proximity({ | |
controller: "HCSR04", | |
pin: 7 | |
}); | |
*/ | |
io.sockets.on('connection', function (socket) { | |
socket.on('click_servo_yes', function (degree_y) { | |
console.log('サーボ1: ' + degree_y); | |
var options_y = { | |
uri: 'https://us.wio.seeed.io/v1/node/GroveServoD1/angle/' + degree_y, | |
form: { access_token: '4e2b286ed9df49400201b233587011de' }, | |
json: true | |
}; | |
request.post(options_y, function(error, response, body){ | |
if (!error && response.statusCode == 200) { | |
} else { | |
console.log('error: '+ response.statusCode); | |
} | |
}); | |
}); | |
socket.on('click_servo_no', function (degree_n) { | |
console.log('サーボ0: ' + degree_n); | |
var options_n = { | |
uri: 'https://us.wio.seeed.io/v1/node/GroveServoD0/angle/' + degree_n, | |
form: { access_token: '4e2b286ed9df49400201b233587011de' }, | |
json: true | |
}; | |
request.post(options_n, function(error, response, body){ | |
if (!error && response.statusCode == 200) { | |
console.log(body); | |
} else { | |
console.log('error: '+ response.statusCode); | |
} | |
}); | |
}); | |
/* | |
proximity.on("data", function() { | |
console.log("cm: ", this.cm); | |
socket.emit('message', this.cm); | |
}); | |
*/ | |
socket.on('click_motor_forward', function () { | |
a.rev(252); | |
b.fwd(252); | |
setTimeout(function(){ | |
a.stop(); | |
b.stop(); | |
},500); | |
}); | |
socket.on('click_sound_robot', function () { | |
exec('aplay /home/pi/ponbot05/public/sounds/robot.wav', function(error, stdout, stderr) { | |
if (error != null) { | |
console.log(error); | |
} | |
}); | |
}); | |
socket.on('click_sound_shutter', function () { | |
exec('aplay /home/pi/ponbot05/public/sounds/shutter.wav', function(error, stdout, stderr) { | |
if (error != null) { | |
console.log(error); | |
} | |
}); | |
}); | |
socket.on('click_motor_stop', function () { | |
a.stop(); | |
b.stop(); | |
}); | |
socket.on('click_motor_right', function () { | |
a.rev(381); | |
b.rev(381); | |
setTimeout(function(){ | |
a.stop(); | |
b.stop(); | |
},300); | |
}); | |
socket.on('click_motor_right_turn', function () { | |
a.rev(381); | |
b.rev(381); | |
}); | |
socket.on('click_motor_left', function () { | |
a.fwd(381); | |
b.fwd(381); | |
setTimeout(function(){ | |
a.stop(); | |
b.stop(); | |
},300); | |
}); | |
socket.on('click_motor_left_turn', function () { | |
a.fwd(381); | |
b.fwd(381); | |
}); | |
socket.on('click_motor_backward', function () { | |
a.fwd(252); | |
b.rev(252); | |
setTimeout(function(){ | |
a.stop(); | |
b.stop(); | |
},500); | |
}); | |
}); | |
}); |
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
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="utf-8"> | |
<title>PonBot03</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> | |
<link href="https://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet"> | |
<link rel="stylesheet" href="css/style.css"> | |
</head> | |
<body> | |
<article> | |
<h1>PonBot05</h1> | |
<article> | |
<div id="container"> | |
<img class="img-responsive" id="image"> | |
<br> | |
<p id="massage3"></p> | |
<p id="massage2"></p> | |
</div> | |
<div class="spinner"> | |
<div class="bounce1"></div> | |
<div class="bounce2"></div> | |
<div class="bounce3"></div> | |
</div> | |
</article> | |
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script> | |
<script src="http://code.jquery.com/jquery-1.11.1.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/annyang/2.4.0/annyang.min.js"></script> | |
<script> | |
$(document).ready(function() { | |
var socket = io.connect('http://192.168.0.11'); | |
if (annyang) { | |
var commands = {'*i': function() {console.log("実行")}}; | |
annyang.setLanguage('ja-JP') | |
annyang.addCommands(commands); | |
annyang.start(); | |
console.log('録音開始'); | |
annyang.addCallback('resultMatch', function(userSaid) { | |
console.log('録音: ' + userSaid); | |
socket.emit('chat_message', userSaid); | |
}); | |
}; | |
socket.on('msg', function(msg) { | |
if(msg === 'action'){ | |
console.log('アクション'); | |
setTimeout(function(){ | |
socket.emit('click_sound_robot'); | |
socket.emit('click_servo_yes',60); | |
socket.emit('click_motor_left'); | |
setTimeout(function(){ | |
socket.emit('click_servo_yes',120); | |
socket.emit('click_motor_right'); | |
setTimeout(function(){ | |
socket.emit('click_servo_yes',60); | |
socket.emit('click_motor_left'); | |
setTimeout(function(){ | |
socket.emit('click_servo_yes',120); | |
socket.emit('click_motor_right'); | |
setTimeout(function(){ | |
socket.emit('click_servo_yes',80); | |
socket.emit('click_servo_no',90); | |
},1500); | |
},1200); | |
},900); | |
},600); | |
},300); | |
}else if(msg === 'shutter'){ | |
console.log('シャッター'); | |
socket.emit('shutter'); | |
socket.emit('click_sound_shutter'); | |
} | |
}); | |
socket.on('image', function(face) { | |
$("#image").attr('src', 'data:image/jpg;base64,' + face.buffer ); | |
}); | |
socket.on('msg3', function(massage3) { | |
$("#massage3").text(massage3); | |
}); | |
socket.on('msg2', function(massage2) { | |
$("#massage2").text(massage2); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
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
{ | |
"name": "ponbot05", | |
"version": "1.0.0", | |
"main": "app.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "pon_dad", | |
"license": "ISC", | |
"dependencies": { | |
"express": "^4.14.0", | |
"indico.io": "^0.10.5", | |
"johnny-five": "^0.10.3", | |
"mecab-async": "^0.1.0", | |
"opencv": "^6.0.0", | |
"openjtalk": "^0.1.6", | |
"request": "^2.76.0", | |
"socket.io": "^1.5.1" | |
}, | |
"devDependencies": {}, | |
"description": "" | |
} |
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
body{ | |
font-family: 'Orbitron', sans-serif; | |
background-color: #3D8EB9; | |
color: #f6f6f6; | |
max-width: 480px; | |
margin: 0 auto;; | |
padding: 20px; | |
} | |
.btn-group-width{ | |
max-width: 250px; | |
margin: 0 auto; | |
} | |
.spinner { | |
margin: 100px auto 0; | |
width: 70px; | |
text-align: center; | |
} | |
.spinner > div { | |
width: 18px; | |
height: 18px; | |
background-color: #f6f6f6; | |
border-radius: 100%; | |
display: inline-block; | |
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both; | |
animation: sk-bouncedelay 1.4s infinite ease-in-out both; | |
} | |
.spinner .bounce1 { | |
-webkit-animation-delay: -0.32s; | |
animation-delay: -0.32s; | |
} | |
.spinner .bounce2 { | |
-webkit-animation-delay: -0.16s; | |
animation-delay: -0.16s; | |
} | |
@-webkit-keyframes sk-bouncedelay { | |
0%, 80%, 100% { -webkit-transform: scale(0) } | |
40% { -webkit-transform: scale(1.0) } | |
} | |
#caption{ | |
margin-top: 20px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment