开发者

Android OpenCV基础API清晰度亮度识别检测

开发者 https://www.devze.com 2023-01-19 10:21 出处:网络 作者: 小肥羊冲冲冲Android
目录背景基础知识主要Api - 加载图片imreadUtils.bitmapToMat主要API - 写入图片端侧常用分析方法亮度检测清晰度检测最后背景
目录
  • 背景
  • 基础知识
  • 主要Api - 加载图片
    • imread
    • Utils.bitmapToMat
  • 主要API - 写入图片
    • 端侧常用分析方法
      • 亮度检测
      • 清晰度检测
    • 最后

      背景

      工作中遇到业务诉求是通过OpenCV对图片进行一些判断操作和优化,这里是看了部分不错的文章,希望总结一个自己的学习过程,温故而知新,有不对的地方可以评论区指出,小白学习海涵。

      基础知识

      Mat在OpenCV中是非常重要的存在,后续各个API都是在Mat的基础上去做文章,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中其实保存着关于图片的图像信息,包括像素、宽、高、类型大小深度等属性。

      主要Api - 加载图片

      由于我这里使用的集团的二方库,读者大佬可以直接在github搜索 OpenCV对应版本,在gradle中添加依赖即可,由于本人是使用的Java代码通过jni调用底层C++代码,大部分api其实是互通的(网上python教程居多,这也是我想把这个过程总结下来的原因)

      imread

      该方法主要是获取图片的Mat信息的 默认通道为BGR(Blue, Green, Red),可以有很多flags供我们选择以此达到不同的效果。

      public static Mat imread(String filename, int flags) {
             return new Mat(imread_0(filename, flags));
      }
      // 调用例子
      eg:
      Mat bgr = Imgcodecs.imread(filePath, Imgcodecs.IMREAD_UNCHANGED);
      Imgproc.cvtColor(bgr, srcMat, Imgproc.COLOR_BGR2RGB);
      //Imgcodecs flags 常用参数含义
      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);
      

      端侧常用分析方法

      亮度检测

      计算图片在灰度图上的均值和方差,当存在亮度异常时,均值会偏离均值点(可以取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 = http://www.devze.com0; 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;
         js     float cast = K;
              if (cast >= 1) {
                  if (da > 0) {
                      Log.e("ymc", "过亮");
                  } else {
                      Log.e("ymc", "过暗");
       开发者_Go入门   www.devze.com        }
              } else {
                  Log.e("ymc", "亮度:正常");
              }
              return cas编程客栈t;
          }
      

      清晰度检测

      利用拉普拉斯算子计算图片的二阶导数,反映图片的边缘信息,同样事物的图片,清晰度高的,相对应的经过拉普拉斯算子滤波后的图片的方差也就越大。

      //清晰度
      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);
              //后续可根据业务设置阈值
              Log.e("ymc", "清晰度:" + clarity);
              laplacianDstImage.release();
              return clarity;
          }
      

      最后http://www.devze.com

      2022年接触了很多新东西,在工作中也看到了很多大佬的闪光点,后续还会有更深入的OpenCV使用案例博文,图片分析方面还是菜鸟,这篇文章也看了很多Python大佬的文章,正所谓三人行必有我师,继续学习。

      以上就是android OpenCV基础API清晰度亮度识别检测的详细内容,更多关于Android OpenCV API清晰亮度的资料请关注我们其它相关文章!

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号