網(wǎng)站首頁 編程語言 正文
背景
工作中遇到業(yè)務(wù)訴求是通過OpenCV對圖片進行一些判斷操作和優(yōu)化,這里是看了部分不錯的文章,希望總結(jié)一個自己的學(xué)習(xí)過程,溫故而知新,有不對的地方可以評論區(qū)指出,小白學(xué)習(xí)海涵。
基礎(chǔ)知識
Mat在OpenCV中是非常重要的存在,后續(xù)各個API都是在Mat的基礎(chǔ)上去做文章,Mat 是Matrix(矩陣)的縮寫
...
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中其實保存著關(guān)于圖片的圖像信息,包括像素、寬、高、類型大小深度等屬性。
主要Api - 加載圖片
由于我這里使用的集團的二方庫,讀者大佬可以直接在github搜索 OpenCV對應(yīng)版本,在gradle中添加依賴即可,由于本人是使用的Java代碼通過jni調(diào)用底層C++代碼,大部分api其實是互通的(網(wǎng)上Python教程居多,這也是我想把這個過程總結(jié)下來的原因)
imread
該方法主要是獲取圖片的Mat信息的 默認通道為BGR(Blue, Green, Red),可以有很多flags供我們選擇以此達到不同的效果。
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; // 無改動
public static final int IMREAD_GRAYSCALE = 0; // 單通道灰色
public static final int IMREAD_COLOR = 1; //三通道BGR圖像
Utils.bitmapToMat
通過Utils.bitmapToMat方法獲取Mat對象。
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.icon);
Mat mat = Mat()
// bitmap : 支持ARGB_8888和RGB_565兩種格式
// mat : 類型為CV_8UC4,通道順序為RGBA
Utils.bitmapToMat(bitmap, mat);
主要API - 寫入圖片
?? 我們可以通過 imwrite方法將Mat對象保存至指定文件
File file = new File(Environment.getExternalStorageDirectory().getPath() + File.separator + "${System.currentTimeMillis()}.jpg");
if (!file.exists()) {
file.createNewFile();
}
// 文件路徑 , 待輸出mat對象
Imgcodecs.imwrite(file.getPath(), srcMat);
端側(cè)常用分析方法
亮度檢測
計算圖片在灰度圖上的均值和方差,當(dāng)存在亮度異常時,均值會偏離均值點(可以取0-255中間值 128),方差也會偏小;通過計算灰度圖的均值和方差,就可評估圖像是否存在過曝光或曝光不足。
//亮度檢測
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++) {
//在計算過程中,考慮128為亮度均值點
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", "過亮");
} else {
Log.e("ymc", "過暗");
}
} else {
Log.e("ymc", "亮度:正常");
}
return cast;
}
清晰度檢測
利用拉普拉斯算子計算圖片的二階導(dǎo)數(shù),反映圖片的邊緣信息,同樣事物的圖片,清晰度高的,相對應(yīng)的經(jīng)過拉普拉斯算子濾波后的圖片的方差也就越大。
//清晰度
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年接觸了很多新東西,在工作中也看到了很多大佬的閃光點,后續(xù)還會有更深入的OpenCV使用案例博文,圖片分析方面還是菜鳥,這篇文章也看了很多Python大佬的文章,正所謂三人行必有我?guī)煟^續(xù)學(xué)習(xí)。
原文鏈接:https://juejin.cn/post/7189818918033162277
相關(guān)推薦
- 2022-05-13 html頁面 加載完成后再刷新 一次
- 2022-10-31 Go語言面試題之select和channel的用法_Golang
- 2022-04-22 Error:Module “./antd/es/badge/style“ does not exis
- 2022-09-29 ASP.NET?MVC實現(xiàn)多選下拉框保存并顯示_實用技巧
- 2022-06-06 詳解如何自定義Dubbo Filter(含dubbo2.7.X及以上版本和2.6.X及以下版本兩種寫
- 2023-11-13 matplotlib圖例(legend)如何自由設(shè)置其位置、大小以及樣式
- 2022-03-14 寶塔中nginx配置websocket的wss協(xié)議
- 2023-12-07 redis key
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支