android-camera2相機(jī)開發(fā)【8】-使用opengl實(shí)現(xiàn)濾鏡效果(1)

前一篇文章中,實(shí)現(xiàn)了 opengles 進(jìn)行相機(jī)預(yù)覽的功能株茶,基本的流程如下:

  1. 把相機(jī)的預(yù)覽數(shù)據(jù)做成紋理来涨,綁定到opengles對應(yīng)的紋理單元上
  2. 然后通過opengles 的內(nèi)置函數(shù) texture(),在片段著色器中根據(jù)紋理和紋理坐標(biāo)進(jìn)行插值計(jì)算
  3. 直接將計(jì)算結(jié)果輸出到顏色緩沖區(qū)启盛,顯示到屏幕的像素上蹦掐。

給圖像添加濾鏡本質(zhì)上就是圖片處理,也就是對圖片的像素進(jìn)行計(jì)算僵闯,簡單來說卧抗,圖像處理的方法可以分為三類:

  1. 點(diǎn)算子:當(dāng)前像素的處理只和自身的像素值有關(guān),和其他像素?zé)o關(guān)鳖粟,比如灰度處理社裆。
  2. 鄰域算子:當(dāng)前像素的處理需要和相鄰的一定范圍內(nèi)的像素有關(guān),比如高斯模糊向图。
  3. 全局算子:在全局上對所有像素進(jìn)行統(tǒng)一變換泳秀,比如幾何變換标沪。

實(shí)現(xiàn)濾鏡的思路

濾鏡本質(zhì)上就是對每個位置的顏色值進(jìn)行調(diào)整,比如灰度效果嗜傅,就是將彩色圖像的各個顏色分量的值變成一樣的金句。

對顏色值進(jìn)行調(diào)整的時機(jī)應(yīng)該是再上面步驟的2、3之間吕嘀,這個時候已經(jīng)拿到了顏色值违寞,還沒有輸出到顏色緩沖區(qū),這個時候我們對顏色值進(jìn)行處理就可以實(shí)現(xiàn)濾鏡效果偶房。

用上一篇的片段著色器代碼做個說明:

#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;

in vec2 v_texCoord;
out vec4 outColor;
uniform samplerExternalOES s_texture;

void main(){
    //拿到顏色值
    vec4 tmpColor = texture(s_texture, v_texCoord);
    //對顏色值進(jìn)行處理
    process(tmpColor);
    //將處理后的顏色值輸出到顏色緩沖區(qū)
    outColor = tmpColor;
}

點(diǎn)算子實(shí)現(xiàn)的濾鏡

灰度濾鏡

灰度濾鏡通過圖像的灰度化算法進(jìn)行實(shí)現(xiàn)坞靶。

在 RBG顏色模型中,讓 R=G=B=grey蝴悉, 即可將彩色圖像轉(zhuǎn)為灰度圖像彰阴,其中 grey 叫做灰度值。

grey的計(jì)算方法有四種:分量法拍冠,最大值法尿这,平均值法、加權(quán)平均法庆杜。

分量法

使用彩色圖像的某個顏色分量的值作為灰度值射众。

  • grey=R:R分量灰度圖
  • grey=G:G分量灰度圖
  • grey=B:B分量灰度圖

最大值法

將彩色圖像三個顏色分量中值最大的作為灰度值。

grey = max(R,G,B)

平均值法

將彩色圖像的三個顏色分量值的平均值作為灰度值

grey = (R+G+B)/3

加權(quán)平均法

在 RGB 顏色模型中晃财,人眼對G(綠色)的敏感度最高叨橱,對B(藍(lán)色)的敏感的最低,所以對彩色圖像的三個顏色分量做加權(quán)平均計(jì)算灰度值效果比較好断盛。

grey = 0.3R + 0.59G + 0.11*B

下面在片段著色器中用加權(quán)平均法實(shí)現(xiàn)灰度濾鏡罗洗。

#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;

in vec2 v_texCoord;
out vec4 outColor;
uniform samplerExternalOES s_texture;

//灰度濾鏡
void grey(inout vec4 color){
    float weightMean = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
    color.r = color.g = color.b = weightMean;
}

void main(){
    //拿到顏色值
    vec4 tmpColor = texture(s_texture, v_texCoord);
    //對顏色值進(jìn)行處理
    grey(tmpColor);
    //將處理后的顏色值輸出到顏色緩沖區(qū)
    outColor = tmpColor;
}

效果圖

原圖 灰度濾鏡
image
image

黑白濾鏡

黑白濾鏡就是將圖像進(jìn)行二值化處理,彩色圖像的顏色值經(jīng)過處理之后钢猛,要么是 0(黑色)伙菜,要么是255(白色)。

實(shí)際應(yīng)用中使用的不多命迈,從各大直播贩绕、美顏相機(jī)、短視頻app上就能發(fā)現(xiàn)壶愤,基本上沒有用黑白濾鏡淑倾,因?yàn)椴缓每础?/p>

二值化方法主要有:全局二值化,局部二值化征椒,局部自適應(yīng)二值化娇哆。最影響效果的就是閾值的選取。

  • 全局二值化是選定一個閾值,然后將大于該閾值的顏色值置為255迂尝,小于該閾值的顏色置為0脱茉。因?yàn)槭褂玫娜珠撝担詴适Ш芏嗉?xì)節(jié)垄开。
  • 局部二值化:為了彌補(bǔ)全局閾值化的缺陷琴许,將圖像分為N個窗口,每個窗口設(shè)定一個閾值溉躲,進(jìn)行二值化操作榜田,一般取該窗口顏色值的平均值。
  • 局部自適應(yīng)二值化:局部二值化的閾值選取方法仍然不能很好的將對應(yīng)窗口的圖像進(jìn)行二值化锻梳,在此基礎(chǔ)上箭券,通過窗口顏色的平均值E、像素之間的差平方P疑枯、像素之間的均方根Q等能夠表示窗口內(nèi)局部特征的參數(shù)辩块,設(shè)定計(jì)算公式計(jì)算閾值。

這里使用最簡單的全局二值化做個示例

//黑白濾鏡
void blackAndWhite(inout vec4 color){
    float threshold = 0.5;
    float mean = (color.r + color.g + color.b) / 3.0;
    color.r = color.g = color.b = mean >= threshold ? 1.0 : 0.0;
}

效果圖

原圖 黑白濾鏡
image
image

反色濾鏡

RGB 顏色值的范圍是 [0,255]荆永,反色濾鏡的的原理就是將 255 與當(dāng)前顏色的每個分量Rs,Gs,Bs值做差運(yùn)算废亭。

結(jié)果顏色為 (R,G,B) = (255 - Rs, 255 - Gs, 255 - Bs);

//反向?yàn)V鏡
void reverse(inout vec4 color){
    color.r = 1.0 - color.r;
    color.g = 1.0 - color.g;
    color.b = 1.0 - color.b;
}

效果圖

原圖 反色濾鏡
image
image

亮度濾鏡

增加亮度有兩種方法:

  1. 再 rgb 顏色空間下,將各個顏色分量都加上一個值具钥,可以達(dá)到圖像亮度增加的目的豆村,但是這種方式會導(dǎo)致圖像一定程度上偏白。
  2. 將顏色值從 rgb 顏色空間轉(zhuǎn)換到 hsl 顏色空間上骂删,因?yàn)?hsl 更適合視覺上的描述掌动,色相、飽和度宁玫、亮度粗恢,調(diào)整 l(亮度分量),即可實(shí)現(xiàn)圖像的亮度處理撬统,然后將調(diào)整后的 hsl 值再轉(zhuǎn)換到 rgb 顏色空間上進(jìn)行輸出适滓。

各顏色空間轉(zhuǎn)換方法

下面以第2中方式為例:

//rgb轉(zhuǎn)hsl
vec3 rgb2hsl(vec3 color){
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(color.bg, K.wz), vec4(color.gb, K.xy), step(color.b, color.g));
    vec4 q = mix(vec4(p.xyw, color.r), vec4(color.r, p.yzx), step(p.x, color.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

//hsla轉(zhuǎn)rgb
vec3 hsl2rgb(vec3 color){
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(color.xxx + K.xyz) * 6.0 - K.www);
    return color.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), color.y);
}

//亮度
void light(inout vec4 color){
    vec3 hslColor = vec3(rgb2hsl(color.rgb));
    hslColor.z += 0.15;
    color = vec4(hsl2rgb(hslColor), color.a);
}
原圖 亮度濾鏡
image
image

項(xiàng)目github地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恋追,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罚屋,老刑警劉巖苦囱,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異脾猛,居然都是意外死亡撕彤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羹铅,“玉大人蚀狰,你說我怎么就攤上這事≈霸保” “怎么了麻蹋?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長焊切。 經(jīng)常有香客問我扮授,道長,這世上最難降的妖魔是什么专肪? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任刹勃,我火速辦了婚禮,結(jié)果婚禮上嚎尤,老公的妹妹穿的比我還像新娘荔仁。我一直安慰自己,他們只是感情好芽死,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著掌呜,像睡著了一般坪哄。 火紅的嫁衣襯著肌膚如雪质蕉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天翩肌,我揣著相機(jī)與錄音,去河邊找鬼念祭。 笑死,一個胖子當(dāng)著我的面吹牛粱坤,可吹牛的內(nèi)容都是我干的系冗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼摆出,長吁一口氣:“原來是場噩夢啊……” “哼包券!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起株旷,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梯嗽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灯节,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缠俺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡磷雇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出躏救,到底是詐尸還是另有隱情,我是刑警寧澤崩掘,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布少办,位于F島的核電站,受9級特大地震影響英妓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蔓纠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一腿倚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧暂筝,春花似錦懈叹、人聲如沸乖杠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卫漫,卻和暖如春肾砂,著一層夾襖步出監(jiān)牢的瞬間列赎,已是汗流浹背镐确。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工源葫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人息堂。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像床未,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子薇搁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容