摘要:語音識別,語義理解一站式解決之智能照相機人臉識別如果有代碼排版和圖片顯示問題,請訪問博客。前面寫了兩篇語音識別,語義理解的博文,分別是語音在線聽書和語音記帳軟件,本篇是語音智能照相機。
語音識別,語義理解一站式解決之智能照相機(人臉識別,olami)
如果有代碼排版和圖片顯示問題,請訪問CSDN博客。
轉載請注明CSDN博文地址:http://blog.csdn.net/ls0609/a...
olami sdk實現了把錄音或者文字轉化為用戶可以理解的json字符串從而實現語義理解,用戶可以定義自己的
語義,通過這種方式可以實現用戶需要的語義理解。前面寫了兩篇語音識別,語義理解的博文,分別是語音
在線聽書和語音記帳軟件,本篇是語音智能照相機。
1.智能照相機的功能
手機后攝像頭像素比較高,如果用后設想頭對準自己自拍,那么看不到屏幕的情況下怎么知道
自己在不在鏡頭中呢?而本篇做的智能照相機就可以為您解決這個問題。
想要做的是這樣一個照相機app,可以語音切換攝像頭,人臉識別并語音播報識別的人臉是否在屏幕中央,
是偏向哪里,當人臉居中的時候,提示用戶可以拍照了,用戶說“拍照”,“茄子”就會自動抓拍并保存圖
片在手機中。
抓了兩張應用運行時的圖片:
2.eclipse中的lib目錄結構如下
assets下面的事tts播報的資源文件
libs目錄下,
libtts.so tts播報所需的庫文件
libspeex.so 語音識別所需的庫文件
libolamsc.so 語音識別所需的庫文件
tts.jar tts播報所需的庫文件
voicesdk_android.jar 語音識別所需的庫文件
3.AndroidManifest.xml
package="com.olami"
android:versionCode="1"
android:versionName="1.0" >
需要錄音,網絡,讀寫sd卡,拍照等權限。
4.layout布局xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
在surfaceview中自定義了一個FaceView,faceview用來顯示抓拍的人臉。
屏幕最下方有個button,因為這個版本暫時不支持語音喚醒功能(后續添加后再更新),添加一個button用于用戶想隨時說拍照的時候點擊觸發用。
5.MainActivity.java 和FaceView.java
1.MainActivity.Java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.layout_camera); initHandler();//用于處理錄音狀態回調的消息 initView(); //初始化界面 initViaVoiceRecognizerListener(); //初始化olami語音回調監聽 init(); //初始化olami語音識別sdk initTts(); //初始化tts語音播報 DisplayMetrics dm = new DisplayMetrics();//定義DisplayMetrics對象 getWindowManager().getDefaultDisplay().getMetrics(dm);//取得窗口屬性 mScreenCenterx = dm.widthPixels/2;//窗口的寬度 mScreenCentery = dm.heightPixels/2; //窗口的高度
}
以下是olamisdk的初始化
public void init()
{
mOlamiVoiceRecognizer = new OlamiVoiceRecognizer(MainActivity.this); TelephonyManager telephonyManager= (TelephonyManager) this.getSystemService( this.getBaseContext().TELEPHONY_SERVICE); String imei=telephonyManager.getDeviceId(); mOlamiVoiceRecognizer.init(imei);//設置身份標識,可以填null //設置識別結果回調listener mOlamiVoiceRecognizer.setListener(mOlamiVoiceRecognizerListener); //設置支持的語音類型,優先選擇中文簡體 mOlamiVoiceRecognizer.setLocalization( OlamiVoiceRecognizer.LANGUAGE_SIMPLIFIED_CHINESE); mOlamiVoiceRecognizer.setAuthorization( "51a4bb56ba954655a4fc834bfdc46af1", "asr", "68bff251789b426896e70e888f919a6d", "nli"); //注冊Appkey,在olami官網注冊應用后生成的appkey //注冊api,請直接填寫“asr”,標識語音識別類型 //注冊secret,在olami官網注冊應用后生成的secret //注冊seq ,請填寫“nli” //錄音時尾音結束時間,建議填//2000ms mOlamiVoiceRecognizer.setVADTailTimeout(2000); //設置經緯度信息,不愿上傳位置信息,可以填0 mOlamiVoiceRecognizer.setLatitudeAndLongitude( 31.155364678184498,121.34882432933009);
}
定義OlamiVoiceRecognizerListener,此處代碼就不貼了。
onError(int errCode)//出錯回調,可以對比官方文檔錯誤碼看是什么錯誤
onEndOfSpeech()//錄音結束
onBeginningOfSpeech()//錄音開始
onResult(String result, int type)//result是識別結果JSON字符串
onCancel()//取消識別,不會再返回識別結果
onUpdateVolume(int volume)//錄音時的音量,1-12個級別大小音量
以下是handler消息處理,包含語義解析
private void initHandler()
{ mHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case MessageConst.CLIENT_ACTION_START_RECORED: mBtnStart.setText("錄音中"); break; case MessageConst.CLIENT_ACTION_STOP_RECORED: mBtnStart.setText("識別中"); break; case MessageConst.CLIENT_ACTION_CANCEL_RECORED: mBtnStart.setText("開始"); break; case MessageConst.CLIENT_ACTION_ON_ERROR: mBtnStart.setText("開始"); break; case MessageConst.CLIENT_ACTION_UPDATA_VOLUME: //mTextViewVolume.setText("音量: "+msg.arg1); break; case MessageConst.SERVER_ACTION_RETURN_RESULT: mBtnStart.setText("開始"); try{ String message = (String) msg.obj; String input = null; JSONObject jsonObject = new JSONObject(message); JSONArray jArrayNli = jsonObject.optJSONObject("data").optJSONArray("nli"); JSONObject jObj = jArrayNli.optJSONObject(0); JSONArray jArraySemantic = null; if(message.contains("semantic")) { jArraySemantic = jObj.getJSONArray("semantic"); String modifier = jArraySemantic.optJSONObject(0).optJSONArray( "modifier").optString(0); if("take_photo".equals(modifier)) capture(); else if("switch_camera".equals(modifier)) switchCamera(); } else{ Log.i("ppp","result error"); } } catch(Exception e) { e.printStackTrace(); } break; case MessageConst.CLIENT_ACTION_UPDATA_FACEDECTION_DATA: if(mIsRecording) break; RectF rect = (RectF) msg.obj; mLeft = rect.left; mRight = rect.right; mTop = rect.top; mBottom = rect.bottom; float centerx = mLeft +(mRight - mLeft)/2; float centery = mTop + (mBottom-mTop)/2; String promptString = ""; if(centerx100) promptString = "位置偏左,"; else if((centerx > mScreenCenterx)&& (Math.abs(centerx -mScreenCenterx)>100)) promptString = "位置偏右,"; if((centery < mScreenCentery)&&( Math.abs(mScreenCentery-centery) >200)) { if("".equals(promptString)) promptString = "位置偏上"; else promptString += "并且偏上"; } else if((centery > mScreenCentery)&& (Math.abs(centery -mScreenCenterx)>200)) { if("".equals(promptString)) promptString = "位置偏下"; else promptString += "并且偏下"; } if("".equals(promptString)) { promptString = "位置已經居中,可以拍照了"; mIsCenter = true; } else { mIsCenter = false; } ITtsListener ttsListener = new ITtsListener() { @Override public void onPlayEnd() { if(mIsCenter) { if(mOlamiVoiceRecognizer != null) mOlamiVoiceRecognizer.start(); } } @Override public void onPlayFlagEnd(String arg0) { } @Override public void onTTSPower(long arg0) { } }; TtsPlayer.playText(MainActivity.this, promptString, ttsListener,Tts.TTS_SYSTEM_PRIORITY); break; } } }; }
在MessageConst.SERVER_ACTION_RETURN_RESULT消息中,通過解析服務器返回的json字符串,可以找到modifier這個字段的值,如果是take_photo表示拍照,如果是switch_camera表示切換攝像頭。
當用戶說拍照或者茄子的時候,服務器返回如下json字符串:
[
{
"desc_obj": { "status": 0 }, "semantic": [ { "app": "camera", "input": "拍照", "slots": [ ], "modifier": [ "take_photo" ], "customer": "58df512384ae11f0bb7b487e" } ], "type": "camera"
}
]
這個拍照,茄子等語法都是自己定義的,詳細請看:
olami開放平臺語法編寫簡介:http://blog.csdn.net/ls0609/a...
olami開放平臺語法官方介紹:https://cn.olami.ai/wiki/?mp=...
? 2.人臉識別FaceView.java
public class FaceView extends View {
private Camera.Face[] mFaces; private Paint mPaint; private Matrix matrix = new Matrix(); private RectF mRectF = new RectF(); private Handler mHandler; private long mCurrentTime; public void setFaces(Camera.Face[] faces) { mFaces = faces; invalidate(); } public FaceView(Context context) { super(context); init(context); } public FaceView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public FaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } public void init(Context context) { mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStrokeWidth(5f); mPaint.setStyle(Paint.Style.STROKE); } public void setHandler(Handler handler) { mHandler = handler; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mFaces == null || mFaces.length < 0) { return; } //準備矩形框 MainActivity.prepareMatrix(matrix, false, 270, getWidth(), getHeight()); canvas.save(); matrix.postRotate(0); canvas.rotate(-0); RectF tempRectF = new RectF(); long tempTime = System.currentTimeMillis(); for (int i = 0; i < mFaces.length; i++) { mRectF.set(mFaces[i].rect);//獲取face矩形框值 float temp = mRectF.top; mRectF.top = -mRectF.bottom; mRectF.bottom = - temp; //上下交換 matrix.mapRect(mRectF); canvas.drawRect(mRectF, mPaint);//繪制矩形框 tempRectF.set(mRectF); if((mCurrentTime == 0) ||((tempTime-mCurrentTime)/1000) >= 4) {//超過4秒,發送一次識別face矩形框值 mHandler.sendMessage(mHandler.obtainMessage( MessageConst.CLIENT_ACTION_UPDATA_FACEDECTION_DATA, tempRectF)); mCurrentTime = tempTime; } Log.i("ppp","mRectF.left = "+mRectF.left+" mRectF.right = "+mRectF.right); } canvas.restore(); }
}
自定義FaceView中,由于旋轉了270度,所以需要face矩形框上下值進行交換,不然人臉識別總是左右或者上下不能追蹤。每隔4秒發送一次矩形框的值,在MainActivity.java的handler中收到這個消息并進行是否居中的判斷。
case MessageConst.CLIENT_ACTION_UPDATA_FACEDECTION_DATA:
if(mIsRecording) break; RectF rect = (RectF) msg.obj; mLeft = rect.left; mRight = rect.right; mTop = rect.top; mBottom = rect.bottom;//保存上下左右的矩形框值 float centerx = mLeft +(mRight - mLeft)/2;//獲取矩形框橫向中心點位置 float centery = mTop + (mBottom-mTop)/2;//獲取矩形框縱向中心點位置 String promptString = ""; if(centerx100) promptString = "位置偏左,"; else if((centerx > mScreenCenterx)&& (Math.abs(centerx -mScreenCenterx)>100)) promptString = "位置偏右,"; if((centery < mScreenCentery)&&( Math.abs(mScreenCentery-centery) >200)) { if("".equals(promptString)) promptString = "位置偏上"; else promptString += "并且偏上"; } else if((centery > mScreenCentery)&& (Math.abs(centery -mScreenCenterx)>200)) { if("".equals(promptString)) promptString = "位置偏下"; else promptString += "并且偏下"; } if("".equals(promptString)) { promptString = "位置已經居中,可以拍照了"; mIsCenter = true; } else { mIsCenter = false; } ITtsListener ttsListener = new ITtsListener() { @Override public void onPlayEnd() { if(mIsCenter) { if(mOlamiVoiceRecognizer != null) mOlamiVoiceRecognizer.start(); } } @Override public void onPlayFlagEnd(String arg0) { } @Override public void onTTSPower(long arg0) { } }; TtsPlayer.playText(MainActivity.this, promptString, ttsListener,Tts.TTS_SYSTEM_PRIORITY);
break;
可以獲得屏幕的中心點和人臉識別的矩形框的中心點,對比橫向和縱向的中心點大小和絕對值差,當橫向的值差100像素以上就認為橫向不居中,并且根據大小分居左和居右,縱向大小差值在200像素以上認為縱向不居中,并且根據大小分偏上和偏下,這個100,200像素值用戶可以自己調節到合適的值。
調用TtsPlayer.playText提示,當播報結束后回調到onPlayEnd() ,如果居中那么已經提示用戶可以拍照了,此時啟動錄音程序,用戶不用點擊button也不用喚醒,只許說拍照或者茄子就可以拍照了。
6.源碼下載鏈接
https://pan.baidu.com/s/1qXITWs8
7.相關鏈接
語音在線聽書:http://blog.csdn.net/ls0609/a...
語音記賬demo:http://blog.csdn.net/ls0609/a...
olami開放平臺語法編寫簡介:http://blog.csdn.net/ls0609/a...
olami開放平臺語法官方介紹:https://cn.olami.ai/wiki/?mp=...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67610.html
摘要:前言阿里巴巴機器智能實驗室線下智能團隊從年底開始涉及線下智能領域,從算法工程產品化業務落地多個方面入手,與合作伙伴們一起取得了一些小小的成績。目前,該套工具作為推薦的量化工具廣泛應用在阿里集團內多個線下業務場景中。 showImg(https://segmentfault.com/img/remote/1460000019246850); 阿里妹導讀:AI 技術已經從互聯網走向零售、...
摘要:這群小伙伴們堅信的強大能力,堅信可以模擬人類很多的感官功能,包括視覺聽覺,甚至包括思考能力給安裝上一個機械手臂,甚至可以模擬人類的肢體功能,這就是阿里云人工智能的能力。 阿里云人工智能 ET, 代表的是阿里云語音識別、語音合成、自然語言理解、實時圖像識別、機器學習的綜合技術,背后是阿里云飛天系統強大的計算能力。 可是這么高大上的 ET,最近居然開始不務正業了,來看看它都干了啥!!! 視...
摘要:的人工智能版圖人工智能版圖由應用平臺框架三大部分組成應用層是提供各種應用服務,比如平臺層是平臺。應用層主推三大成熟應用基于深度學習的圖像和視頻分析它能實現對象與場景檢測人臉分析面部比較人臉識別名人識別圖片調節等功能。AWS的人工智能版圖 AWS人工智能版圖由:應用、平臺、框架三大部分組成 AI應用層:是提供各種應用服務,比如Amazon Rekognition、Polly...
摘要:的人工智能版圖人工智能版圖由應用平臺框架三大部分組成應用層是提供各種應用服務,比如平臺層是平臺。應用層主推三大成熟應用基于深度學習的圖像和視頻分析它能實現對象與場景檢測人臉分析面部比較人臉識別名人識別圖片調節等功能。 AWS的人工智能版圖AWS人工智能版圖由:應用、平臺、框架三大部分組成AI應用層:是提供各種...
閱讀 1642·2023-04-25 18:27
閱讀 1393·2021-10-19 11:44
閱讀 570·2021-10-14 09:42
閱讀 2143·2021-10-11 10:59
閱讀 2777·2021-09-24 09:47
閱讀 1727·2019-08-30 14:20
閱讀 1156·2019-08-30 14:08
閱讀 735·2019-08-29 15:15