赞
踩
方案:使用openCV中的直方图算法做对比。测试效果较好。
- <!-- https://mvnrepository.com/artifact/org.openimaj/core -->
- <dependency>
- <groupId>org.openpnp</groupId>
- <artifactId>opencv</artifactId>
- <version>4.5.5-1</version>
- </dependency>
代码中提供了均方差算法(MSE)、结构相似性指数算法(SSIM)、峰值信噪比(PSNR)、直方图算法。其中直方图效果最好
- package com.angus.temp;
- import org.opencv.core.*;
- import org.opencv.imgcodecs.Imgcodecs;
- import org.opencv.imgproc.Imgproc;
-
- import java.util.ArrayList;
- import java.util.List;
- /**
- * @author angus
- * @version 1.0.0
- * @Description
- * @createTime 2023年06月01日 19:15:00
- */
- public class OpenCVImageSimilarity {
- public static void main(String[] args) {
- // 加载OpenCV库
- System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
-
- // 读取两张图像。准备比对的图片
- Mat image1 = Imgcodecs.imread("C:\\Users\\Pictures\\0009.jpg");
- Mat image2 = Imgcodecs.imread("C:\\Users\\Pictures\\0011.jpg");
-
-
- // 将图片处理成一样大
- Imgproc.resize(image1, image1, image2.size());
- Imgproc.resize(image2, image2, image1.size());
-
- // 计算均方差(MSE)
- double mse = calculateMSE(image1, image2);
- System.out.println("均方差(MSE): " + mse);
-
- // 计算结构相似性指数(SSIM)
- double ssim = calculateSSIM(image1, image2);
- System.out.println("结构相似性指数(SSIM): " + ssim);
-
- // 计算峰值信噪比(PSNR)
- double psnr = calculatePSNR(image1, image2);
- System.out.println("峰值信噪比(PSNR): " + psnr);
-
- // 计算直方图
- final double similarity = calculateHistogram(image1, image2);
- System.out.println("图片相似度(直方图): " + similarity);
-
- // 计算归一化交叉相关(NCC)
- // double ncc = calculateNCC(image1, image2);
- // System.out.println("归一化交叉相关(NCC): " + ncc);
- }
-
- // 计算均方差(MSE)
- private static double calculateHistogram(Mat image1, Mat image2) {
- // 计算直方图
- Mat hist1 = calculateHistogram(image1);
- Mat hist2 = calculateHistogram(image2);
-
- // 计算相似度
- final double similarity = Imgproc.compareHist(hist1, hist2, Imgproc.CV_COMP_CORREL);
- return similarity;
- }
-
-
- // 计算均方差(MSE)
- private static double calculateMSE(Mat image1, Mat image2) {
- Mat diff = new Mat();
- Core.absdiff(image1, image2, diff);
- Mat squaredDiff = new Mat();
- Core.multiply(diff, diff, squaredDiff);
- Scalar mseScalar = Core.mean(squaredDiff);
- return mseScalar.val[0];
- }
-
- // 计算结构相似性指数(SSIM)
- private static double calculateSSIM(Mat image1, Mat image2) {
- Mat image1Gray = new Mat();
- Mat image2Gray = new Mat();
- Imgproc.cvtColor(image1, image1Gray, Imgproc.COLOR_BGR2GRAY);
- Imgproc.cvtColor(image2, image2Gray, Imgproc.COLOR_BGR2GRAY);
- MatOfFloat ssimMat = new MatOfFloat();
- Imgproc.matchTemplate(image1Gray, image2Gray, ssimMat, Imgproc.CV_COMP_CORREL);
- Scalar ssimScalar = Core.mean(ssimMat);
- return ssimScalar.val[0];
- }
-
- // 计算峰值信噪比(PSNR)
- private static double calculatePSNR(Mat image1, Mat image2) {
- Mat diff = new Mat();
- Core.absdiff(image1, image2, diff);
- Mat squaredDiff = new Mat();
- Core.multiply(diff, diff, squaredDiff);
- Scalar mseScalar = Core.mean(squaredDiff);
- double mse = mseScalar.val[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();
- // Imgproc.cvtColor(image1, image1Gray, Imgproc.COLOR_BGR2GRAY);
- // Imgproc.cvtColor(image2, image2Gray, Imgproc.COLOR_BGR2GRAY);
- // MatOfInt histSize = new MatOfInt(256);
- // MatOfFloat ranges = new MatOfFloat(0, 256);
- // Mat hist1 = new Mat();
- // Mat hist2 = new Mat();
- //
- // Core.normalize(hist1, hist1, 0, 1, Core.NORM_MINMAX);
- // Core.normalize(hist2, hist2, 0, 1, Core.NORM_MINMAX);
- // double ncc = Core.compareHist(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<>();
- images.add(image);
-
- // 计算直方图
- Imgproc.calcHist(images, channels, new Mat(), hist, histSize, ranges);
-
- return hist;
- }
- }
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java455 in java.library.path
- Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java455 in java.library.path: [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 java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2680)
- at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:807)
- at java.base/java.lang.System.loadLibrary(System.java:1907)
- at com.angus.easyes.temp.OpenCVImageSimilarity.main(OpenCVImageSimilarity.java:17)
6.相似性效果对比
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。