Android?OpenCV基礎(chǔ)API清晰度亮度識(shí)別檢測(cè)
背景
工作中遇到業(yè)務(wù)訴求是通過(guò)OpenCV對(duì)圖片進(jìn)行一些判斷操作和優(yōu)化,這里是看了部分不錯(cuò)的文章,希望總結(jié)一個(gè)自己的學(xué)習(xí)過(guò)程,溫故而知新,有不對(duì)的地方可以評(píng)論區(qū)指出,小白學(xué)習(xí)海涵。
基礎(chǔ)知識(shí)
Mat在OpenCV中是非常重要的存在,后續(xù)各個(gè)API都是在Mat的基礎(chǔ)上去做文章,Mat 是Matrix(矩陣)的縮寫(xiě)
... inline Mat::Mat(int _rows, int _cols, int _type) : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) { create(_rows, _cols, _type); } inline void Mat::create(int _rows, int _cols, int _type) { _type &= TYPE_MASK; if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data ) return; int sz[] = {_rows, _cols}; create(2, sz, _type); } ...
Mat中其實(shí)保存著關(guān)于圖片的圖像信息,包括像素、寬、高、類(lèi)型大小深度等屬性。
主要Api - 加載圖片
由于我這里使用的集團(tuán)的二方庫(kù),讀者大佬可以直接在github搜索 OpenCV對(duì)應(yīng)版本,在gradle中添加依賴(lài)即可,由于本人是使用的Java代碼通過(guò)jni調(diào)用底層C++代碼,大部分api其實(shí)是互通的(網(wǎng)上Python教程居多,這也是我想把這個(gè)過(guò)程總結(jié)下來(lái)的原因)
imread
該方法主要是獲取圖片的Mat信息的 默認(rèn)通道為BGR(Blue, Green, Red),可以有很多flags供我們選擇以此達(dá)到不同的效果。
public static Mat imread(String filename, int flags) { return new Mat(imread_0(filename, flags)); } // 調(diào)用例子 eg: Mat bgr = Imgcodecs.imread(filePath, Imgcodecs.IMREAD_UNCHANGED); Imgproc.cvtColor(bgr, srcMat, Imgproc.COLOR_BGR2RGB); //Imgcodecs flags 常用參數(shù)含義 public static final int IMREAD_UNCHANGED = -1; // 無(wú)改動(dòng) public static final int IMREAD_GRAYSCALE = 0; // 單通道灰色 public static final int IMREAD_COLOR = 1; //三通道BGR圖像
Utils.bitmapToMat
通過(guò)Utils.bitmapToMat方法獲取Mat對(duì)象。
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.icon); Mat mat = Mat() // bitmap : 支持ARGB_8888和RGB_565兩種格式 // mat : 類(lèi)型為CV_8UC4,通道順序?yàn)镽GBA Utils.bitmapToMat(bitmap, mat);
主要API - 寫(xiě)入圖片
我們可以通過(guò) imwrite方法將Mat對(duì)象保存至指定文件
File file = new File(Environment.getExternalStorageDirectory().getPath() + File.separator + "${System.currentTimeMillis()}.jpg"); if (!file.exists()) { file.createNewFile(); } // 文件路徑 , 待輸出mat對(duì)象 Imgcodecs.imwrite(file.getPath(), srcMat);
端側(cè)常用分析方法
亮度檢測(cè)
計(jì)算圖片在灰度圖上的均值和方差,當(dāng)存在亮度異常時(shí),均值會(huì)偏離均值點(diǎn)(可以取0-255中間值 128),方差也會(huì)偏??;通過(guò)計(jì)算灰度圖的均值和方差,就可評(píng)估圖像是否存在過(guò)曝光或曝光不足。
//亮度檢測(cè) private static float brightness(Mat grayImage) { float a = 0; int Hist[] = new int[256]; for (int i = 0; i < 256; i++) { Hist[i] = 0; } for (int i = 0; i < grayImage.rows(); i++) { for (int j = 0; j < grayImage.cols(); j++) { //在計(jì)算過(guò)程中,考慮128為亮度均值點(diǎn) a += (float) (grayImage.get(i, j)[0] - 128); int x = (int) grayImage.get(i, j)[0]; Hist[x]++; } } float da = a / (float) (grayImage.rows() * grayImage.cols()); float D = Math.abs(da); float Ma = 0; for (int i = 0; i < 256; i++) { Ma += Math.abs(i - 128 - da) * Hist[i]; } Ma /= (float) ((grayImage.rows() * grayImage.cols())); float M = Math.abs(Ma); float K = D / M; float cast = K; if (cast >= 1) { if (da > 0) { Log.e("ymc", "過(guò)亮"); } else { Log.e("ymc", "過(guò)暗"); } } else { Log.e("ymc", "亮度:正常"); } return cast; }
清晰度檢測(cè)
利用拉普拉斯算子計(jì)算圖片的二階導(dǎo)數(shù),反映圖片的邊緣信息,同樣事物的圖片,清晰度高的,相對(duì)應(yīng)的經(jīng)過(guò)拉普拉斯算子濾波后的圖片的方差也就越大。
//清晰度 private static double clarity(Mat grayImage) { Mat laplacianDstImage = new Mat(); Imgproc.Laplacian(grayImage, laplacianDstImage, CvType.CV_64F); MatOfDouble median = new MatOfDouble(); MatOfDouble std = new MatOfDouble(); Core.meanStdDev(laplacianDstImage, median, std); double clarity = Math.pow(std.get(0, 0)[0], 2); //后續(xù)可根據(jù)業(yè)務(wù)設(shè)置閾值 Log.e("ymc", "清晰度:" + clarity); laplacianDstImage.release(); return clarity; }
最后
2022年接觸了很多新東西,在工作中也看到了很多大佬的閃光點(diǎn),后續(xù)還會(huì)有更深入的OpenCV使用案例博文,圖片分析方面還是菜鳥(niǎo),這篇文章也看了很多Python大佬的文章,正所謂三人行必有我?guī)?,繼續(xù)學(xué)習(xí)。
以上就是Android OpenCV基礎(chǔ)API清晰度亮度識(shí)別檢測(cè)的詳細(xì)內(nèi)容,更多關(guān)于Android OpenCV API清晰亮度的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android實(shí)現(xiàn)簡(jiǎn)單的照相功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)單的照相功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Android編程之交互對(duì)話(huà)框?qū)嵗郎\析
這篇文章主要介紹了Android編程之交互對(duì)話(huà)框,結(jié)合實(shí)例形式簡(jiǎn)單分析了Android交互對(duì)話(huà)框AlertDialog的功能、簡(jiǎn)單用法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-03-03Android編程基礎(chǔ)之簡(jiǎn)單Button事件響應(yīng)綜合提示控件Toast應(yīng)用示例
這篇文章主要介紹了Android編程基礎(chǔ)之簡(jiǎn)單Button事件響應(yīng)綜合提示控件Toast應(yīng)用,結(jié)合實(shí)例形式分析了Button事件響應(yīng)與Toast提醒的相關(guān)操作技巧,需要的朋友可以參考下2016-10-10Android實(shí)現(xiàn)短信驗(yàn)證碼自動(dòng)攔截讀取功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)短信驗(yàn)證碼自動(dòng)攔截讀取功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08Android彈出DatePickerDialog并獲取值的方法
這篇文章主要為大家詳細(xì)介紹了Android彈出DatePickerDialog并獲取值的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05Android自定義View實(shí)現(xiàn)QQ消息氣泡
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)QQ消息氣泡,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08Android自定義有限制區(qū)域的圖例角度自識(shí)別涂鴉工具類(lèi)完結(jié)篇
這篇文章主要為大家介紹了Android自定義有限制區(qū)域的圖例角度自識(shí)別涂鴉工具類(lèi)完結(jié)篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Android開(kāi)發(fā)之底圖局部加載移動(dòng)的方法示例
這篇文章主要介紹了Android開(kāi)發(fā)之底圖局部加載移動(dòng)的方法,涉及Android針對(duì)圖片與屏幕屬性的讀取、計(jì)算、設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下2017-08-08AndroidStudio 3.6 中 R.layout 找不到對(duì)應(yīng)的xml文件問(wèn)題及解決方法
這篇文章主要介紹了AndroidStudio 3.6 中 R.layout 找不到對(duì)應(yīng)的xml文件問(wèn)題,本文給出了解決方法對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03解析Android截取手機(jī)屏幕兩種實(shí)現(xiàn)方案
這篇文章主要介紹了解析Android截取手機(jī)屏幕兩種實(shí)現(xiàn)方案,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04