基于百度AI开放平台的人脸识别及语音合成

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

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值