Android平臺美顏相機/Camera實時濾鏡/視頻編解碼/影像後期/人臉技術探索——1.1 工程思路與難點

回到目錄

本文主要探討搭建一款Android平臺下美顏相機可能需要填的坑,內容會不斷更新。。

相機框架

相機框架相對比較簡單,現有的開源代碼很多,可以很容易的實現拍照和錄像的功能。

預覽尺寸選擇

預覽尺寸就是相機顯示紋理的尺寸,也是每一幀原始數據的尺寸,一般相對拍照尺寸較低(1080P就算比較高的預覽尺寸了)

拍照尺寸選擇

拍照尺寸只在拍照時起作用,往往可以調的很高,而且獲取數據非常快(例如1300萬像素,相當於1080P數據的7倍左右)

拍照:已被棄用的Camera API可以提供takePicture進行拍照,在onPictureTaken(final byte[] data, final Camera camera)中可以獲得包括了Exif數據的圖片,直接寫入到文件就是一張沒有做過任何處理的照片,也可以轉成bitmap再做處理(圖片尺寸就是拍照尺寸),但是很容易出現OOM的問題,例如1300萬像素的照片至少佔內存50M,分分鐘死給你看。

錄像:使用MediaRecorder可以進行錄像,相機需要在錄像模式和預覽模式之間切換,使用較爲方便

獲取每一幀數據:onPreviewFrame(byte[] data, Camera camera)中可以獲取到每一幀的原始數據,如果處理不及時下一幀就會被丟棄,幀率並不是固定的(也就是可能比相機預覽的速度慢很多),這裏的圖像大小和設定的預覽尺寸相同

Camera2 API

後期會切換到這個API,ImageReader類確實封裝的很好,雖然我還沒搞清楚怎麼獲取原始數據

實時濾鏡

用CPU來處理圖像真的太慢慢慢慢慢慢了,尤其是在移動平臺下,因此一定要用GPU來加速處理。
由於是圖像處理,OpenGL尚能夠勝任,而且兼容性和通用性都比較好,所以不考慮RenderScript和OpenCL,相機的數據可以直接利用GL_TEXTURE_EXTERNAL_OES進行GPU加速的格式轉換,在顯示層面不需要自己再做YUV420SP/YUV420P到RGB的轉換,之後就可以使用GL_TEXTURE_2D來進行各種處理。GPU相對CPU要快很多,舉個例子:在Mali400MP1這種渣渣GPU上,高斯模糊可以在720P的圖像上連續處理6次依然絲般潤滑毫無卡頓之感。

疊加特效後拍照/截屏/離屏渲染

在疊加了濾鏡、面具、面部貼紙後,如果要拍照,有兩種可能的解決方案:
拍照後離屏渲染:效率較高,但是較爲複雜,需要自行管理一個工作線程,因爲照片的尺寸遠大於預覽的紋理尺寸,而且內存開銷較大,適合於軟件定位爲圖像處理/專業相機應用時的情況,拍完照片後不影響後續拍照,用戶體驗可以做的很棒(例如各大國產ROM自帶的濾鏡功能,拍完後不會感覺到任何卡頓)
直接對Surface截屏:這是最簡單粗暴的方法,代碼簡單,非常魯棒,內存佔用也低(畢竟屏幕分辨率2K已經算高了,也才200萬像素),經過測試,Snow相機和FaceU都是採用的這種方法,特點是方便快捷,但是生成的圖片尺寸較小(一般就是屏幕分辨率),適合於軟件定位爲偏社交相機應用的情況,拍完照直接編輯預覽。

錄屏錄像

錄屏在Android 5.0之前是沒有提供接口的(需要root),如果是5.0及以上版本錄屏(直播)就會非常方便,但是如果只是錄製相機的預覽區域就不同了(對於Surface進行錄製)
硬編:硬件編碼的CPU佔用低,碼率可以拉的很高,不卡頓,MediaRecorder可以直接錄製視頻,但是沒法實時處理,在5.0及以上版本也可以錄製Surface了,但是封裝的太好,使用並不自由。
MediaCodec是一個相對“野生”的API,最常用的硬編格式是”video/avc”,也就是喜聞樂見的h264格式,目前大部分手機都支持硬編(Snow相機、FaceU以及各大直播軟件都首選此方案),雖然要求API在4.3以上才能夠比較完美的運行,但是不能硬編的手機真的太少了(除了我的破手機)
MediaCodec可以直接對Surface進行錄製(參考 Google的grafika),因爲我們直接使用了SurfaceTexture做預覽,不需要每次都獲取原始數據在用BufferQueue喂數據,這也就意味着我們可以很容易的讓預覽結果和錄製視頻的結果不同,分辨率也可以不同,例如視頻中可以實時打水印,但是預覽不顯示水印之類的(當然一般是相同的)
軟編:軟編就是用CPU來進行編碼,常見的例如FFMpeg軟編,資源佔用高,可能卡頓,增大APK體積,但是兼容性很好,還可以一直兼容到原始社會(Android2.3)

圖像後期

如果定位專業相機軟件,那麼圖像後期的功能就多了去了,完全可以把整個PS都搬過來,如果是偏向社交的軟件,那麼後期主要是一些美化,加文字、貼圖的效果(當然一鍵分享到朋友圈是一定一定一定要有的功能)

視頻後期/轉碼

視頻後期其實和實時錄製比較類似,就是一個解碼,加特效再編碼的過程,當然分辨率和碼率就可以很高很高啦,畢竟不是實時的應用

人臉相關應用

實際上,穩定高效的人臉檢測、對齊纔是在做一款美顏類APP是會碰到的最大的問題。市場上主流的軟件也都是採用第三方的解決方案,例如商湯(ST)、虹軟(ArcSoft)、Face++、優圖(Tencent)等,雖然實時的人臉識別技術歷史悠久,但是最近的直播熱好像又讓她煥發了新生。
現在人工智能大熱,不管什麼方向好像深度學習都能取得非常優異的成績,也正興起着一股把神經網絡搬到移動平臺上來的風潮(OpenCL、RenderScript、Vulkan、Metal等,當然也有直接上CPU跑的),神經網絡用來處理圖像,識別物體的App大家應該也都見過不少。
然而,如果要在線處理,就要保證算法足夠高效,在移動平臺上好像還沒有公認的很好的公開解決方案。OpenCV的LBP做人臉檢測其實很好,但是還有待調教,其他的像JDA、npd等都可以考慮。
在Github上轉了一圈,找到不少開源項目,有C語言的,Java封裝的,Python封裝的,居然還有.so語言的,真是讓我大開眼界。
個人感覺國內這一塊的風氣並不是很好,稍微有點小成果就拿去圈錢(@於仕琪老師,多向山老師學學),當然這也好理解,畢竟難度遠高於拿着別人的輪子自己調調UI做一個App上線,大家都不容易嘛。

有了人臉的特徵點就可以做很多很多事情了,例如換臉肯定就建立在高效的人臉特徵點跟蹤上,剩下的就是貼個圖的事情(例如OpenGL的Blend),如果是臉部貼紙就更輕鬆了。當然,”美顏2.0”也是建立在人臉識別的基礎上(例如大眼小臉),如果沒有人臉檢測,就只能做做膚色、光線調整什麼的,或者來個哈哈鏡,功能就會大受限制。

直播推流

直播推流有很多現有的解決方案,可能也並不是美顏相機的重點(是直播App的重點呢,哈哈),但是直播App和美顏相機用到的技術有很大的交集,因此直播推流也會成爲後期探索的內容之一(例如硬編錄屏推流,軟編錄像等等)。
回到目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章