數字圖像處理、拼接,圖像靜態濾鏡(GPUImage/GPU加速) - Android

  圖像濾鏡處理的兩種方式:RGB點乘運算;GPU的矩陣運算(效率更高)。圖片處理中的計算:RGBA~利用自帶的方法修改色調,飽和度,亮度來修改圖片;矩陣~利用矩陣計算獲得新的矩陣修改圖片。html

  幾個圖像像素數據處理過程當中的幾個知識點:像素格式,圖像拉伸,YUV像素取值範圍,色域。java

  快手、美拍、Instagram、OPPO/ViVO 等。
  既然是圖像處理,那麼濾鏡的操做就主要是:卷積、像素映射、座標映射,反映到具體效果上,就是模糊銳化,覆蓋層(貼紙等),RGB曲線調整,旋轉縮放扭曲之類的。濾鏡本質就是像素點的座標和顏色的變化。
  濾鏡原理:ios經過顏色矩陣(ColorMatrix)和座標變換矩陣(Matrix)能夠完美的作出上面的所說的效果。視頻濾鏡,都是對視頻中的圖像幀進行操做來改變光影和色彩。android

  美顏有兩步,一個是磨皮,一個是美白,要想正確美顏,因此還須要加上人臉識別技術和皮膚識別技術。ios

濾鏡,圖形變換處理核心是拿到紋理對象的rgb作算法處理.git

【Android】自動瘦臉與眼睛放大美顏算法(shader)- https://blog.csdn.net/Taily_Duan/article/details/67636041github

> 圖像濾鏡
  基本濾鏡效果的實現:若是咱們用ColorMatrix調整RGB三種顏色的比重,就能夠實現諸如單色、黑白的效果。Lomo濾鏡效果的實現:改變圖像數值+遮罩。濾鏡包括遮罩、浮雕、模糊、濾鏡、漸變色、離散、透明等,而且實現了PATH的各類特效;web

-- 美顏等濾鏡功能Demo
Android實現圖像處理濾鏡功能特效實現(資源下載)- http://download.csdn.net/detail/jasonez/8788931
[圖片處理] 99種濾鏡效果 ImageFilterForAndroid-master- http://download.csdn.net/download/cleopard/8454813
ImageFilterForAndroid圖像渲染- http://download.csdn.net/detail/heng615975867/6593591
圖像處理濾鏡/美化ImageFilterForAndroid- https://github.com/daizhenjun/ImageFilterForAndroid
android 圖像處理濾鏡系列合集- http://blog.csdn.net/jingwen3699/article/details/7770287
Android實戰經驗之圖像處理及特效處理的集錦(總結版)- https://www.oschina.net/question/231733_44154
Android圖片各類處理效果源碼- http://download.csdn.net/download/lilidejing/7927579 
sangmingming/android-instagram-filter-- https://github.com/sangmingming/android-instagram-filter
imrunning/android-instagram-image-filter-- https://github.com/imrunning/android-instagram-image-filter
Instagram中最初的不到20個濾鏡的代碼與資源(InstagramFilters)- http://download.csdn.net/detail/oshunz/9335481
ImageFilterForAndroid-master- http://download.csdn.net/detail/cleopard/8454813
如何製做攝影類 app 中的濾鏡- https://www.zhihu.com/question/20073281
如何製做攝影類 app 中的濾鏡?- https://github.com/YuAo/YUCIHighPassSkinSmoothing
-- [Android] 圖像各類處理系列文章合集- http://blog.csdn.net/eastmount/article/details/40689397
Android實戰經驗之圖像處理及特效處理的集錦(總結版)- https://www.oschina.net/question/231733_44154
實時美顏濾鏡(ColorMatrix)- https://github.com/Guikunzhi/BeautifyFaceDemo  
實時美顏濾鏡(ColorMatrix)- https://github.com/BradLarson/GPUImage
Android視頻編輯器,給本地視頻加水印和美顏濾鏡- http://blog.csdn.net/qqchenjian318/article/details/78274901
圖像濾鏡處理算法:灰度、黑白、底片、浮雕 - http://www.icodelogic.com/?p=575
This is a sobel filter on Android using OpenCL to accelerate.OPenCV,在Android上還實現了不少種並行化的算法,好比SHA-一、HDR、K-means、NL-means、SRAD等- https://github.com/WhiteIsClosing/Android-OpenCL-Sobel-Filter算法

Android平臺美顏相機/Camera實時濾鏡/視頻編解碼/影像後期/人臉技術探索-http://blog.csdn.net/martin20150405/article/details/54766660
Android平臺美顏相機/Camera實時濾鏡/視頻編解碼/影像後期/人臉技術探索-http://blog.csdn.net/Martin20150405/article/category/6274984
照片美妝---每天P圖瘋狂變臉特效算法研究- http://blog.csdn.net/trent1985/article/details/71446860
圖像算法---磨皮算法研究彙總- http://blog.csdn.net/trent1985/article/details/50496969
人像美妝---妝容遷移算法研究(Makeup transfer)- http://blog.csdn.net/trent1985/article/details/70226779
圖像處理(二十一)基於數據驅動的人臉卡通動畫生成-Siggraph Asia 2014- http://blog.csdn.net/hjimce/article/details/47083321
-- 圖像處理濾鏡的話主要處理圖片的三原色,並根據三原色進行運算。
android 圖像處理濾鏡系列合集-- http://blog.csdn.net/jingwen3699/article/details/7770287
圖像濾鏡藝術- http://blog.csdn.net/Trent1985/article/category/2644207數據庫

opencv,圖像處理的第三方庫不少。
數字圖像處理研究- http://blog.csdn.net/Trent1985/article/category/1850555
圖像處理,圖像分割,特徵提取,機器學習,模式識別,深度學習等- http://blog.csdn.net/real_myth?viewmode=contents
OpenGL實踐- http://blog.csdn.net/wangkuifeng0118/article/category/1115152
OpenCV 3.1.0編譯與添加擴展模塊- http://blog.csdn.net/jia20003/article/details/54583431編程

 ImageMagik處理圖片的功能很強大 vs PhotoShop。ImageMagick是一套功能強大、穩定並且開源的工具集和開發包,能夠用來讀、寫和處理超過89種基本格式的圖片文件,包括流行的TIFF、JPEG、GIF、PNG等格式。利用ImageMagick,你能夠根據web應用程序的須要動態生成圖片, 還能夠對一個(或一組)圖片進行改變大小、旋轉、銳化、減色或增長特效等操做,並將操做的結果以相同格式或其它格式保存,對圖片的操做,便可以經過命令行進行,也能夠用C/C++、Perl、Java、PHP、Python或Ruby編程來完成。

-- GPUImage 圖像處理和實時濾鏡
美麗的濾鏡背後都是數學和藝術在支撐。相片磨皮;基於GPU的圖像處理和實時濾鏡,鼎鼎大名的GPUImage
gpuimage濾鏡- https://github.com/CyberAgent/android-gpuimage
 GPUImage的項目結構其實很簡單,android版本就更是簡陋,結構以下:
  1.一堆濾鏡(shader以及配套設置參數的代碼);
  2.FilterGroup(利用FBO進行同一副圖像的屢次處理);
  3.EGL管理類(主要用來作離屏渲染);
 雖然GPUImage的主要價值在那堆濾鏡上,可是咱們主要來分析後面兩個,這是GPUImage的框架,而濾鏡就像插件同樣,想插就插:D,咱們也能夠依葫蘆畫瓢定製本身的濾鏡。
  GPUImage是採用鏈式方法來處理畫面,經過addTarget方法添加對象到鏈中,處理完一個target,就會吧上一個環節處理好的圖像數據傳遞到下一個target處理,成爲GPUImage處理鏈。
  GPU工做原理:CPU指定顯示器工做,顯示控制器根據CPU的控制到指定的地方去取數據和指令,目前的數據通常是從顯存裏取,若是顯存裏存不下,則從內存裏取,內存也放不下,則從硬盤裏取。
  濾鏡處理的原理:就是把靜態圖片或者視頻的每一幀進行圖形變化後在顯示到屏幕上,其本質就是像素點的座標和顏色的變化。

  一個視頻通訊的基礎架構可能涉及到採集(音視頻採集)、前處理(例如噪聲處理、人臉識別等)、音視頻編解碼、流媒體協議、系統架構(如數據庫、文件系統)、CDN、播放控制(如音視頻同步)和交互技術等。MediaCodec,MediaMuxer,MediaFormat等.

-- 濾鏡在色彩處理中,一般使用如下三個角度來描述一個圖像:
  色調——物體傳播的顏色;飽和度——顏色的純度,從0(灰)到100%(飽和)來進行描述;亮度——顏色的相對明暗程度;在Android 的 ColorMatrix 顏色矩陣中也封裝了一些 API 來快速調整上面這三個顏色參數,而不用每次都去計算矩陣的值。

-- 美顏的實現的步驟是:https://www.2cto.com/kf/201604/498289.html
 1.用具備保邊效果的濾波算法對圖像進行模糊處理;
 2.用膚色檢測算法保護非皮膚區域;
 3.將模糊後的圖像和原圖進行圖像融合;
 4.對融合後的圖像進行銳化處理;

 - 美顏和濾鏡
  通常的思路是磨破+美白,即用相似雙邊濾波這樣的邊緣保持濾波器對膚色區域作平滑處理,而後作膚色的色調調節.
  根據RGB值識別皮膚部分,進行膚色調整,用具備保持邊緣效果的濾波算法對圖像進行模糊處理,用一些算法將模糊後的圖像與原圖進行融合,增長皮膚質感,此時的圖片會有一些朦朧感,銳化能夠強化邊緣,讓圖像更加清晰。
  自動瘦臉與眼睛放大能夠算做圖像局部扭曲算法的一個應用,其參考文獻能夠追溯至1993年的一篇博士論文- http://www.gson.org/thesis/warping-thesis.pdf.
  在1979年Lee發表的論文《Lee Filter Digital Image Enhancement and Noise Filtering by Use of Local Statistics》中,提出了基於局部信息去除加性噪音、乘性噪音及加性乘性混合噪音的方法,通過仔細的學習和編碼,發現其去除加性噪音的方法效果很是好,具備如今一些EPF算法相似的邊緣保留功能,而且其運算並不複雜,能夠應用到相似於磨皮這種項目中。http://imagej.net/Integral_Image_Filters. 皮膚識別有不少算法.

 - 美白算法: 借用色彩平衡算法;使用logarithmic Curve;使用圖層混合.。對人臉進行美白、磨皮、瘦臉和大眼等美化功能;磨皮算法 實時濾鏡。
  Smooth:皮膚平滑度,越高皮膚除;
  Skin Color:皮膚.色,low爲作紅.處理;
  Sharp:瘦臉&大眼程度,值越高表示程度越大。

-- OpenGL ES程序處理圖片的步驟:
1.初始化OpenGL ES 環境,編譯、連接頂點着色器和片元着色器。
2.緩存頂點、紋理座標數據,傳送圖像數據到GPU
3.繪製圖元到特定的幀緩存;
4.在幀緩存去除繪製的圖像。

> 圖像處理,圖像像素處理,圖像處理技術
【數字圖像處理的基本原理和經常使用方法】- https://blog.csdn.net/xCnhYKoHj3eK/article/details/80103618
  圖形和圖像信息。數字圖像處理做爲一門學科大約造成於 20 世紀 60 年代初期。早期的圖像處理的目的是改善圖像的質量,它以人爲對象,以改善人的視覺效果爲目的。圖像處理中,輸入的是質量低的圖像,輸出的是改善質量後的圖像,經常使用的圖像處理方法有圖像加強、復原、編碼、壓縮、圖像分類(識別)、圖像變換等。
  圖像處理技術在娛樂中的應用主要包括:電影特效製做、電腦電子遊戲、數碼相機、視頻播放、數字電視等。
  Android對於圖片的處理,最常使用到的數據結構是位圖——Bitmap,它包含了一張圖片全部的數據。整個圖片都是由點陣和顏色值組成的,所謂點陣就是一個包含像素的矩陣,每個元素對應着圖片的一個像素。而顏色值—ARGB,分別對應着透明度、紅、綠、藍這四個通道份量,他們共同決定了每一個像素點顯示的顏色。上圖顯示的就是色光三原色。

-- 像素處理getPixel getPixels setPixel setPixels
Android Bitmap 加載與像素操做- https://blog.csdn.net/jia20003/article/details/46723903
Android圖像處理整理- http://blog.csdn.net/luzhenyuxfcy/article/details/49427781

-- 開源圖像庫Skia: Skia 是完整的2D圖像庫,Google 一個底層的圖形、圖像、動畫、 SVG 、文本/RGB(8byte – 32byte)編碼(jpeg, png) 和解碼功能等多方面的圖形庫,是 android 中圖形系統的引擎。
Android圖片解碼流程:
 1) APP:BitmapDecode.Java
 2) API:BitmapFactory.java(static image)、Movie.java(dynamic image)
 3) JNI:BitmapFactory.cpp(static image)、Movie.cpp(dynamic image)
 4) C Native Service(Skia):SkImageDecoder.cpp(static image)、SkMovie.cpp(dynamic image)
  skia 源碼解析 http://www.eoeandroid.com/thread-27841-1-1.html .libskia
  使用系統自帶libjpeg時問題 http://stackoverflow.com/questions/5208817/failing-to-link-against-libjpeg-so-in-jni-ndk-shared-library .libjpeg是個跨平臺的開源庫.

Skia主要使用的第三方庫:Zlib、Jpeglib、Pnglib、giflib、fpdfemb(處理pdf文檔);
Skia編譯及調用 Android? Skia調用OpenGL或OpenGL ES?

--圖片繪製,PorterDuffXfermode,這是CoorChice-https://github.com/chenBingX/CoorChiceLibOne/blob/448cf36e0b33fb667cb4fd5a8d8db2651bf0647e/app/src/main/java/com/chenbing/coorchicelibone/Views/PorterDuffXDemoActivity.java

  YUV是被歐洲電視系統索採用的一種顏色編碼方法。採用YUV色彩空間的重要性是它的亮度信號Y和色度信號U、V是分離的。若是隻有Y信號份量而沒有U、V份量,那麼這樣表示的圖像就是黑白灰度圖像,彩色電視採用YUV空間正式爲了用亮度信號Y解決彩色電視機與黑白電視機的兼容問題,使黑白電視機也能接收彩色電視信號。
  YUV主要用於優化彩色視頻信號的傳輸,使其向後相容老式黑白電視。與RGB視頻信號傳輸相比,它最大的優勢在於只需佔用極少的頻寬。

-- 貼圖
android ndk調用OpenGL 實現紋理貼圖Texture- http://blog.csdn.net/chrisfxs/article/details/34359265
android ndk調用OpenGL 實現紋理貼圖Texture- http://download.csdn.NET/detail/chrisfxs/7547637

-- 圖片分片,拼圖遊戲能夠用到
【Android圖像處理】將一張圖片切成許多碎片- http://blog.csdn.net/qq_32353771/article/details/53215322
[Android] Android中將一個圖片切割成多個圖片- http://blog.csdn.net/arui319/article/details/7470193

-- android拼接多張bitmap圖片- http://blog.csdn.net/ajun495175289/article/details/18091683
/**
* 橫向拼接
* <功能詳細描述>
* @param first
* @param second
* @return 
*/
private Bitmap add2Bitmap(Bitmap first, Bitmap second) {
  int width = first.getWidth() + second.getWidth();
  int height = Math.max(first.getHeight(), second.getHeight());
  Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888);
  Canvas canvas = new Canvas(result);
  canvas.drawBitmap(first, 0, 0, null);
  canvas.drawBitmap(second, first.getWidth(), 0, null);
  return result;
}

/**
* 縱向拼接
* <功能詳細描述>
* @param first
* @param second
* @return 
*/
private Bitmap addBitmap(Bitmap first, Bitmap second) {
  int width = Math.max(first.getWidth(),second.getWidth());
  int height = first.getHeight() + second.getHeight();
  Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888);
  Canvas canvas = new Canvas(result);
  canvas.drawBitmap(first, 0, 0, null);
  canvas.drawBitmap(second, first.getHeight(), 0, null);
  return result;
}

-- 圖片倒影,其原理基本上就是將原圖倒置,畫在畫布上,而後加上一個半透明的蒙版 public static Bitmap createReflectedImage(Bitmap originalImage)  {           int width = originalImage.getWidth();           int height = originalImage.getHeight();           Matrix matrix = new Matrix();           // 實現圖片翻轉90度           matrix.preScale(1, -1);           // 建立倒影圖片(是原始圖片的一半大小)           Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false);           // 建立總圖片(原圖片 + 倒影圖片)           Bitmap finalReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888);           // 建立畫布           Canvas canvas = new Canvas(finalReflection);           canvas.drawBitmap(originalImage, 0, 0, null);           //把倒影圖片畫到畫布上           canvas.drawBitmap(reflectionImage, 0, height + 1, null);           Paint shaderPaint = new Paint();           //建立線性漸變LinearGradient對象           LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, finalReflection.getHeight() + 1, 0x70ffffff,                   0x00ffffff, TileMode.MIRROR);           shaderPaint.setShader(shader);           shaderPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));           //畫布畫出反轉圖片大小區域,而後把漸變效果加到其中,就出現了圖片的倒影效果。           canvas.drawRect(0, height + 1, width, finalReflection.getHeight(), shaderPaint);           return finalReflection;    }    -- 圖片陰影,在一個圓角矩形的圖片四周加上陰影效果,在原圖四邊加上矩形的陰影,而後在四個圓角的地方畫扇形陰影來實現。 Android圖片添加陰影效果的兩種方式- http://blog.csdn.net/u011421608/article/details/51923812 public static Bitmap createShadowBitmap(Bitmap orignalBitmap,               int shadowMargin, int iconCornerRadius) {           int w = orignalBitmap.getWidth();           int h = orignalBitmap.getHeight();           Bitmap shadowBitmap = Bitmap.createBitmap(w + shadowMargin * 2, h                   + shadowMargin * 2, Config.ARGB_8888);           int width = shadowBitmap.getWidth();           int height = shadowBitmap.getHeight();           Canvas canvas = new Canvas(shadowBitmap);           canvas.drawBitmap(orignalBitmap, shadowMargin, shadowMargin, null);           Paint paint = new Paint();           paint.setXfermode(new PorterDuffXfermode(Mode.DST_OVER));           int radius = shadowMargin + iconCornerRadius;           // 四個邊的陰影效果,採用線性陰影,寬度等於陰影邊距+圓角半徑           LinearGradient leftGradient = new LinearGradient(radius, 0, 0, 0,                   0x7F000000, 0x00000000, TileMode.CLAMP);           LinearGradient rightGradient = new LinearGradient(width - radius, 0,                   width, 0, 0x7F000000, 0x00000000, TileMode.CLAMP);           LinearGradient topGradient = new LinearGradient(0, radius, 0, 0,                   0x7F000000, 0x00000000, TileMode.CLAMP);           LinearGradient bottomGradient = new LinearGradient(0, height - radius,                   0, height, 0x7F000000, 0x00000000, TileMode.CLAMP);           paint.setShader(leftGradient);           canvas.drawRect(0, radius, radius, height - radius, paint);           paint.setShader(rightGradient);           canvas.drawRect(width - radius, radius, width, height - radius, paint);           paint.setShader(topGradient);           canvas.drawRect(radius, 0, width - radius, radius, paint);           paint.setShader(bottomGradient);           canvas.drawRect(radius, height - radius, width - radius, height, paint);           // 四個角的陰影效果,採用圓形陰影,半徑等於陰影邊距+圓角半徑           RadialGradient topLeftCornerGradient = new RadialGradient(radius,                   radius, radius, 0x7F000000, 0x00000000, TileMode.CLAMP);           RadialGradient topRightCornerGradient = new RadialGradient(width                   - radius, radius, radius, 0x7F000000, 0x00000000,                   TileMode.CLAMP);           RadialGradient bottomLeftCornerGradient = new RadialGradient(radius,                   height - radius, radius, 0x7F000000, 0x00000000, TileMode.CLAMP);           RadialGradient bottomRightCornerGradient = new RadialGradient(width                   - radius, height - radius, radius, 0x7F000000, 0x00000000,                   TileMode.CLAMP);           // 畫四個角,就是畫四個圓心角爲90度的扇形,drawArc函數第一個參數爲圓弧所在圓的的外接矩形,第二個參數爲起始角度,第三個參數爲扇形順時針滑過的角度,第四個參數若是爲true時,在繪製圓弧時將圓心包括在內(用來畫扇形),第五個參數爲畫筆           paint.setShader(topLeftCornerGradient);           canvas.drawArc(new RectF(0, 0, radius * 2, radius * 2), 180, 90, true,                   paint);           paint.setShader(topRightCornerGradient);           canvas.drawArc(new RectF(width - radius * 2, 0, width, radius * 2),                   270, 90, true, paint);           paint.setShader(bottomLeftCornerGradient);           canvas.drawArc(new RectF(0, height - radius * 2, radius * 2, height),                   90, 90, true, paint);           paint.setShader(bottomRightCornerGradient);           canvas.drawArc(new RectF(width - radius * 2, height - radius * 2,                   width, height), 0, 90, true, paint);           return shadowBitmap;   }

相關文章
相關標籤/搜索