基于OpenCV对图片清晰度、色偏和亮度的检测(java版)

本文链接:https://blog.csdn.net/qq_34997906/article/details/87970817

由来:近期项目需要检测图片的亮度和色偏,但网上大多为用C实现的,没有java版本的,此篇为java版本对opencv的调用,谨以此献给CSDN的广大用户。

一. 导入OpenCV所需依赖

依赖下载:OpenCV运行环境下载(包含jar包和dll依赖库)

  1. 在IDEA的项目模块下新建一个libs目录,将opencv-343.jar放进去,将opencv_java343.dll放到项目下。
    如图:

    注意:opencv_java343.dll文件很多时候会加载不了,放在系统的path路径下也是可以的,jdk目录以及windows32目录下都是可行的,如果有强迫症的话就放在项目下吧。

  2. pom 文件依赖引入

<dependency><groupId>org.opencv</groupId><artifactId>opencv</artifactId><version>0.0.1</version><scope>system</scope><systemPath>${project.basedir}/libs/opencv-343.jar</systemPath>
</dependency>

二. 项目代码

1. 色偏检测

原理说明: 网上常用的一种方法是将RGB图像转变到CIE Lab空间,其中L表示图像亮度,a表示图像红/绿分量,b表示图像黄/蓝分量。通常存在色偏的图像,在a和b分量上的均值会偏离原点很远,方差也会偏小;通过计算图像在a和b分量上的均值和方差,就可评估图像是否存在色偏。计算CIE Lab*空间是一个比较繁琐的过程,好在OpenCV提供了现成的函数,因此整个过程也不复杂。

/*** opencv 检测图片色偏* jpegFile:待检测的图片* calcCast 计算并返回一幅图像的色偏度以及,色偏方向* cast 计算出的偏差值,小于1表示比较正常,大于1表示存在色偏* da 红/绿色偏估计值,da大于0,表示偏红;da小于0表示偏绿* db 黄/蓝色偏估计值,db大于0,表示偏黄;db小于0表示偏蓝*/import org.opencv.core.Core;import org.opencv.core.Mat;import org.opencv.imgcodecs.Imgcodecs;import org.opencv.imgproc.Imgproc;public static Boolean colorException(File jpegFile) {Mat srcImage = Imgcodecs.imread(jpegFile.getAbsolutePath());Mat dstImage = new Mat();//  将RGB图像转变到CIE L*a*b*Imgproc.cvtColor(srcImage, dstImage, Imgproc.COLOR_BGR2Lab);float a=0,b=0;int HistA[] = new int[256],HistB[] = new int[256];for(int i=0;i<256;i++){HistA[i]=0;HistB[i]=0;}int size= (int)dstImage.total() * dstImage.channels();for(int i=0;i < dstImage.rows(); i++){for(int j=0;j< dstImage.cols(); j++){//在计算过程中,要考虑将CIEL*a*b*空间还原后同a+=(float)(dstImage.get(i,j)[1]-128);b+=(float)(dstImage.get(i,j)[2]-128);
//                int x=Math.abs(dstImage.ptr(i,j).get(1));
//                int y=Math.abs(dstImage.ptr(i,j).get(2));int x=(int)dstImage.get(i,j)[1];int y=(int)dstImage.get(i,j)[2];HistA[x]++;HistB[y]++;}}float  da=a/(float)(dstImage.rows() * dstImage.cols());float db=b/(float)(dstImage.rows() * dstImage.cols());float D= (float)Math.sqrt(da*da+db*db);float Ma=0,Mb=0;for(int i=0;i<256;i++){//计算范围-128~127Ma+=Math.abs(i-128-da)*HistA[i];Mb+=Math.abs(i-128-db)*HistB[i];}Ma/=(float)(dstImage.rows() * dstImage.cols());Mb/=(float)(dstImage.rows() * dstImage.cols());float M=(float)Math.sqrt(Ma*Ma+Mb*Mb);float K=D/M;float cast =K;System.out.printf("色偏指数: %f\n",cast);if(cast>1.1) {System.out.printf("存在色偏\n");return true;}else {System.out.printf("不存在色偏\n");return false;}}

2. 亮度检测

原理说明:计算图片在灰度图上的均值和方差,当存在亮度异常时,均值会偏离均值点(可以假设为128),方差也会偏小;通过计算灰度图的均值和方差,就可评估图像是否存在过曝光或曝光不足。

/*** opencv 检测图片亮度* brightnessException 计算并返回一幅图像的色偏度以及,色偏方向* cast 计算出的偏差值,小于1表示比较正常,大于1表示存在亮度异常;当cast异常时,da大于0表示过亮,da小于0表示过暗* 返回值通过cast、da两个引用返回,无显式返回值*/import org.opencv.core.Core;import org.opencv.core.Mat;import org.opencv.imgcodecs.Imgcodecs;import org.opencv.imgproc.Imgproc;public static Integer brightnessException ( File jpegFile) {Mat srcImage = Imgcodecs.imread(jpegFile.getAbsolutePath());Mat dstImage = new Mat();// 将RGB图转为灰度图Imgproc.cvtColor(srcImage,dstImage, Imgproc.COLOR_BGR2GRAY);float a=0;int Hist[] = new int[256];for(int i=0;i<256;i++) {Hist[i] = 0;}for(int i=0;i<dstImage.rows();i++){for(int j=0;j<dstImage.cols();j++){//在计算过程中,考虑128为亮度均值点a+=(float)(dstImage.get(i,j)[0]-128);int x=(int)dstImage.get(i,j)[0];Hist[x]++;}}float da =  a/(float)(dstImage.rows()*dstImage.cols());System.out.println(da);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)((dstImage.rows()*dstImage.cols()));float M=Math.abs(Ma);float K=D/M;float cast = K;System.out.printf("亮度指数: %f\n",cast);if(cast>=1) {System.out.printf("亮度:"+da);if(da > 0) {System.out.printf("过亮\n");return 2;} else {System.out.printf("过暗\n");return 1;}} else {System.out.printf("亮度:正常\n");return 0;}}

3. 图片颜色检测

 /*** opencv 检测图片颜色*/public static void imageColor ( File jpegFile) {Mat srcImage = Imgcodecs.imread(jpegFile.getAbsolutePath());Mat dstImage = new Mat();Imgproc.cvtColor(srcImage,dstImage, Imgproc.COLOR_BGR2HSV);int i = 0 ,j = 0;loop:for( i=0;i<dstImage.rows();i++) {for(j=0;j<dstImage.cols();j++) {//在计算过程中,考虑128为亮度均值点double[] colorVec = dstImage.get(i,j);int x=(int)dstImage.get(i,j)[0];if((colorVec[0]>=0&&colorVec[0]<=180)&&(colorVec[1]>=0&&colorVec[1]<=255)&&(colorVec[2]>=0&&colorVec[2]<=46)) {continue;}else  if((colorVec[0]>=0&&colorVec[0]<=180)&&(colorVec[1]>=0&&colorVec[1]<=43)&&(colorVec[2]>=46&&colorVec[2]<=220)){continue;}else  if((colorVec[0]>=0&&colorVec[0]<=180)&&(colorVec[1]>=0&&colorVec[1]<=30)&&(colorVec[2]>=221&&colorVec[2]<=255)){continue;}else {System.out.println("彩色图像");break loop;}}}if(i==dstImage.rows() && j==dstImage.cols()) {System.out.println("黑白图像");}}

4. 清晰度检测
网上用opencv检测的各个版本均为c++/c#写的,二者的库依赖和方法变量名都存在较大的差异,转换太过麻烦,此处提供一个javacv的写法,以解部分老哥的燃眉之急。
4.1 javacv依赖引入(依赖jar包较大)

<dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.4.3</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_imgcodecs;
import org.bytedeco.javacpp.opencv_imgproc;/*** javacv 检测图片清晰度* 标准差越大说明图像质量越好*/public static void clarityException(File jpegFile){String path = "E:\\test\\";opencv_core.Mat srcImage = opencv_imgcodecs.imread(jpegFile.getAbsolutePath());opencv_core.Mat dstImage = new opencv_core.Mat();//转化为灰度图opencv_imgproc.cvtColor(srcImage, dstImage, opencv_imgproc.COLOR_BGR2GRAY);//在gray目录下生成灰度图片opencv_imgcodecs.imwrite(path+"gray-"+jpegFile.getName(), dstImage);opencv_core.Mat laplacianDstImage = new opencv_core.Mat();//阈值太低会导致正常图片被误断为模糊图片,阈值太高会导致模糊图片被误判为正常图片opencv_imgproc.Laplacian(dstImage, laplacianDstImage, opencv_core.CV_64F);//在laplacian目录下升成经过拉普拉斯掩模做卷积运算的图片opencv_imgcodecs.imwrite(path+"laplacian-"+jpegFile.getName(), laplacianDstImage);//矩阵标准差opencv_core.Mat stddev = new opencv_core.Mat();//求矩阵的均值与标准差opencv_core.meanStdDev(laplacianDstImage, new opencv_core.Mat(), stddev);// ((全部元素的平方)的和)的平方根// double norm = Core.norm(laplacianDstImage);// System.out.println("\n矩阵的均值:\n" + mean.dump());System.out.println(jpegFile.getName() + "矩阵的标准差:\n" + stddev.createIndexer().getDouble());// System.out.println(jpegFile.getName()+"平方根:\n" + norm);}

最后的叮嘱:项目部署到服务器时,一定注意将opencv_java343.dll放在系统的path路径下,或者Tomcat的bin目录下。

java OpenCV 图片清晰度、色偏和亮度检测相关推荐

  1. java opencv 图片放大缩小,角点检测和边缘检测(14)

    什么是高斯金字塔 所谓的高斯金字塔是利用算法将图片放大,如下面的图形: openCv对应的函数: src输入图像 dst 目标图像 dstsize 放大尺寸 borderType 边框类型 实例: S ...

  2. Java+OpenCV图片对比

    近期老板让研究一下航拍.遥感影像对比功能,个人认为可行性并不高,没有知识储备,而且真要做好的话得当作产品去砸钱(老板:砸钱是不可能的,这辈子都不可能砸钱). 经过查询相关资料,OpenCV对图像的处理 ...

  3. java opencv 图片处理_Java图像处理:基于OpenCV与JVM

    Java图像处理:基于OpenCV与JVM 作者:(法)尼古拉斯·莫德奇克(Nicolas Modrzyk) 著 出版日期:2019年04月 文件大小:7.64M 支持设备: ¥60.00仅供试读 适 ...

  4. java Opencv 图片修复 Photo

    OpenCV 如何进行图片修复 修复函数: Photo.inpaint(imageSrc, imageMask, imageDst, radius, Photo.INPAINT_TELEA); ima ...

  5. 基于OpenCV对图片清晰度、色偏和亮度的检测(java版)

    由来:近期项目需要检测图片的亮度和色偏,但网上大多为用C实现的,没有java版本的,此篇为java版本对opencv的调用,谨以此献给CSDN的广大用户. 一. 导入OpenCV所需依赖 依赖下载:O ...

  6. 视频清晰度、色偏以及亮度异常检测

    原文链接:http://blog.csdn.net/kklots/article/details/12720359 昨天老板临时交代一个活,要求通过算法检测监控设备是否存在失焦.偏色.亮度异常等问题. ...

  7. java OpenCV实现扫描仪图片倾斜矫正

    首先先去opencv官网下载资源 官网地址:Releases - OpenCV 官网下载慢可以选择在百度网盘下载,版本是455 链接:https://pan.baidu.com/s/1LADtih8l ...

  8. 图像质量判断:模糊/色偏/亮度检测综合

    以下先列出图像质量判断3项的原理公式说明,并给出代码博客链接. 1.原理 https://blog.csdn.net/weixin_41770169/article/details/82349687  ...

  9. java 对比度,java批改图片亮度对比度

    java修改图片亮度对比度 我参考了这个博客 http://blog.csdn.net/jia20003/article/details/7385160 以下是我根据这个编的代码 public sta ...

最新文章

  1. 搭建zookeeper+kafka集群
  2. CDT源代码框架分析改造 线程对象的改造 添加标签 区分断点跟跟踪点
  3. java当数值超过byte时_java试题及答案
  4. 为什么卫星天线长得像口大锅?
  5. 前端学习(3192):react第一个案例
  6. IAR下μCosIII移植心得
  7. 使用Webpack的代码分离实现Vue懒加载(译文)
  8. 1.4_select_sort_选择排序
  9. UNet以ResNet34为backbone in keras
  10. No ip domain-lookup和Logging synchronous和Exec-timeout 0 0
  11. 关于MD5的那点事,你都了解清楚了吗?
  12. 木讷的程序员需要知道的事情 (四)
  13. 《代码大全》读书笔记
  14. java代码是干嘛的_程序员究竟是干嘛的呢?
  15. Python笔记五(写excel,加密模块,字典排序,常用的标准模块,操作mysql,时间模块)...
  16. 无线充电宝CE认证和FCC认证怎么办理?无线充移动电源UL报告
  17. 利用燕尾花数据集画出P-R曲线
  18. C语言(C++)打开有规律名称的多个文件,并写入数据
  19. 【分隔结构】动宾分离
  20. Html5---div布局方式

热门文章

  1. insight-vmi 编译中的问题
  2. 判断鼠标不在控件上_基础设施:一套基本控件
  3. eplan文本怎么换行_JDK 14的新特性:文本块Text Blocks
  4. Design Pattern - Interpreter(C#)
  5. STL list源码解析
  6. android 测试工具,Android开源项目第四篇:开发及测试工具篇
  7. realme怎么互传_realme真我X7 Pro首发体验:非常轻快,颜值不赖
  8. java数组 相同颜色距离最远的_java-数组列表并找到具有相同编号的最长子...
  9. 利用计算机模拟人脑进行演绎,2014年4月自学考试计算机应用技术试题
  10. 标注工具_语料标注工具(2)