2013年4月21日 星期日

android apps範例_Augment Reality(AR)擴增實境

前言:
上次那篇android apps範例_camera就是為了這篇AR(擴增實境)預做準備的, 剛剛完成prototype,
程式碼在Acer Iconia B1 A71上面測過是OK的,相關程式碼以及開發過程稍微整理一下就寫了這篇blog. 若有不周,歡迎批評指教, 缺漏的部份日後會慢慢補上. 轉貼或引用本篇blog內文章段落, 不必交代出處.不過程式碼的部分是參考日本網站(google搜尋NyARToolkit)而做修改的,拿android 1.0版的老舊程式改成android 4.2版的,所以相關著作權法律的問題請注意一下!
過程:
AR(Augment Reality_擴增實境)近來頗流行的, 就是用攝影機拍攝進來的畫面經過電腦解析後,
將有用的資訊用文字或圖像的方式結合原來實景, 秀在螢幕上, 本範例就是用camera將實景拍攝進來,偵測畫面範圍內是否有mark(標示物)存在,若有的話就以文字方式秀座標在畫面內, 然後整個秀在螢幕上!

所有程式碼下載連結:
https://docs.google.com/file/d/0B6EVEd5P2B9cNDctbHJCVGFwOGs/edit?usp=sharing

5/5/2013補充:
4月22日 (13 天以前)
-整理code改版的心路歷程:
1.首先拿到android1.0版的程式後,匯入eclipse內,補足缺少的部分(target android4.2 project 目錄tree結構跟android 1.0 project差異大),修正紅色打叉的部分,舊function不能用的,用新function替代掉,沒用到的就註解掉是最快的,
2.找到程式執行入口(C語言來說的話就是void main();),觀看整個flow,原先project是利用網路串流取得攝影機畫面,現在改成用Acer Iconia B1 A71本身的前置鏡頭,
 ->若能成功透過攝影機抓到畫面後,呼叫偵測的部分來偵測畫面範圍內是否出現mark,若出現則用OpenGL ES畫3D cube,這部分因為OpenGL ES也是舊版的,完全不適用,為了減少麻煩,這部分的程式暫時拿掉,改用秀'TEXT文字'取代,

3.build and then run,啥畫面都沒有,只好重頭檢查起,到底camera打開沒有?只好另闢camera專案來研究一下,詳情請見另一篇android apps範例_camera,
4.研究好之後將camera這部分的code套用進來,成功可以預覽畫面,接下來弄capture(Canvas canvas);就是將攝影機畫面抓進來,偵測mark是否存在,然後秀文字的這段,因為畫布canvas無法用holder.lockcanvas產生畫布的物件,所以改成畫布另外自己形成一個view用framelayout.addView的方式疊在camera preview那個view的上面,可以達到畫面合成的目的.
->原先在capture();內要做完畫畫布的動作改成capture();內只要偵測到mark,回傳mark所在位置座標給畫布view透過invalidate();呼叫畫布重繪onDraw();即可!
5.進到capture();內第一件事情就是抓畫面,抓畫面反應要一段時間,所以呼叫takePicture();後要等它一陣子(thread.sleep(500)),才能進行下一階段_偵測mark,
->偵測mark這部分程式沒動過保持原先的code,
->接下來是若偵測到mark要回傳座標,原先是想透過在capture();內呼叫畫布這個view的method(setresultf();)來達成,結果capture();內部無法建立畫布這個view的物件自然無從調用setresultf();只好叫capture();將座標回傳囉,
6.但是又發生setresultf();內無法直接呼叫invalidate叫view重繪(主程序中不能隨便改變view的內容),只好叫holder去處理handlemessage,抓到message來做處理時就可呼叫invalidate();
7.但是又發生setresultf();內部要用傳回message傳回view的物件時,傳回空的view物件,導致錯誤發生,將view這個字換成this就ok了,
->測試ok,偵測到mark就秀紅色座標在畫面上,其實mark也只認黑白相間的四方框,框內文字不一定是要Hiro,

p.s.本軟體使用方法->先去日本網站抓mark.jpg印出來,拿在鏡頭前面晃就會出現一排紅色文字顯示座標,

042713
1.接042213進度,準備利用秀出來的TEXT(座標)畫紅色正方形外框框住mark->failed!因為那根本不是被偵測到的mark的四個頂點座標,而是座標變換矩陣,
->x,y,z 3d座標加上oritation(轉向),是專門餵給OpenGL ES的東西,所以現在直接跳過2D紅框,直接做OpenGL ES,等以後有空再來搞自己的2D偵測引擎,
->弄openGL ES前,先實驗一下,靜態固定座標秀3D 旋轉cube,發現被蓋掉一半,雖然程式是把openGL那層surfaceView疊加到camera preview之上,

042813
1.若只要2D->追code,轉換成opengl座標之前的座標是多少?<-failed!
2.另外一個TEXT mode未傳出的變數是誰?<-這招沒效,還是要去看src或官網,
3.做簡單openGL實驗(原點或是矩陣的影響力多大)<-亂try也不是辦法,還是上網去查openGL繪圖原理比較實在一點,
->昨晚弄3d的弄不出,只好回歸2d,可是座標頂點又弄不出來,
src code,官網(似乎openGL以原點為準,其他都是靠'定點座標'乘上'投影矩陣'或是'MODELVIEW'矩陣?
->先看書(有起始原點,再對照定點座標頂點,是否有乘上其他矩陣就不得而知了),再對照AR原始code有關openGL那段,
->看來還是要先玩會簡單的openGL例子再說了...
->next:
 1.做簡單openGL實驗(原點或是矩陣的影響力多大),上網查openGL繪圖原理,
2.解決如何將camera的preview(surfaceView)跟openGL ES(surfaceView)疊在一起?

050113突破_成功疊兩層:
原因在一個異想不到的地方"glView.setEGLConfigChooser(8,8,8,8,16,0);",

050413
1.弄到能將float[16] arp,跟float[16] resultf都能從capture();內傳出來,
  - a.先畫固定的cube,
  - b.畫出正確位置的cube(站在mark上面),

050513
下午完成a,b兩部分,又微調了一下(mark size跟調整螢幕為橫向),詳細的調整去看華盛頓網站,
p.s.Cube站的位置跟實際的mark所在處仍有些微差距,

所有程式碼下載連結(OpenGL ES版):
https://docs.google.com/file/d/0B6EVEd5P2B9cMVJjTF82WE1wcVE/edit?usp=sharing

沒有留言:

張貼留言