2013年9月26日 星期四

background removal algogo !

關於這點是研究不完的,能用的演算法之多,符合怎樣的場景使用哪種等,我想這邊不該是講這些的地方,應該留給研究生去研究。
那麼主要講的是基本的圖形演算法的幾個東西 dilation erosion .
我用的演算法非常簡單,基本上就是設定個threshold ,讓顏色能夠透過threshold去作擴張。並且隨著距離作linear decay。
首先透過手在圖片上畫過的路徑取點,作分群演算法取出最大群組的顏色量,以那幾點當作基準點去作Dilation
Dilation
http://www.cs.princeton.edu/~pshilane/class/mosaic/images/dilation.png
不囉說直接看圖大概就知道Dilation在幹嘛,基本上我全用十字的參考去作dilate
http://ostermiller.org/dilate_and_erode.html
這網站對於Dilation有詳盡的implement可以參考。
但是對於程式判斷出來的區塊,用這麼簡易的threshold去作判別出來的區塊是非常殘破的,這時候才是Dilation and Erosion發揮的地方。
首先對自己判斷出來的區塊作fixed times Dilation,之後再對已存在的區塊作the same times Erosion
最後出現的區塊就會非常完整,Dilation and Erosion那步驟吃掉了破碎的像素
整個spirit就如同上述所敘的,很容易吧。。
。。實際上運作起來會死人的
首先假設一張很普通的圖,say 800x600好了,那實際上就有480000個像素,所需要的bitmask就要有480000個,不要太囂張用bitwise那還得在寫一些macro去實作,用最小的uint8好了,也會有480000bytes,那也要將近0.5mb的記憶體,這已經是很小張的圖片以及最保守的bitmask了。
再來就是計算點位的問題,假設你第一步的Dilation不要太多,兩百pixel就夠了,200pixel在800x600的圖來看只吃掉了1/4個距離,也就是說每一步你只能擴張1/4左右的圖片大小,所需要掃描的次數為800x600x200次...恩,我本來跑在simulator覺得沒什麼,還是一樣快,真正跑在ipad3才發現,跑完一次要五六秒。。這還只是average。。
直接講我目前版本的三個步驟final的作法好了
對於那些點存進兩個set container,輪流作reset,將第一次dilate的點存進另一個container,這樣不斷的來回作你想要dilate的次數,這樣可以避免每次都要掃600x800次,但這部份的速率感覺上並沒有比600x800實作良好的continue快許多,畢竟物件也是有效率的問題。
最後的dilation我取20好了,也就是作800x600x20次,速度還是在0.2秒內完成。
最慘的是erosion,最近才發現erosion做了兩秒多,並且這部份似乎好像沒有簡化的方法,直到目前我才想到一個好方法!就是在上述的public dilation中,取出最後一次dilation的點存進container,而直接用那些點去作dilate就夠了,直到這部份的完成,目前整個作一次消背景的動作average time可以壓在一秒左右,並且跑出的效果還ok

如此複雜背景的圖片,多花點步驟還是可以弄出不錯的成果。


我目前覺得值得做的further
1. 回復上一步
2. 手動畫筆清除
3. 手動畫筆復原
4. 自動手動切換
5. 全部重作
6. threshold的調整
7. dilate width的調整
甚至能想到的further應該都有辦法作,目前就先如此了。

2013年9月6日 星期五

google calendar api使用方法

-- brief version
ios
透過oauth2認證後,取得GTLServiceCalendar對象,便可對calendar list作query,query的流程為一個CalendarListTicket,取得list資料後,可以從calendar-entry裡面的id對calendar events作query。基本上整個calendar就只有兩個主要資料格式,calendar list and indicated calendar events list .
android
使用google play的機制取得google account,而後也是維持一個com.google.api.services.calendar.Calendar的對象,也是先取得calendar list後再對該id取得calendar內的events .
我所設計的格式都是一個叫core的物件去storage取得的資料,並且使用一個callback來更新ui,一開始取得的calendar list 出現頁面後,在經由點選取得該event lists 。
-- Detail version
ios 版
各類資料網站
https://code.google.com/apis/console
首先要上google develop申請project , 開啟calendar api的使用 會給你一組Client ID:Client secret: 是用來作oauth2.0認證的
而他推薦的library為
https://developers.google.com/google-apps/calendar/downloads?hl=zh-TW
點選ios版的 下載
需拉進HTTPFetcher OAuth2 Objects Utilities這四個資料夾 其他optional
並且拉進Service裡面你需要的google data api
code flow為
需維持GTLServiceCalendar一個對象,透過GTMOAuth2ViewControllerTouch可以透過畫面登入google id得取authenticate,傳給GTLServiceCalendar.auth .
認證過後就可以在透過他的方法取得calendar list ,
每個calendar list有subcategory events

- android 版
首先也是上android api console去註冊android需要的key ,
需要的資料為 package name , and key fingerprint SHA1
取得SHA1的方法如下
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
取的是debug key的fingerprint
註冊android key似乎需要反應時間

- importart
這邊使用google play的帳號來幫忙存取google account , 需要手機上有google play
需將google play弄成libery編譯至project內 參照下面說明
http://developer.android.com/google/play-services/setup.html
此外幾個重要的lib檔皆可參考demo裡面所附的jar檔
比較值得一提的是,整個google api應該也都是如此的flow。

2013年9月5日 星期四

Camera特效篇

--ios

在ios實作上基本上是比較困難的。basic on api supported and some technique issue and below .

Since then, Apple has ported some of their Core Image framework from the Mac to iOS. Core Image provides an interface for doing filtering of images and video on the GPU. Unfortunately, the current implementation on iOS has some limitations. The largest of these is the fact that you can't write your own custom filters based on their kernel language, like you can on the Mac. This severely restricts what you can do with the framework. Other downsides include a somewhat more complex interface and a lack of iOS 4.0 support. Others have complained about some performance overhead, but I've not benchmarked this myself.

但是實際上有了這個framework GPUImage ..

https://github.com/BradLarson/GPUImage

基本上使用起image camera video等特效可以說是非常簡單,甚至比使用一般framework的function還要簡單些,可以這麼說。

他也是基於opengl es 2.0下去撰寫的framework,內建的濾鏡多到看了就花了,即使如此還是支援glsl , opengl shader language . 關於這點我並沒有看太熟。

所謂的濾鏡為一個shader language,有五個
主要部分可以去作宣染著色,相較於opengl 1.0擁有更flexible , efficient的功能。


整個code flow先要一個GPUImageStillCamera的instance , 這instance為一個camera的畫面,並且可自行跟換濾鏡,而後濾鏡丟進stillcamera的instance之後隨即表現至螢幕上,使用拍照功能後則instance會丟出目前的image data出來。

我目前所寫的demo,我將我撈出來的所有濾鏡直接做成list可以更換,其中各種濾鏡都有參數可以去作調整,但是所有參數全都不一,所以目前下方的slider bar還沒有連結至各濾鏡,並且我並沒有去一一看各種濾鏡的效果,只有將會crash的濾鏡刪除而已。

這只是我撈濾鏡所使用的方法,並不需要看懂。
grep -Rl ": GPUImageFilter" * | sed -e s/framework\\/Source\\///g | sed -e s/\\.h//g | awk '{printf "@\"" ; printf $0 ; printf "\"," ; printf "\n" ;}' > ha.txt

to sum up , GPUImage提供了一般user很輕易的就能使用opengl es 2.0的功能來達到image video processing,甚至可以連內容都不用管的情況下來使用他內建的特效。


--android

android端真的就得一步一步來了,基本上整個flow不會太難,難的部份還是opengl 2.0去實現的部份,因為全程自己來所以下面的technique issue比較雜。

首先進入點是onPreviewFrame這個interface ,在於camera PreviewCallback,

public void onPreviewFrame(byte[] yuvs, Camera camera) 
在此camera這層會傳給你一組data stream called yuvs , as it says這image format為yuvs420的格式
http://en.wikipedia.org/wiki/YUV

而如果需要使用需要轉為rgb的格式,所以透過一個jni傳至c層去作decode。
public native void yuv420sp2rgb(byte[] in, int width, int height, int textureSize, byte[] out);
可以稍微簡介一下jni,他是個java native interface,千萬不要覺得他很難,他就是個java層對應到c層一個one-one mapping的function而已,你可以想像整個framework層就是透過一堆jni去將driver層的資料porting到framework層,扯遠了,總之他有個一固定的format可以讓你在java層可以使用c層的function,比較要注意的是package class name得跟native那層完全對應才行。

透過這個jni可以將資料轉為rgb格式,分別存在兩段buffer,在opengl層bind一個空材質texture,然後透過glTexSubImage2D不斷將指針指向這兩段buffer來作動畫的效果,既然傳進了gl這層,就可以透過shader來做到各種特效了,很遺憾的是我們得實作shader這層,這個open source有一些寫好的shader可以作參考。

簡略的講一下glsurfaceview的flow,在view create的時候call

public void onSurfaceCreated(GL10 gl, EGLConfig config)
在整個view的layout有改變時call
public void onSurfaceChanged(GL10 gl, int width, int height)
其餘整個frame會call
public void onDrawFrame(GL10 gl)
最好的情況,沒修改default的話每秒的frame是60個,也就是60fps,也就是說onDrawFrame會call六十次每秒。


等到拍照時,將當時的opengl pixels讀取出來,透過GLES20.glReadPixels,在opengl層的argb跟bitmap格式的argb的blue and red是對調的,所以要交換,然後透過bitmap factory將data轉存bitmap,就是整個android camera effect的特效了。

some shit


http://stackoverflow.com/questions/16483175/why-is-nsclassfromstring-returning-nil-or-not-in-these-two-cases

NSString* theClassName = /* assume this exists */
Class theClass = NSClassFromString(theClassName);
NSObject* myObject = [[theClass performSelector:@selector(alloc)] init];


grep -Rl ": GPUImageFilter" * | sed -e s/framework\\/Source\\///g | sed -e s/\\.h//g | awk '{printf "@\""; printf $0 ; printf "\"," ; printf "\n" ;}' > ha.txt

http://hi.baidu.com/hh20040410/item/d1eda629421d97cdddf69a6d

第一次安裝時間 android
if (Build.VERSION.SDK_INT >= 9)
     try {
          long installed = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).firstInstallTime;
           params.put("installDate", dateFormat.format(new Date(installed)));
         }
        catch (Exception e)
        {

       }