使用openCV比对任意两张图片的相似度(亲测较准确)

时间:2025-05-08 07:26:09

1.引入openCV的依赖

      <!-- /artifact//core -->
        <dependency>
            <groupId></groupId>
            <artifactId>opencv</artifactId>
            <version>4.5.5-1</version>
        </dependency>

2.代码

代码中提供了均方差算法(MSE)、结构相似性指数算法(SSIM)、峰值信噪比(PSNR)、直方图算法。其中直方图效果最好

package ;
import .*;
import ;
import ;

import ;
import ;
/**
 * @author angus
 * @version 1.0.0
 * @Description
 * @createTime 2023年06月01日 19:15:00
 */
public class OpenCVImageSimilarity {
    public static void main(String[] args) {
        // 加载OpenCV库
        (Core.NATIVE_LIBRARY_NAME);

        // 读取两张图像。准备比对的图片
        Mat image1 = ("C:\\Users\\Pictures\\");
        Mat image2 = ("C:\\Users\\Pictures\\");


        // 将图片处理成一样大
        (image1, image1, ());
        (image2, image2, ());

        // 计算均方差(MSE)
        double mse = calculateMSE(image1, image2);
        ("均方差(MSE): " + mse);

        // 计算结构相似性指数(SSIM)
        double ssim = calculateSSIM(image1, image2);
        ("结构相似性指数(SSIM): " + ssim);

        // 计算峰值信噪比(PSNR)
        double psnr = calculatePSNR(image1, image2);
        ("峰值信噪比(PSNR): " + psnr);

        // 计算直方图
        final double similarity = calculateHistogram(image1, image2);
        ("图片相似度(直方图): " + similarity);

        // 计算归一化交叉相关(NCC)
//        double ncc = calculateNCC(image1, image2);
//        ("归一化交叉相关(NCC): " + ncc);
    }

    // 计算均方差(MSE)
    private static double calculateHistogram(Mat image1, Mat image2) {
        // 计算直方图
        Mat hist1 = calculateHistogram(image1);
        Mat hist2 = calculateHistogram(image2);

        // 计算相似度
        final double similarity = (hist1, hist2, Imgproc.CV_COMP_CORREL);
        return similarity;
    }


    // 计算均方差(MSE)
    private static double calculateMSE(Mat image1, Mat image2) {
        Mat diff = new Mat();
        (image1, image2, diff);
        Mat squaredDiff = new Mat();
        (diff, diff, squaredDiff);
        Scalar mseScalar = (squaredDiff);
        return [0];
    }

    // 计算结构相似性指数(SSIM)
    private static double calculateSSIM(Mat image1, Mat image2) {
        Mat image1Gray = new Mat();
        Mat image2Gray = new Mat();
        (image1, image1Gray, Imgproc.COLOR_BGR2GRAY);
        (image2, image2Gray, Imgproc.COLOR_BGR2GRAY);
        MatOfFloat ssimMat = new MatOfFloat();
        (image1Gray, image2Gray, ssimMat, Imgproc.CV_COMP_CORREL);
        Scalar ssimScalar = (ssimMat);
        return [0];
    }

    // 计算峰值信噪比(PSNR)
    private static double calculatePSNR(Mat image1, Mat image2) {
        Mat diff = new Mat();
        (image1, image2, diff);
        Mat squaredDiff = new Mat();
        (diff, diff, squaredDiff);
        Scalar mseScalar = (squaredDiff);
        double mse = [0];
        double psnr = 10.0 * Math.log10(255.0 * 255.0 / mse);
        return psnr;
    }

    // 计算归一化交叉相关(NCC)
//    private static double calculateNCC(Mat image1, Mat image2) {
//        Mat image1Gray = new Mat();
//        Mat image2Gray = new Mat();
//        (image1, image1Gray, Imgproc.COLOR_BGR2GRAY);
//        (image2, image2Gray, Imgproc.COLOR_BGR2GRAY);
//        MatOfInt histSize = new MatOfInt(256);
//        MatOfFloat ranges = new MatOfFloat(0, 256);
//        Mat hist1 = new Mat();
//        Mat hist2 = new Mat();
//
//        (hist1, hist1, 0, 1, Core.NORM_MINMAX);
//        (hist2, hist2, 0, 1, Core.NORM_MINMAX);
//        double ncc = (hist1, hist2, Imgproc.CV_COMP_CORREL);
//        return ncc;
//    }

    private static Mat calculateHistogram(Mat image) {
        Mat hist = new Mat();

        // 设置直方图参数
        MatOfInt histSize = new MatOfInt(256);
        MatOfFloat ranges = new MatOfFloat(0, 256);
        MatOfInt channels = new MatOfInt(0);
        List<Mat> images = new ArrayList<>();
        (image);

        // 计算直方图
        (images, channels, new Mat(), hist, histSize, ranges);

        return hist;
    }
}

3.会遇到一个问题

Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java455 in java.library.path

Exception in thread "main" : no opencv_java455 in : [C:\Program Files\Java\jdk-14.0.2\bin, C:\Windows\Sun\Java\bin, C:\Windows\system32, C:\Windows, C:\Windows\system32, C:\Windows, C:\Windows\System32\Wbem, C:\Windows\System32\WindowsPowerShell\v1.0\, C:\Windows\System32\OpenSSH\, D:\angus\soft\Xshell 7\, D:\angus\soft\Xftp 7\, C:\Program Files\Git\cmd, C:\Program Files\Java\jdk-14.0.2\bin, C:\Users\angus\AppData\Local\Microsoft\WindowsApps, ., D:\angus\soft\Microsoft VS Code\bin, .]
	at /(:2680)
	at /.loadLibrary0(:807)
	at /(:1907)
	at (:17)

4.解决方法

Exception in thread “main“ : no opencv_java455 in :_水的精神的博客-****博客