使用java+OpenCV进行图片对比并标记差异部分

设计方法为:

  1. 首先将两个图片转化为灰度图;
  2. 进行灰度图比对,1为完全相同,此处可以插入阀值;
  3. 计算两个灰度图的绝对差值并放入一个新的Mat对象;
  4. 将新的mat对象进行绝对差值化;
  5. 寻找轮廓图并用红色进行标记;
  6. 输出到新图片中;

代码块如下所示

/**
     * 比较两张图片,如不同则将不同处标记并输出到新的图片中
     * @param imagePath1 图片1的路径
     * @param imagePath2 图片2的路径
     */
    public void CompareAndMarkDiff(String imagePath1, String imagePath2)
    { 
        Mat mat1 = Imgcodecs.imread(imagePath1, Imgcodecs.IMREAD_UNCHANGED);
        Mat mat2 = Imgcodecs.imread(imagePath2, Imgcodecs.IMREAD_UNCHANGED);
        if(mat1.cols() == 0 || mat2.cols() == 0 || mat1.rows() == 0 || mat2.rows() == 0)
        {
            LogUtil.error("图片文件路径异常,获取的图片大小为0,无法读取");
            return;
        }
        if(mat1.cols() != mat2.cols() || mat1.rows() != mat2.rows())
        {
            LogUtil.error("两张图片大小不同,无法比较");
            return;
        }
        Mat mat1_gray = new Mat();
        Imgproc.cvtColor(mat1, mat1_gray, Imgproc.COLOR_BGR2GRAY);
        Mat mat2_gray = new Mat();
        Imgproc.cvtColor(mat2, mat2_gray, Imgproc.COLOR_BGR2GRAY);
        mat1_gray.convertTo(mat1_gray, CvType.CV_32F); 
        mat2_gray.convertTo(mat2_gray, CvType.CV_32F); 
        double result = Imgproc.compareHist(mat1_gray, mat2_gray, Imgproc.CV_COMP_CORREL);
        if(result == 1)
        {
            compareResult = true;//此处结果为1则为完全相同
            return;
        }
        LogUtil.info("相似度数值为:"+result);
        Mat mat_result = new Mat();
        //计算两个灰度图的绝对差值,并输出到一个Mat对象中
        Core.absdiff(mat1_gray, mat2_gray, mat_result);
        //将灰度图按照阈值进行绝对值化
        mat_result.convertTo(mat_result, CvType.CV_8UC1);
        List<MatOfPoint> mat2_list = new ArrayList<MatOfPoint>();
        Mat mat2_hi = new Mat();
        //寻找轮廓图
        Imgproc.findContours(mat_result, mat2_list, mat2_hi, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
        Mat mat_result1 = mat1;
        Mat mat_result2 = mat2;
        //使用红色标记不同点
        for (MatOfPoint matOfPoint : mat2_list) 
        {
            Rect rect = Imgproc.boundingRect(matOfPoint);
            Imgproc.rectangle(mat_result1, rect.tl(), rect.br(), new Scalar(0, 0, 255),1);
            Imgproc.rectangle(mat_result2, rect.tl(), rect.br(), new Scalar(0, 0, 255),1);
        }
        String fileName1 = FileUtil.getFileName(imagePath1);
        String targetPath1 = FileUtil.getParentDir(imagePath2)+File.separator+fileName1.replace(".", mark+".");
        String fileName2 = FileUtil.getFileName(imagePath2);
        String targetPath2 = FileUtil.getParentDir(imagePath2)+File.separator+fileName2.replace(".", mark+".");
        //图片一的带标记的输出文件;
        Imgcodecs.imwrite(targetPath1, mat_result1);
        //图片二的带标记的输出文件;
        Imgcodecs.imwrite(targetPath2, mat_result2);

猜你喜欢

转载自blog.csdn.net/df0128/article/details/80016760