基于百度AI的人脸识别及语音合成课题
课题需求
(1)人脸识别
在Web界面上传人的照片,后台使用Java技术接收图片,然后对图片进行解码,调用云平台接口识别人脸特征,接收平台返回的人员年龄、性别、颜值等信息,将信息返回到Web界面进行显示。
(2)人脸比对
在Web界面上传两张人的照片,后台使用Java技术接收图片,然后对图片进行解码,调用云平台接口比对照片信息,返回相似度。
(3)语音识别
在Web页面上传语音文件,判断语音文件格式,如果不是wav格式进行转码处理,然后调用平台接口进行识别,最后将识别的文本内容返回到Web界面进行显示。
(4)语音合成
在Web界面上传文本内容和语音类型,后台接收文本内容和语音类型后,调用平台接口生成语音数据,最后将数据转码成mp3格式文件,Web界面可以下载到本地。
课题设计
课题基于客户端—服务端-平台端构架,客户端主要实现功能界面展示、数据上传和处理结果展示;服务器端接收客户端数据、数据转码处理、平台接口调用、请求结果相应;平台端介绍服务端数据、人脸识别、人脸比对、语音识别、语音合成等。
总体架构
总体逻辑
前端设计(包括首页、人脸检测、人脸对比、语音识别及语音合成)
index.html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>人工智能 未来已来</title>
<link rel="stylesheet" href="css/button.min.css" />
<link rel="stylesheet" href="css/style.css" />
<script type='text/javascript' src='js/jquery-1.11.1.min.js'></script>
<script type='text/javascript' src='js/jquery.particleground.min.js'></script>
<script type='text/javascript' src='js/ai.js'></script>
</head>
<body>
<div id="context">
<div class="intro">
<div class="position">
<h1>人工智能 未来已来</h1>
<!--start button, nothing above this is necessary -->
<div class="svg-wrapper">
<svg height="140" width="450" xmlns="http://www.w3.org/2000/svg">
<rect id="shape" height="140" width="300" />
<div id="text">
<a href="face_recognition.html"><span class="spot"></span>人脸检测</a>
</div>
</svg>
</div>
<div class="svg-wrapper">
<svg height="140" width="450" xmlns="http://www.w3.org/2000/svg">
<rect id="shape" height="140" width="300" />
<div id="text">
<a href="face_match.html"><span class="spot"></span>人脸比对</a>
</div>
</svg>
</div>
<!--Next button -->
<div class="svg-wrapper">
<svg height="140" width="450" xmlns="http://www.w3.org/2000/svg">
<rect id="shape" height="140" width="300" />
<div id="text">
<a href="speech_recognition.html"><span class="spot"></span>语音识别</a>
</div>
</svg>
</div>
<!--Next button -->
<div class="svg-wrapper">
<svg height="140" width="450" xmlns="http://www.w3.org/2000/svg">
<rect id="shape" height="140" width="300" />
<div id="text">
<a href="speech_produce.html"><span class="spot"></span>语音合成</a>
</div>
</svg>
</div>
<!--End button -->
</div>
</div>
</div>
</body>
</html>
face_recognition.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>人脸识别</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<script src="js/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.particleground.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/ai.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<style type="text/css">
.cent_bg {
width: 80%;
height: 22em;
border: 1px solid rgba(255, 255, 255, 0.5);
margin: auto;
padding: 3% 6%;
border-radius: 10%;
font-size: 1.5em;
line-height: 2em;
position: relative;
}
.cent {
margin-top: 1.5em;
overflow-y: auto;
height: 80%;
text-indent: 2em;
text-align: left;
padding-right: 0.2em;
}
::-webkit-scrollbar {
width: 10px;
background-color: rgba(255,255,255,0.2);
}
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
border-radius: 5px;
background-color: transparent;
}
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: rgba(255,255,255,0.7);
}
.btn{
margin-top: 20px;
width: 70%;
height:80px;
transition: 0.4s;
border-radius: 1em;
border: 1px solid rgba(255, 255, 255, 0.5);
border-top:none;
z-index: 66;
background: rgba(255, 255, 255, 0.2);
}
.btn:hover{
border: 1px solid rgba(255, 255, 255, 0.8) !important;
border-top:none !important;
}
.btn span{
width: 40%;
height: 84%;
margin-top:6px;
line-height: 38px;
display: inline-block;
border: 1px solid #009FFD;
color: #fff;
background: rgba(255,255,255,0.4);
border-radius: 4px;
cursor: pointer;
}
.btn span:nth-of-type(1){
margin-right: 15px;
}
.btn span:nth-of-type(2){
margin-left: 15px;
}
.img{
width: 70%;
height: 100%;
float: left;
position: relative;
}
.xinxi{
width: 30%;
height: 100%;
float: left;
}
.biankuang{
width: 92%;
height: 150%;
top: -100px;
position: absolute;
background: url(img/biankuang.png) no-repeat;
background-size: 100% 100%;
}
.xinxi{
text-align: left;
}
.xinxi span{
margin-top: 50px;
}
.xinxi span a{
color: #FFFFFF;
text-decoration: none;
}
#neirong{
color: red;
}
</style>
</head>
<body>
<div id="context">
<div class="intro">
<div class="cent_bg">
<div class="img">
<div class="biankuang">
<img src="img/img111.jpg" id='img' style="width: 83%;height: 55%;position: absolute;left: 49px;top: 150px;"/>
</div>
</div>
<div class="xinxi">
<span style="display: block;">性别:<a href="" id="sex"></a></span>
<span style="display: block;">年龄:<a href="" id="age"></a><span style="margin-left: 10px;">岁</span></span>
<span style="display: block;">表情:<a href="" id="expression"></a></span>
<span style="display: block;">颜值:<a href="" id="beauty"></a></span>
<span style="display: block;"><a href="" id="neirong"></a></span>
</div>
</div>
<div class="btn">
<form id="renlian" method="post">
<span style="position: relative;">提交图片
<input type="file" name="image" value="" id="uploading" onchange="test()" style="opacity: 0;width: 100%;position: absolute;height: 100%;display: block;top: 0px;" />
</span>
<span id="tijiao">开始识别</span>
</form>
</div>
</div>
</div>
</body>
</html>
<script type="text/javascript">
function test() {
var file = document.getElementById("uploading").files[0];
var fr = new FileReader;
var filePath = document.querySelector("#uploading").value;
fileFormat = filePath.substring(filePath.lastIndexOf(".")).toLowerCase();
if(!fileFormat.match(/.png|.jpg|.jpeg/)) {
alert('上传错误,文件格式必须为:png/jpg/jpeg');
return;
} else {
fr.readAsDataURL(file);
fr.onload = function(e) {
document.getElementById("img").src = this.result;
}
}
}
$("#tijiao").click(function() {
$.ajax({
type: "post",
url: basePath + "/FaceDetect",
dataType: "json",
data: new FormData($('#renlian')[0]),
processData: false,
contentType: false,
beforeSend: function() {
uploading = true;
},
success: function(res) {
if(res.status=="200"){
$("#neirong").text("");
$("#sex").text(res.data.gender);
$("#age").text(res.data.age);
$("#expression").text(res.data.expression);
$("#beauty").text(res.data.beauty);
}else{
$("#neirong").text("无法识别");
}
},
error(xhr,status,error){
$("#neirong").text("后台服务异常");
return;
}
})
})
</script>
face_match.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>人脸比对</title>
<script src="js/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.particleground.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/ai.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<style type="text/css">
#dianji:hover{
transition: 0.5s;
background: skyblue;
}
.sss{
display: inline-block;
line-height:100px ;
border-radius: 100%;
width: 200px;
margin: auto;
height: 200px;
border: 1px solid white;
margin-top: 10%;
}
</style>
</head>
<body>
<div id="context">
<div class="intro">
<div style="overflow: hidden; position: relative;top: 40%; overflow: hidden;margin: auto;text-align: center;">
<div style="border: 1px solid white; width: 30%; height: 400px; float: left;"><img id="ig1" src="" alt="" style="width: 100%; height: 100%"/></div>
<div class="sss">相似度</div>
<div style="border: 1px solid white; width: 30%; height: 400px; float: right;"><img id="ig2" src="" alt="" style="width: 100%; height: 100%;"/></div>
</div>
<form id="tttt" method="post" style="width: 80%; margin:40px auto;">
<div style="width: 40%;float: left; position: relative;">
<span style="position: absolute;left: 0px;background: skyblue;display: inline-block;height: 40px;line-height: 40px;width: 160px;">
点击上传
</span>
<input style="opacity: 0; position: absolute;left: 0px; height: 40px;" id="uploading" type="file" onchange="upload1()" name="image1">
</div>
<div style="float: right;bwidth: 40%;float: right;position: relative;">
<span id="" style="position: absolute;right: 0px;background: skyblue;display: inline-block;height: 40px;line-height: 40px;width: 160px;">
点击上传
</span>
<input id="up" type="file" onchange="upload2()" name="image2" style="opacity: 0; position: absolute;right: 0px; height: 40px;" >
</div>
</form>
<div id="dianji" style="border: 1px solid white;width: 140px;height: 40px;line-height: 40px;border-radius: 15px; margin: auto;">开始比对</div>
</div>
</div>
</body>
<script type="text/javascript">
function upload1() {
var file = document.getElementById("uploading").files[0];
var fr = new FileReader;
var filePath = document.querySelector("#uploading").value;
fileFormat = filePath.substring(filePath.lastIndexOf(".")).toLowerCase();
if(!fileFormat.match(/.png|.jpg|.jpeg/)) {
alert('上传错误,文件格式必须为:png/jpg/jpeg');
return;
} else {
fr.readAsDataURL(file);
fr.onload = function(e){
document.getElementById("ig1").src = this.result;
}
}
}
function upload2() {
var file = document.getElementById("up").files[0];
var fr = new FileReader;
var filePath = document.querySelector("#up").value;
fileFormat = filePath.substring(filePath.lastIndexOf(".")).toLowerCase();
if(!fileFormat.match(/.png|.jpg|.jpeg/)) {
alert('上传错误,文件格式必须为:png/jpg/jpeg');
return;
} else {
fr.readAsDataURL(file);
fr.onload = function(e){
document.getElementById("ig2").src = this.result;
}
}
}
$(function() {
$("#dianji").click(function() {
$.ajax({
url: basePath+"/FaceMatch",
type: 'post',
cache: false,
data: new FormData($('#tttt')[0]),
processData: false,
contentType: false,
dataType: "json",
beforeSend: function() {
uploading = true;
},
success: function(data) {
if(data.status==200){
document.querySelector(".sss").innerHTML="相似度<br>"+data.data.score;
}else{
$(".sss").html("相似度<br><span style='color:red'>"+data.msg+"</span>");
}
},
error(xhr,status,error){
$(".sss").html("相似度<br><span style='color:red'>后台服务异常</span>");
return;
}
});
});
});
</script>
</html>
speech_recognition.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>语音识别</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<script src="js/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.particleground.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/ai.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<style type="text/css">
.cent_bg {
width: 80%;
height: 22em;
border: 1px solid rgba(255, 255, 255, 0.5);
margin: auto;
padding: 3% 6%;
border-radius: 10%;
font-size: 1.5em;
line-height: 2em;
position: relative;
}
.cent {
margin-top: 1.5em;
overflow-y: auto;
height: 80%;
text-indent: 2em;
text-align: left;
padding-right: 0.2em;
}
::-webkit-scrollbar {
width: 10px;
background-color: rgba(255, 255, 255, 0.2);
}
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
border-radius: 5px;
background-color: transparent;
}
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.7);
}
#ttttt{
display: none;
}
.btn {
margin-top: 20px;
width: 70%;
height: 80px;
transition: 0.4s;
border-radius: 1em;
border: 1px solid rgba(255, 255, 255, 0.5);
border-top: none;
z-index: 66;
overflow: hidden;
position: relative;
background: rgba(255, 255, 255, 0.2);
}
.btn:hover {
border: 1px solid rgba(255, 255, 255, 0.8) !important;
border-top: none !important;
}
.btn span {
width: 40%;
height: 84%;
margin-top: 6px;
line-height: 38px;
display: inline-block;
border: 1px solid #009FFD;
color: #fff;
background: rgba(255, 255, 255, 0.4);
border-radius: 4px;
cursor: pointer;
}
.btn span:nth-of-type(1) {
margin-right: 15px;
position: relative;
}
.btn span:nth-of-type(2) {
margin-left: 15px;
}
input{
width: 100%;
height: 100%;
border: 1px solid red;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.img{
width: 60px;
height: 60px;
margin: auto;
text-align: center;
position: relative;
}
.img img{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.mmm{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 999;
display: none;
cursor: pointer;
background: #b9fff4;
color: aqua;
line-height: 80px;
}
</style>
</head>
<body>
<div id="context">
<div class="intro">
<div class="cent_bg">
<h3>语音识别内容:</h3>
<div class="cent">
</div>
</div>
<div class="btn">
<span>上传文件
</span>
<span>开始识别</span>
<div class="mmm">
正在识别...
</div>
</div>
<form id="ttttt" action="" method="post">
<input type="file" name="voice" value="">
</form>
</div>
</div>
</body>
</html>
<script type="text/javascript">
$(function() {
$(".btn span:nth-of-type(1)").click(function() {
$('#ttttt input[name="voice"]').click();
})
$(".btn span:nth-of-type(2)").click(function() {
if(document.querySelector("input").value==""){
return alert("未选择文件");
}
$(".mmm").css("display","block");
$(".cent").html('<div class="img"><img src="img/timg.gif"/></div>');
$.ajax({
url: basePath + "/VoiceRecognize",
type: 'post',
cache: false,
data: new FormData($('#ttttt')[0]),
processData: false,
contentType: false,
dataType: "json",
beforeSend: function() {
uploading = true;
},
success: function(data) {
if (data.status=="200") {
$(".cent").html(data.data.text);
$(".mmm").css("display","none");
} else{
$(".cent").html("未能识别 "+data.msg);
$(".mmm").css("display","none");
}
}
});
});
});
</script>
speech_produce.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>语音合成</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<script src="js/jquery-2.1.0.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.particleground.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/ai.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<style type="text/css">
#error {
width: 60%;
height: 120px;
line-height: 120px;
text-align: center;
font-size: 1.5em;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -65%);
z-index: 999;
}
.cent_bg {
width: 80%;
height: 22em;
border: 1px solid rgba(255, 255, 255, 0.5);
margin: auto;
padding: 3% 6%;
border-radius: 10%;
font-size: 1.5em;
line-height: 2em;
position: relative;
}
.cent {
margin-top: 1em;
width: 100%;
background: rgba(0, 0, 0, .5);
overflow-y: auto;
height: 80%;
color: white;
font-size: 1.3em;
text-indent: 1em;
padding: .8em;
border: none;
resize: none;
outline-color: white;
}
::-webkit-scrollbar {
width: 10px;
background-color: rgba(255, 255, 255, 0.2);
}
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
border-radius: 5px;
background-color: transparent;
}
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.7);
}
.btn {
width: 70%;
height: 40px;
transition: 0.4s;
border-bottom-left-radius: 1em;
border-bottom-right-radius: 1em;
border: 1px solid rgba(255, 255, 255, 0);
border-top: none;
z-index: 66;
background: rgba(255, 255, 255, 0.2);
padding: 5px 0px;
}
.btn #btnSub:hover {
border: 1px solid rgba(255, 255, 255) !important;
color: white;
}
.btn #btnSub {
width: 40%;
height: 100%;
line-height: 25px;
display: inline-block;
border: 1px solid #009FFD;
color: #fff;
background: rgba(255, 255, 255, 0.4);
border-radius: 4px;
font-size: 1.1em;
cursor: pointer;
}
#select {
margin: auto;
margin-top: 10px;
width: 70%;
height: 30px;
border-top-left-radius: 1em;
border-top-right-radius: 1em;
transition: 0.4s;
border-top: none;
z-index: 66;
background: rgba(255, 255, 255, 0.2);
}
#selectBox {
width: 70%;
height: 30px;
margin: 0 auto;
}
#mantext,
#womantext {
font-size: 1.25em;
line-height: 30px;
float: left;
}
#mantext {
text-align: center;
}
#woman {}
.inputBox {
width: 50%;
height: 30px;
float: left;
}
#man,
#woman {
margin-top: 6px;
display: block;
float: left;
width: 20px;
height: 20px;
}
</style>
</head>
<body>
<div id="error">请在此输入文本内容</div>
<div id="context">
<div class="intro">
<form method="post" enctype="multipart/form-data" id="Voice">
<div class="cent_bg">
<h3>请输入要合成的语音文本:</h3>
<textarea id="Content" class="cent" name="text"></textarea>
</div>
<div id="select">
<div id="selectBox">
<div class="inputBox">
<label id="mantext" for="man" style="float: right;">男声</label><input id="man" type="radio" name="voiceType" checked value="1" style="float: right;" />
</div>
<div class="inputBox">
<input id="woman" type="radio" name="voiceType" value="2" /><label id="womantext" for="woman">女声</label>
</div>
</div>
</div>
<div class="btn">
<button id="btnSub" type="submit">合成语音</button>
</div>
</form>
</div>
</div>
</body>
<script>
$(function() {
var cor=0;
var stop=setInterval(function(){
$('#error').fadeToggle(700);
cor++;
if(cor==3){
clearInterval(stop);
}
},700);
$('#btnSub').on('click', function() {
cor=0;
var Text = $('#Content').val();
if(Text.length == 0) {
var stop=setInterval(function(){
$('#error').fadeToggle(700);
cor++;
if(cor==4){
clearInterval(stop);
}
},700);
return false;
}
});
// 服务器请求地址
$('#Voice').attr('action', basePath+"/VoiceGen");
});
</script>
</html>
ai.js
// 服务器主地址
var basePath="127.0.0.1:8080/AIProject"
// 背景效果
$(document).ready(function() {
$('#context').particleground({
dotColor: '#5cbdaa',
lineColor: '#5cbdaa'
});
$('.intro').css({
'margin-top': -($('.intro').height() / 2)
});
});
style.css
/*********CSS初始化*********/
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* particleground demo */
*{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
/*overflow: scroll;*/
}
/*********CSS初始化结束*********/
body {
background: #202AA3;
font-family: 'Montserrat', sans-serif;
color: #fff;
line-height: 1.3;
-webkit-font-smoothing: antialiased;
}
#particles {
width: 100%;
height: 100%;
overflow: hidden;
}
.intro {
position: absolute;
left: 0;
top: 50%;
padding: 0 20px;
width: 100%;
text-align: center;
}
h1 {
text-transform: uppercase;
font-size: 85px;
font-weight: 700;
letter-spacing: 0.015em;
}
h1::after {
content: '';
width: 60%;
display: block;
background: #fff;
height: 10px;
margin: 30px auto;
line-height: 1.1;
}
p {
margin: 0 0 30px 0;
font-size: 24px;
}
.btn {
display: inline-block;
padding: 15px 30px;
border: 2px solid #fff;
text-transform: uppercase;
letter-spacing: 0.015em;
font-size: 18px;
font-weight: 700;
line-height: 1;
color: #fff;
text-decoration: none;
-webkit-transition: all 0.4s;
-moz-transition: all 0.4s;
-o-transition: all 0.4s;
transition: all 0.4s;
}
.btn:hover {
color: #005544;
border-color: #005544;
}
@media only screen and (max-width: 1000px) {
h1 {
font-size: 70px;
}
}
@media only screen and (max-width: 800px) {
h1 {
font-size: 48px;
}
h1::after {
height: 8px;
}
}
@media only screen and (max-width: 568px) {
.intro {
padding: 0 10px;
}
h1 {
font-size: 30px;
}
h1::after {
height: 6px;
}
p {
font-size: 18px;
}
.btn {
font-size: 16px;
}
}
@media only screen and (max-width: 320px) {
h1 {
font-size: 28px;
}
h1::after {
height: 4px;
}
}
接口规范
数据交互类型:JSON
请求数据:请求数据除了请求参数以外,还需另外发送以下参数:(否则会返回403状态码)
返回数据格式:
{“status”: “200”,“msg”:"",“data”: {“namename”:“user”,“password”:“password”}}
(1)人脸识别
接口名:FaceDetect
请求参数:
返回参数:
(2)人脸比对
接口名:FaceMatch
请求参数:
返回参数:
(3)语音识别
接口名:VoiceRecognize
请求参数:
返回参数:
(4)语音生成
接口名:VoiceGen
返回参数:
Mp3音频格式文件
请求注意事项
- 请求体格式化:Content-Type为application/json,通过json格式化请求体。
- Base64编码:请求的图片需经过Base64编码,图片的base64编码指将图片数据编码成一串字符串,使用该字符串代替图像地址。您可以首先得到图片的二进制,然后用Base64格式编码即可。需要注意的是,图片的base64编码是不包含图片头的,如data:image/jpg;base64,
- 图片格式:现支持PNG、JPG、JPEG、BMP,不支持GIF图片
实例代码
1. 人脸识别实例代码
// 配置请求参数
HashMap<String, String> options = new HashMap<String, String>();
options.put("face_field", "age,gender,glasses,beauty,expression");
options.put("max_face_num", "2");
options.put("face_type", "LIVE");
// 转换成base64
String image = Base64Util.part2Base64(imagePart);
String imageType = "BASE64";
// 接口调用,并返回JSON数据
JSONObject json = client.detect(image, imageType, options);
// 响应数据处理
Map<String, Object> map = new HashMap<>();
// 获取人脸信息列表
JSONObject result = json.getJSONObject("result").getJSONArray("face_list").getJSONObject(0);
// 响应数据:性别
JSONObject genderObj = result.getJSONObject("gender");
String genderStr = genderObj.getString("type");
if(genderObj.getDouble("probability") >= 0.6) {//概率并转换
if("female".equals(genderStr)) {
genderStr = "女";
}else if("male".equals(genderStr)) {
genderStr = "男";
}
}
map.put("gender", genderStr);
// 返回接口数据
return ResponseData.success(map);
2. 人脸对比实例代码
// 转换成base64
String image1 = Base64Util.part2Base64(imagePart1);
String image2 = Base64Util.part2Base64(imagePart2);
// 封装平台接口请求对象
MatchRequest req1 = new MatchRequest(image1, "BASE64");
MatchRequest req2 = new MatchRequest(image2, "BASE64");
ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
requests.add(req1);
requests.add(req2);
// 人脸匹配
JSONObject json = client.match(requests);
// 响应数据处理
Map<String, Object> map = new HashMap<>();
// 匹配分值
double score = json.getJSONObject("result").getDouble("score");
return ResponseData.success(map);
3. 语音识别实例代码
// 文件类型
String fileType = voicePart.getContentType();
if(fileType.endsWith("mp3")) {
fileType = MP3;
}else if(fileType.endsWith("wav")) {
fileType = WAV;
}else {
return ResponseData.fail("请上传mp3、wav音频");
}
try {
// 获取音频字符流
InputStream is = voicePart.getInputStream();
// 保存临时音频文件
String filename = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(Calendar.getInstance().getTime());
File tmpVoice = new File(workspace + File.separator + filename+fileType);
VoiceUtil.saveVoiceFile(is, tmpVoice);
if(fileType.equals(MP3)) {
File mp3File = tmpVoice;
tmpVoice = new File(tmpVoice.getPath().replace(MP3, WAV));
if(!VoiceUtil.mp3ToWav(mp3File, tmpVoice)) {
return ResponseData.fail("mp3音频文件错误,请用wav音频。");
}
mp3File.delete();
}
// 调用百度接口
JSONObject json = client.asr(tmpVoice.getPath(), "wav", 16000, null);
tmpVoice.delete();
Integer status = json.getInt("err_no"); //状态码
if(status != 0) {
// 异常响应处理
String msg = json.getString("err_msg");
log.warn("百度接口调用响应异常,error_code:"+status + " error_msg:"+msg);
return ResponseData.fail(msg);
}
// 响应数据处理
Map<String, Object> map = new HashMap<>();
// 获取结果
JSONArray jsonArray = json.getJSONArray("result");
// 识别文本
String text = jsonArray.getString(0);
map.put("text", text);
return ResponseData.success(map);
} catch (Exception e) {
log.warn("识别音频文件错误:", e);;
}
4. 语音合成实例代码
// 请求参数
HashMap<String, Object> options = new HashMap<String, Object>();
// 语速,取值0-9,默认为5中语速
options.put("spd", "5");
// 音调,取值0-9,默认为5中语调
options.put("pit", "5");
// 发音人选择, 0为女声,1为男声, 3为情感合成-度逍遥,4为情感合成-度丫丫,默认为普通女
options.put("per", voiceType);
// 调用百度api接口
TtsResponse res = client.synthesis(text, "zh", 1, options);
byte[] data = res.getData();
return data;
效果展示
源码下载地址:https://github.com/jcdjor/AIProject
PS:下面为源码的一些说明
- AIProject.zip 为后端代码,为eclipse项目,app.properties文件需要自己配置百度云开发平台的AppID、APIKey、SecretKey。
- Web.zip 为前端代码,前后端分离,可直接运行使用 。
- 运行环境,对版本没太大要求,但jdk和tomcat要对应 JDK:,我使用的版本为JDK1.8,官方下载地址
Tomcat:,我使用的版本为tomcat 9,官方下载地址;- 注意需要百度云开放平台的AppID、APIKey、SecretKey,百度云AI开放平台:http://ai.baidu.com/
声明:本文欢迎大家评论和转载,使用本文章或代码还请声明,且在使用处的明显位置给出。如有其它问题或有什么建议,可在下方评论,或加QQ(1414782205),或发邮箱jcdjor@163.com。