2013年11月18日 星期一

zxing barcode qrcode in android 使用方法

1. 先下載https://code.google.com/p/zxing/

2. 解壓縮後要編core.jar 進入core中打mvn -DskipTests -Dgpg.skip=true install 基本上要作修改的要編整個core , 如果只想使用的可以用migration 

3. 在eclipse中import整個android project

4. properties -> java build path -> add external jar 將剛剛打包好的jar丟入即可

2013年10月24日 星期四

GLImageProcessing image effects in opengl

將圖檔存入opengl texture memory
首先要先看懂texture environment的用法 http://www.khronos.org/opengles/sdk/1.1/docs/man/glTexEnv.xml 




brightness
//告訴目前貼圖環境為GL_COMBINE
//告訴目前貼圖環境為GL_COMBINE
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
if (t > 1.0f)
{
//對於GL_COMBINE_RGB參數為GL_ADD 也就是相加
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_ADD);
//顏色ARRAY
glColor4f(t-1, t-1, t-1, t-1);
}
else
{
//對於GL_COMBINE_RGB參數為GL_SUBTRACT 也就是相減
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_SUBTRACT);
//again顏色ARRAY
glColor4f(1-t, 1-t, 1-t, 1-t);
}
//對於RGB的第一個resource為材質
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
//對於RGB的第二個resource為顏色array
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
//對於Alpha的方式為GL_REPLACE
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
//第一個resource為材質
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_TEXTURE);

before drawarrays , order is not important .
基本上0.5 1.5左右就全黑全白了 以general color來說




constract


// One pass using two units:
// contrast < 1.0 interpolates towards grey
// contrast > 1.0 extrapolates away from grey
//
// Here, the general extrapolation 2*(Src*t + Dst*(0.5-t))
// can be simplified, because Dst is a constant (grey).
// That results in: 2*(Src*t + 0.25 - 0.5*t)
//
// Unit0 calculates Src*t
// Unit1 adds 0.25 - 0.5*t
// Since 0.5*t will be in [0..0.5], it can be biased up and the addition done in signed space.
此為extrapolate(外推)公式 取X_0 = 0 X_1 = 0.5 X_2 = t                        Y_0 = degen  Y_1 = src  便可算出Y_2

GLfloat h = t*0.5f;
告訴目前貼圖環境為GL_COMBINE
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//GL_MODULATE  Arg0 × Arg1

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_MODULATE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_TEXTURE);
//使用第二層紋理 是個灰階圖
GLubyte half[4] = { 0x80, 0x80, 0x80, 0x80 };

glActiveTexture(GL_TEXTURE1);
//這裡只對目前actived texture做enable
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//GL_ADD_SIGNED Arg0 + Arg1 - 0.5
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_ADD_SIGNED);
//C f represents the primary color of the incoming fragment, and C p represent the color computed from the previous texture stage or C f if processing texture stage 0
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
//Arg1使用GL_SRC_ALPHA = A f
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,     GL_SRC_ALPHA);
//RGB x 2
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,        2);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_PREVIOUS);
glColor4f(h, h, h, 0.75 - 0.5 * h); // 2x extrapolation


簡單來說就是達成上面算好的公式 第一層用GL_MODULATE 第二層用GL_ADD_SIGNED去混合這些紋理 第二層比較tricky

saturation

這特效使用一個灰階的texture當作基底來合成

首先要產生灰階的texture







saturation


GLfloat lerp[4] = { 1.0, 1.0, 1.0, 0.5 };

GLfloat avrg[4] = { .667, .667, .667, 0.5 }; // average
GLfloat prcp[4] = { .646, .794, .557, 0.5 }; // perceptual NTSC
    //NTSC, named for the National Television System Committee,[1] is the analog television system that is used in most of North America, parts of South America (except Brazil, Argentina, Uruguay, and French Guiana), Myanmar, South Korea, Taiwan, Japan, the Philippines, and some Pacific island nations and territories (see map).
 GLfloat dot3[4] = { prcp[0]*t+avrg[0]*(1-t), prcp[1]*t+avrg[1]*(1-t), prcp[2]*t+avrg[2]*(1-t), 0.5 };
 
 // One pass using two units:
 // Unit 0 scales and biases into [0.5..1.0]
 // Unit 1 dot products with perceptual weights

lerp是第一張texture的constant , avrg為灰階平均像素資料 , prcp是電視顏色基準

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); //Arg0 x Arg2 + Arg1 x (1-Arg2) glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); //Constant means Color of GL_TEXTURE_ENV_COLOR glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR, lerp); // Note: we prefer to dot product with primary color, because // the constant color is stored in limited precision on MBX glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); //GL_DOT3_RGB or GL_DOT3_RGBA 4*((Arg0r - 0.5) * (Arg1r - 0.5) + (Arg0g - 0.5) * (Arg1g - 0.5) + (Arg0b - 0.5) * (Arg1b - 0.5)) glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB); //refers to the color computed from the previous texture stage (or the incoming fragment if processing texture stage 0), glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); glColor4f(dot3[0], dot3[1], dot3[2], dot3[3]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

第一張貼圖使用interpolate看似很威 實際上的constant是 1 1 1 0.5 也就是說除了alpha RGB還是使用bind的texture , 實際上alpha算出來也是1 , 而第二章用DOT3_RGB可以轉換成灰階 , alpha不變 也就能產出灰階圖片了 接著的外推 透過extrapolate算出後在使用 去作rgb scale

2013年10月17日 星期四

image effects

此篇未完

剛好找到一個直接對image作處理的project讀的一些心得

RGB處理

作色偏處理 

將RGB[0 , 255] 作 mapping 對應到 [ n, m ]  , n m      [0 , 255] . 即可達到色偏的效果 .

Gaussian Blur

將一個像素取周遭的像素來作平均 該矩陣由normal distribution 2 dimensional取得,邊緣失去的像素我assume是由中間去遞補, 事實上不會是一個很難的filter if you have the conception of all these stuffs .

Sepia Filter
Sepia toning is a specialized treatment to give a black-and-white photographic print a warmer tone and to enhance its archival qualities. Chemicals are used to convert the metallic silver in the print to a sulfidecompound, which is much more resistant to the effects of environmental pollutants such as atmospheric sulfur compounds. Silver sulfide is at least 50% more stable than silver.

基本上就是套用以下formula
outputRed = (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189)
outputGreen = (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168)
outputBlue = (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131)





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)
        {

       }

2013年8月15日 星期四

淺談computer vision color detection .

淺談computer vision color detection .

bitmap基本的格式
透過android可取得bitmap上argb的32 bits位元,在此忽略alpha的影響只取RGB,將RGB轉成HSV格式,HSV是指H指hue(色相)、S指saturation(飽和度)、V指value(色調) 之color space,比起RGB它類似於人類感覺顏色的方式,具有較強的感知度,基本上一個是色環上有360度,每30度變換一種色彩,相對的顏色互補,RGB轉HSV有基本的公式,事實上我認為下面這圖直接解釋了對應關係
wiki上有詳盡的解釋以及資料
中文
英文 資料細節較為詳盡

我採用的第一種辨識方式就透過分析HSV的分布 將顏色分成12種
透過saturation 的程度分成色階以及灰階value分三種程度分別為鮮明的色彩 暗黑的色彩 以及黑色
此種分辨方法較為清楚且辨識度蠻高的,缺點是12種色彩的定義有些太相近。

第二種方法使用Nine color model

分辨法為下
(1) Value (V) was substituted by the Y of YIQ color
model.
(2) Black region: V<=0.225, S<=0.225 and V<0.8.
Code=1.
(3) White region: S<=0.225 and V>=0.8. Code=2.
(4) Color region: H ([0,360]) was divided into seven
intervals, [330, 20), [20, 35), [35, 65), [65, 165), [165,
200), [200, 270), [270, 330). The Code in turn were 3, 4,
5, 6, 7, 8, 9, namely red, orange, yellow, green, cyan, blue
and magenta, respectively.
取得九種顏色資料,此種辨識方法為一般監視器系統的色階,直接取得九種人類最常使用的九種顏色,辨識度似乎也比較簡略。

2013年7月30日 星期二

amazing

使用方法
1. 安裝
(請自行參考官網)
2. 進入ios app路徑執行(需有adb)
apportable load
3. 可以下載範例遊戲tweejump測試
https://github.com/haqu/tweejump


its really amazing
可以把ios (iphone) app 直接編成 android apk .
對於一些用opengl cocos2d開發的遊戲支援性才高
支援的內建library並不多 一般app幾乎編不過 編過似乎也沒畫面
別人寫好的library也幾乎編不過去
我們ipad版的flipover我有編到有畫面聲音的程度 但是retina下整個畫面還是會跑掉


一些function必須在java端重寫 方法如下
http://docs.apportable.com/using-java.html#calling-android-methods
直接使用android framework function有包好的如下
http://static.apportable.com/documentation/BridgeKit/html/
一些轉移成功的範例
http://www.apportable.com/customers



2013年6月20日 星期四

一個月內熟悉一種程式語言,似乎已經快過了這年紀了,