基於百度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。