美文网首页
opencv两张图片找不同

opencv两张图片找不同

作者: 牙叔教程 | 来源:发表于2021-06-07 22:40 被阅读0次

    牙叔教程 简单易学

    使用场景

    两张图片找不同, 大家来找茬之类的

    效果展示

    效果小图.png

    autojs版本

    8.8.7-0

    get知识点

    1. 灰度
    2. 图片做减法
    3. 高斯滤波
    4. 闭运算( 先膨胀, 再腐蚀 )
    5. 查找轮廓
    6. 查找最小外接矩形
    7. 计算矩形中心
    8. 计算轮廓面积
    9. 遍历轮廓点位
    10. 画轮廓
    11. 构造Size
    12. 构造Scalar
    13. MatOfPoint转MatOfPoint2f

    流程图

    流程图.png

    代码讲解

    1. 读取图片
    var path = "测试图片.png";
    var img = images.read(path);
    path = "测试图片有绿圈.png";
    var img2 = images.read(path);
    
    2. 获取mat
    let src1Mat = img.getMat();
    let src2Mat = img2.getMat();
    
    3. 颜色空间转换 灰度图
    let src1MatGray = new Mat();
    let src2MatGray = new Mat();
    Imgproc.cvtColor(src1Mat, src1MatGray, Imgproc.COLOR_BGR2GRAY);
    Imgproc.cvtColor(src2Mat, src2MatGray, Imgproc.COLOR_BGR2GRAY);
    
    4. 图片做减法
    var dst = new Mat();
    Core.subtract(src2MatGray, src1MatGray, dst);
    
    5. 保存做了减法的图片
    var subtractImg = images.matToImage(dst);
    let subtractImgPath = files.join(files.getSdcardPath(), "图片减法.png");
    images.save(subtractImg, subtractImgPath);
    
    6. 高斯滤波
    let 高斯滤波后的图像 = new Mat();
    Imgproc.GaussianBlur(dst, 高斯滤波后的图像, newSize(5), 3, 3);
    
    7. 闭运算 (先膨胀后腐蚀)
    let 闭运算后的图像 = new Mat();
    Imgproc.morphologyEx(
      高斯滤波后的图像,
      闭运算后的图像,
      Imgproc.MORPH_CLOSE,
      Imgproc.getStructuringElement(Imgproc.MORPH_RECT, newSize(5))
    );
    
    8. 查找轮廓
    let contours = new java.util.ArrayList();
    let hierarchy = new Mat();
    Imgproc.findContours(闭运算后的图像, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    
    9. 遍历轮廓, 提取数据
    let bigArr = [];
    let cxyArr = [];
    let areaArr = [];
    for (let i = 0; i < contours.size(); ++i) {
      let item = contours.get(i);
      // 最小外接矩形
      let rotateRect = Imgproc.minAreaRect(new MatOfPoint2f(item.toArray()));
      // 矩形中心
      cxyArr.push([rotateRect.center.x, rotateRect.center.y]);
      // 轮廓面积
      let area = Math.abs(Imgproc.contourArea(item));
      areaArr.push(area);
      var len = item.size();
      let arr = [];
      // 提取轮廓坐标
      for (var w = 0; w < len.width; w++) {
        for (var h = 0; h < len.height; h++) {
          arr.push(item.get(h, w));
        }
      }
      bigArr.push(arr);
    }
    
    10. 画面积较大的轮廓
    var len = bigArr.length;
    for (var i = 0; i < len; i++) {
      if (areaArr[i] < 10000) {
        continue;
      }
      let arr = bigArr[i];
      var arrLen = arr.length;
      path.moveTo(arr[0][0], arr[0][1]);
      for (var j = 1; j < arrLen; j++) {
        path.lineTo(arr[j][0], arr[j][1]);
      }
      path.close();
      // 画轮廓
      canvas.drawPath(path, paint);
      // 画轮廓中心
      let xy = cxyArr[i];
      canvas.drawPoint(xy[0], xy[1], paint);
    }
    
    11. 保存图片
    var image = canvas.toImage();
    images.save(image, "/sdcard/tmp.png");
    
    12. 释放资源
    img.recycle();
    img2.recycle();
    subtractImg.recycle();
    image.recycle();
    
    src1Mat.release();
    src2Mat.release();
    src1MatGray.release();
    src2MatGray.release();
    dst.release();
    高斯滤波后的图像.release();
    闭运算后的图像.release();
    hierarchy.release();
    
    13. 打开图片
    app.viewFile("/sdcard/tmp.png");
    

    相关知识点

    1. 另一种图片减法
    Core.absdiff(src2MatGray, src1MatGray, dst);
    
    2. findContours 参数轮廓的检索模式, 定义轮廓的近似方法
    findContours( InputOutputArray image, OutputArrayOfArrays contours,
                                  OutputArray hierarchy, int mode,
                                  int method, Point offset=Point());
    取值一:CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
    取值一:CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内
    取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息
    
    3. Scalar
    color = new Scalar(0,255,0)
    color = new Scalar(199);
    
    4. drawContours
    Imgproc.drawContours(闭运算后的图像, contours, idx, color, Core.FILLED, 8, hierarchy);
    

    参考文章

    声明

    部分内容来自网络
    本教程仅用于学习, 禁止用于其他用途

    给我个面子小图.jpg

    相关文章

      网友评论

          本文标题:opencv两张图片找不同

          本文链接:https://www.haomeiwen.com/subject/iiaqeltx.html