使用树莓派实现翻译机

只用一根网线实现树莓派和PC的链接

硬件:

  1. 树莓派套件(树莓派3B、16G内存卡、读卡器、充电器)
  2. 一台可以上网PC(我的操作系统版本为Windows10 1709)
  3. 一个USB耳机(有麦)
  4. 一根网线

软件

  1. 树莓派操作系统(我使用的是Raspbian)
  2. Putty(安装在Windows端,用来设置树莓派端)
  3. VNCViewer(安装在Windows端,用来链接树莓派端)
  4. Win32DiskImager(安装在Windows端,用来在内存卡上制作“启动盘”)

硬件和软件准备好了,我们现在正式开始翻译机的制作

安装树莓派系统

  1. 下载操作系统并解压缩
    版本信息如下Version:April 2018Release date:2018-04-18Kernel version:4.14下载地址:https://downloads.raspberrypi.org/raspbian_latest下载下来的是一个压缩包,解压缩以后是img格式的镜像文件



2. 制作“启动盘”
①下载Win32DiskImager并安装,可以百度,版本无所谓;
下载地址https://sourceforge.net/projects/win32diskimager/
②双击运行Win32DiskImager,设置如下;

校验值选“无”,不勾选仅读取分配分区
写入完成后,一般会弹出一个让你格式化的弹框,直接叉掉就好

然后把把内存卡插到树莓派上就好
【注意!!!不是用读卡器把内存卡插到树莓派上,而是插到树莓派上面的内存卡插槽里】

OK,到这边,树莓派系统已经算是安装好了(只用插好内存卡就可以了,不需要其他操作)。

连接树莓派和电脑
①在Windows上安装Putty和VNCViewer
百度安装即可,没什么好说的;
②给树莓派通电,并用网线连接树莓派和电脑
③在Windows上设置网络为共享;如图所示


④Window+r打开cmd命令行,arp -a命令,获取树莓派的ip地址
在192.168.137.1栏中,192.168.137.255上面的ip地址即为树莓派的ip地址,如图(每次电脑重新开机后,这个ip地址都会变):


⑤打开Putty软件,填上树莓派的ip地址,点击open

会弹出这样的对话框,选择否。

然后登录即可,默认登录账户是:pi,密码是raspberry

这样已经实现了树莓派和电脑相连,可以操作树莓派系统了(Linux)。

但是现在只能通过命令行操作,如果想要图形界面的话还需要进行一些配置。

图形化界面配置

  1. 安装tightvncserver服务
sudo apt-get update
sudo apt-get installtightvncserver
  1. 安装xrdp服务
sudo apt-get install xrdp
  1. 给树莓派安装服务包
sudo apt-get install vnc4server tightvncserver
  1. 启动tightserver服务
tightserver
#这个命令会提示你设置密码,确认密码等,一定要记住密码!

理论上现在应该可以使用Windows自带的远程桌面进行连接了,但是我的电脑好像连接不了(截止至2018.06.22还未解决),所以我又借助了其他工具进行连接。就是我们刚刚安装的VNCViewer软件,双击运行即可。【注意!!这里的地址是树莓派的ip地址加上”:1”】,然后点connect。

输入刚刚设置的密码,即可连接

这就是树莓派的图形化界面啦,本来是有壁纸的,后来被我搞丢了。

到这里,树莓派和电脑的连接就完成啦!

下面,开始编程。

翻译机编程实现

编程主要使用Java和一些shell命令(很少,只有几句)。我们先来捋一捋,本程序要主要的模块

  1. 录音
  2. 把录下来的音频文件转换成文字
  3. 把文字从中文转换成英文
  4. 把文字转换成音频文件
  5. 播放音频文件

我们分别从这几个模块分析:

1.录音
这个功能其实很简单,只要调用一条shell命令即可

arecord -D plughw:Device -d 5 -r 16384 -f S16 input.wav
#注解
#arecord是Linux的录音功能,树莓派里面自带,不需要安装
#-D plughw:Device是指选择USB耳机作为音频输入
#-d 5是指录五秒的音,可以选择其他的
#-r 16384是指采码率是16k,最好就用这个
#-f S16是指位深16位,就用这个吧
#input.wav是录音保存在哪,这个随便写

2.音频文件转换成文字
这个功能一开始我是准备使用Google的speechAPI的,后来因为某些众所周知的原因,我选择了百度的语音识别API,也可以用科大讯飞的API,这里以百度的语音识别API为例(因为是免费的),使用起来非常简单
可以在这里下载SDK,有各种语言版本的,我选择的是Java版本,下载下来以后里面是3个jar文件,利用Eclipse使用很简单,下面的开发文档讲到非常详细。
http://ai.baidu.com/sdk

这是百度语音识别API的开发文档
http://ai.baidu.com/docs#/ASR-Online-Java-SDK/top

3.中文翻译成英文
语音识别功能我们使用的是百度的语音识别API,所以,翻译功能我们也使用百度的翻译API吧,使用方法跟语音识别API差不多,在百度AI平台上面也可以找到demo和开发文档,这里就不在赘述,非常简单。
4.文字转换成音频文件
这个功能跟语音识别API集成在一起了,所以在配置语音识别API的时候,这个也配置好了,技术文档也很简单。
5.播放音频文件
这个功能也很简单,跟录音功能类似,也是只要一条Linux里的命令就可以实现

aplay -D plughw:Device output.wav

接下来是具体实现(由于时间比较急,所以虽然功能实现了,但是代码的质量其实很差)

使用Eclipse编程,项目结构如下:

jars文件夹
jars文件夹里面是百度语音识别和百度语音合成的SDK。懒的去官网找的可以从我的云盘里下载。
①下载下来之后在项目里面新建文件夹jars
②然后把jar包复制到文件夹内
③选中这四个jar包,右击build path
https://download.csdn.net/download/s1455364690/10493784
链接: https://pan.baidu.com/s/1aQ77vyXeCDP_A7wauezxMQ 密码: ve2g

main包

package main;
/*
时间:2018/06/22
描述:树莓派翻译机主类
版本:1.0
作者:WHU_Sun
邮箱:1455364690@qq.com
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;import org.json.JSONException;
import org.json.JSONObject;import speechToLec.Sample;
import tools.Audioplay;
import tools.Tools;
import translate.TransApi;public class Main {//Linux相关命令static String arecord = "arecord -D plughw:Device -d 5 -r 16384 -f S16 input.wav";static String convert = "mpg321 -w output.wav output.mp3";static String aplay = "aplay -D plughw:Device output.wav";static String aplayDing = "aplay -D plughw:Device ding.wav";static String aplayStart = "aplay -D plughw:Device startRecord.wav";static String aplayEnd = "aplay -D plughw:Device endRecord.wav";static String aplayResTip = "aplay -D plughw:Device resTip.wav";static String aplayNext = "aplay -D plughw:Device next.wav";static String aplayOpen = "aplay -D plughw:Device open.wav";static String aplayError = "aplay -D plughw:Device error.wav";// 在平台申请的APP_ID 详见 http://api.fanyi.baidu.com/api/trans/product/desktop?req=developerprivate static final String APP_ID = "这里填自己的百度翻译APPID";private static final String SECURITY_KEY = "这里填自己的百度翻译KEY";#APPID和KEY需要到百度翻译开放平台上面去申请,免费的public static void main(String[] args){//Tools类是工具类,目前我只写了一个调用Linux命令的工具Tools tools = new Tools();String a;Scanner reader = new Scanner(System.in);tools.runShell(aplayOpen);do{try {//用来暂停a = reader.nextLine();//叮tools.runShell(aplayDing);//开始录制tools.runShell(aplayStart);System.out.println("开始录制");//录制..tools.runShell(arecord);//录制完毕tools.runShell(aplayEnd);System.out.println("录制完毕");TransApi api = new TransApi(APP_ID, SECURITY_KEY);Sample sample = new Sample();//调用语音识别APIString query = sample.change("input.wav");System.out.println("您说:"+query);//调用翻译APIJSONObject obj = new JSONObject(api.getTransResult(query, "auto", "en"));String temp = obj.get("trans_result").toString();JSONObject res = new JSONObject(temp.substring(1,temp.length()-1));String resStr = res.get("dst").toString();System.out.println("翻译结果为:"+resStr);//调用语音合成APIsample.say(resStr);tools.runShell(convert);//翻译结果tools.runShell(aplayResTip);//播放结果tools.runShell(aplay);try{Thread.sleep(1000);}catch (Exception e) {// TODO: handle exception}tools.runShell(aplayNext);} catch (Exception e) {tools.runShell(aplayError);continue;// TODO: handle exception}}while(true);}}

speechToLec包

package speechToLec;
/*
时间:2018/06/22
描述:百度语音识别API
版本:1.0
作者:WHU_Sun
邮箱:1455364690@qq.com
*/
import java.io.IOException;import org.json.JSONObject;import com.baidu.aip.speech.AipSpeech;
import com.baidu.aip.speech.TtsResponse;
import com.baidu.aip.util.Util;public class Sample {//设置APPID/AK/SKpublic static final String APP_ID = "这里是百度语音识别API的APPID";public static final String API_KEY = "这里是百度语音识别API的KEY";public static final String SECRET_KEY = "这里是百度语音识别API的SECRET_KEY";#这里是自己去申请的百度语音识别API的相关数据,免费的public String change(String path) {// 初始化一个AipSpeechAipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);// 可选:设置网络连接参数client.setConnectionTimeoutInMillis(2000);client.setSocketTimeoutInMillis(60000);// 可选:设置代理服务器地址, http和socket二选一,或者均不设置//client.setHttpProxy("proxy_host", proxy_port);  // 设置http代理//client.setSocketProxy("proxy_host", proxy_port);  // 设置socket代理// 可选:设置log4j日志输出格式,若不设置,则使用默认配置// 也可以直接通过jvm启动参数设置此环境变量//System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");// 调用接口//JSONObject res = client.asr("test.pcm", "pcm", 16000, null);JSONObject res = client.asr(path, "wav", 16000, null);String temp1 = res.get("result").toString();String[] temp2 = temp1.split(",");return temp2[0].substring(2);}public void say(String sth){// 初始化一个AipSpeechAipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);// 可选:设置网络连接参数client.setConnectionTimeoutInMillis(2000);client.setSocketTimeoutInMillis(60000);// 可选:设置代理服务器地址, http和socket二选一,或者均不设置//client.setHttpProxy("proxy_host", proxy_port);  // 设置http代理//client.setSocketProxy("proxy_host", proxy_port);  // 设置socket代理// 可选:设置log4j日志输出格式,若不设置,则使用默认配置// 也可以直接通过jvm启动参数设置此环境变量//System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");// 调用接口TtsResponse res = client.synthesis(sth, "zh", 1, null);byte[] data = res.getData();JSONObject res1 = res.getResult();if (data != null) {try {Util.writeBytesToFileSystem(data, "output.mp3");} catch (IOException e) {e.printStackTrace();}}if (res1 != null) {//System.out.println(res1.toString(2));}}
}

tools包

package tools;
/*
时间:2018/06/22
描述:调用Linux命令的工具类
版本:1.0
作者:WHU_Sun
邮箱:1455364690@qq.com
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;public class Tools {public void runShell(String cmd) {try {Process ps = Runtime.getRuntime().exec(cmd);BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));StringBuffer sb = new StringBuffer();String line;while ((line = br.readLine()) != null) {sb.append(line+"\n");}String result = sb.toString();System.out.println(result);} catch (Exception e) {e.printStackTrace();}}
}

translate包
这个包是百度翻译的API相关类,直接复制就好

package translate;import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;class HttpGet {protected static final int SOCKET_TIMEOUT = 10000; // 10Sprotected static final String GET = "GET";public static String get(String host, Map<String, String> params) {try {// 设置SSLContextSSLContext sslcontext = SSLContext.getInstance("TLS");sslcontext.init(null, new TrustManager[] { myX509TrustManager }, null);String sendUrl = getUrlWithQueryString(host, params);// System.out.println("URL:" + sendUrl);URL uri = new URL(sendUrl); // 创建URL对象HttpURLConnection conn = (HttpURLConnection) uri.openConnection();if (conn instanceof HttpsURLConnection) {((HttpsURLConnection) conn).setSSLSocketFactory(sslcontext.getSocketFactory());}conn.setConnectTimeout(SOCKET_TIMEOUT); // 设置相应超时conn.setRequestMethod(GET);int statusCode = conn.getResponseCode();if (statusCode != HttpURLConnection.HTTP_OK) {System.out.println("Http错误码:" + statusCode);}// 读取服务器的数据InputStream is = conn.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));StringBuilder builder = new StringBuilder();String line = null;while ((line = br.readLine()) != null) {builder.append(line);}String text = builder.toString();close(br); // 关闭数据流close(is); // 关闭数据流conn.disconnect(); // 断开连接return text;} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (KeyManagementException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}public static String getUrlWithQueryString(String url, Map<String, String> params) {if (params == null) {return url;}StringBuilder builder = new StringBuilder(url);if (url.contains("?")) {builder.append("&");} else {builder.append("?");}int i = 0;for (String key : params.keySet()) {String value = params.get(key);if (value == null) { // 过滤空的keycontinue;}if (i != 0) {builder.append('&');}builder.append(key);builder.append('=');builder.append(encode(value));i++;}return builder.toString();}protected static void close(Closeable closeable) {if (closeable != null) {try {closeable.close();} catch (IOException e) {e.printStackTrace();}}}/*** 对输入的字符串进行URL编码, 即转换为%20这种形式* * @param input 原文* @return URL编码. 如果编码失败, 则返回原文*/public static String encode(String input) {if (input == null) {return "";}try {return URLEncoder.encode(input, "utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return input;}private static TrustManager myX509TrustManager = new X509TrustManager() {@Overridepublic X509Certificate[] getAcceptedIssuers() {return null;}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}};}
package translate;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;/*** MD5编码相关的类* * @author wangjingtao* */
public class MD5 {// 首先初始化一个字符数组,用来存放每个16进制字符private static final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd','e', 'f' };/*** 获得一个字符串的MD5值* * @param input 输入的字符串* @return 输入字符串的MD5值* @throws UnsupportedEncodingException * */public static String md5(String input) throws UnsupportedEncodingException {if (input == null)return null;try {// 拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”)MessageDigest messageDigest = MessageDigest.getInstance("MD5");// 输入的字符串转换成字节数组byte[] inputByteArray = input.getBytes("utf-8");// inputByteArray是输入字符串转换得到的字节数组messageDigest.update(inputByteArray);// 转换并返回结果,也是字节数组,包含16个元素byte[] resultByteArray = messageDigest.digest();// 字符数组转换成字符串返回return byteArrayToHex(resultByteArray);} catch (NoSuchAlgorithmException e) {return null;}}/*** 获取文件的MD5值* * @param file* @return*/public static String md5(File file) {try {if (!file.isFile()) {System.err.println("文件" + file.getAbsolutePath() + "不存在或者不是文件");return null;}FileInputStream in = new FileInputStream(file);String result = md5(in);in.close();return result;} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}public static String md5(InputStream in) {try {MessageDigest messagedigest = MessageDigest.getInstance("MD5");byte[] buffer = new byte[1024];int read = 0;while ((read = in.read(buffer)) != -1) {messagedigest.update(buffer, 0, read);}in.close();String result = byteArrayToHex(messagedigest.digest());return result;} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}private static String byteArrayToHex(byte[] byteArray) {// new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))char[] resultCharArray = new char[byteArray.length * 2];// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去int index = 0;for (byte b : byteArray) {resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];resultCharArray[index++] = hexDigits[b & 0xf];}// 字符数组组合成字符串返回return new String(resultCharArray);}}
package translate;import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;public class TransApi {private static final String TRANS_API_HOST = "http://api.fanyi.baidu.com/api/trans/vip/translate";private String appid;private String securityKey;public TransApi(String appid, String securityKey) {this.appid = appid;this.securityKey = securityKey;}public String getTransResult(String query, String from, String to) throws UnsupportedEncodingException {Map<String, String> params = buildParams(query, from, to);return HttpGet.get(TRANS_API_HOST, params);}private Map<String, String> buildParams(String query, String from, String to) throws UnsupportedEncodingException {Map<String, String> params = new HashMap<String, String>();params.put("q", query);params.put("from", from);params.put("to", to);params.put("appid", appid);// 随机数String salt = String.valueOf(System.currentTimeMillis());params.put("salt", salt);// 签名String src = appid + query + salt + securityKey; // 加密前的原文params.put("sign", MD5.md5(src));return params;}}

测试运行
在树莓派上新建一个文件夹,然后把在网上下载的一些音频文件放在里面(wav格式)
我放的是如下的一些文件

(其实可以随便在网上下载一些wav音频文件,随便命名,只要跟Main.java保持一致就好)
#提示音命名为
ding.wav
#开始录制提示音
startRecord.wav
#结束录制提示音
endRecord.wav
#结果提示音
resTip.wav
#继续翻译提示音
next.wav
#开机提示音
open.wav
#错误提示音
error.wav

然后在Eclipse导出项目为Translator.jar文件,也放在上面那个文件夹里面。
打开Linux终端,输入以下命令

sudo java -jar Translator.jar

即可测试运行

************编辑于2018/06/22**************************

使用树莓派实现翻译机相关推荐

  1. 树莓派4 街机 卡顿_建立开放式街机的4个项目

    树莓派4 街机 卡顿 您最近可能听说过有关 MAME项目已获得GPL版本2许可的消息 . MAME最初代表" Multiple Arcade Machine Emulator",它 ...

  2. 翻译机之后,搜狗再推智能硬件产品录音笔

    去年 10 月,搜狗 AI 事业部总经理张博告诉 AI科技大本营(ID:rgznai100),翻译机只是搜狗做智能硬件的开始,接下里半年里,他们还将发布数款集成了搜狗 AI 技术的硬件产品. 3 月 ...

  3. 不只翻译机,搜狗将在半年内推数款智能硬件产品

    10月24日已是昨日,但属于开发者的1024一直都在--2018 AI开发者大会就是你的1024.11月8-9日,现场聆听国内外AI大牛的深知灼见,与工业界AI应用思维紧密同步,收获60+技术大咖的干 ...

  4. 占据翻译机市场大半壁江山,科大讯飞现AI新物种

    https://www.toutiao.com/a6685598978391671310/ 2019-04-30 16:18:33 如今,随着人们经济水平的提高,越来越多的人选择利用小长假出国游,然而 ...

  5. 树莓派 linux0.12,12 个可替代树莓派的单板机

    正在寻找树莓派的替代品?这里有一些单板机可以满足你的 DIY 渴求. 树莓派是当前最流行的单板机.你可以在你的 DIY 项目中使用它,或者用它作为一个成本效益高的系统来学习编代码,或者为了你的便利,利 ...

  6. 树莓派:树莓派的刷机和登录,以及更新新版vim方便使用

    一.树莓派的刷机 我自己的 路径是:   C:\Users\22330\Documents\Tencent Files\2233093274\FileRecv 这是我自己安装的地方: 我们下载完以后如 ...

  7. 天猫总架构师何崚:好的技术团队不是“需求翻译机”或“架构优化机”

    " 一个好的技术团队应该具备哪些特质?一个好的技术团队的leader应该怎样实施管理?技术和业务如何做到完美结合?这是来自天猫技术团队的经验,仅供参考. 前言 2012 年,无线化大规模到来 ...

  8. 墨迹天气语音包_小米有品“智能AI翻译机”评测,还内置了语音助手,随身WiFi功能...

    出国旅游时,我们需要面对的最大问题应该就是言语沟通了,毕竟想要掌握一门新的语言不是什么容易的事情.近期,小米科技旗下的小米有品平台上线了一款新品:Langogo智能AI翻译机,对于想出国游玩或工作的朋 ...

  9. 中英翻译机c语言实验报告引言,课程设计--C语言关键字中英翻译机.doc

    课程设计--C语言关键字中英翻译机.doc 课 程 设 计 报 告学院.系 吉林大学珠海学院计算机科学与技术系专业名称 计算机科学与技术课程设计科目 C 语言程序课程设计所在班级 4 班学生学号 04 ...

最新文章

  1. [Silverlight]使用DoubleAnimation为对象添加动画效果
  2. Spring Security 实战干货:路径Uri中的 Ant 风格
  3. java线程 对文件copy 可能删除了 报异常_java线程对文件copy可能删除了报异常
  4. JavaScript中的this详解
  5. Python之字符串格式化
  6. PHP 和 AJAX MySQL 数据库实例
  7. git flow 分支合并
  8. freetextbox java_FreeTextBox的应用技巧
  9. Unity 防止数组索引越界的几种方法
  10. 那些变态的javascript输出
  11. 永久关闭“WPS热点”的显示
  12. MongoDB—Mac M1的安装
  13. 记录一次心脏滴血靶场实验过程
  14. 每天记忆五个词根之五
  15. 车载以太网交换机功能和应用案例汇总, 适用于AVB/TSN, 802.1AS(gPTP时钟同步)
  16. 微信小程序用户昵称包含表情图片的解决方案
  17. 指标体系构建方法-四个模型
  18. MPD大会上使用的PPT分享
  19. ## 使用strongswan和xl2tpd配置l2tp over ipsec和Xauth
  20. 开放环境下的群智决策:概念、挑战及引领性技术

热门文章

  1. 微信电脑版不能输入中文不能截图的原因竟然是系统有问题
  2. 《C专家编程》读书记录
  3. gcc编译报错-stary '\357' in program
  4. EER的基本知识和使用
  5. Wireshark的常见提示
  6. IAD,ATA 区别
  7. 计算机毕业设计Java博物馆信息管理(源码+系统+mysql数据库+lw文档)
  8. Laya 2.1.1.1 Unity模型导出后顶点处理小记
  9. 团队作业8--展示博客
  10. 【WAF技巧拓展】————9、Bypass WAF Cookbook – MayIKissYou