|
@@ -0,0 +1,138 @@
|
|
|
+package com.hb.proj.diagram.diagnose;
|
|
|
+
|
|
|
+import org.opencv.core.Core;
|
|
|
+import org.opencv.core.CvType;
|
|
|
+import org.opencv.core.Mat;
|
|
|
+import org.opencv.core.Scalar;
|
|
|
+import org.opencv.core.Size;
|
|
|
+import org.opencv.imgcodecs.Imgcodecs;
|
|
|
+import org.opencv.imgproc.Imgproc;
|
|
|
+
|
|
|
+public class SSIMDetecter {
|
|
|
+
|
|
|
+ // 调用OpenCV库文件
|
|
|
+ static {
|
|
|
+ System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final Scalar WEIGHTS = new Scalar(0.68298864, 0.5329522, 0.5329522); // G^2: (0.68298864)^2 : (0.5329522)^2
|
|
|
+
|
|
|
+ private static final double K1 = 0.01;
|
|
|
+ private static final double K2 = 0.03;
|
|
|
+
|
|
|
+ private static double calculateSSIM(Mat img1, Mat img2) {
|
|
|
+ int width = img1.cols();
|
|
|
+ int height = img1.rows();
|
|
|
+
|
|
|
+ Mat I1 = img1.clone();
|
|
|
+ Mat I2 = img2.clone();
|
|
|
+
|
|
|
+ Core.convertScaleAbs(I1, I1, 1 / 255.0);
|
|
|
+ Core.convertScaleAbs(I2, I2, 1 / 255.0);
|
|
|
+
|
|
|
+ Mat mu1 = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat mu2 = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat sigma1 = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat sigma2 = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat sigma12 = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat sigma1_sq = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat sigma2_sq = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat sigma12_sq = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+
|
|
|
+ Imgproc.GaussianBlur(I1, mu1, new Size(11, 11), 1.5);
|
|
|
+ Imgproc.GaussianBlur(I2, mu2, new Size(11, 11), 1.5);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ Core.pow(I1, 2.0, sigma1_sq);
|
|
|
+ Core.pow(I2, 2.0, sigma2_sq);
|
|
|
+ Core.subtract(I1, mu1, sigma1);
|
|
|
+ Core.subtract(I2, mu2, sigma2);
|
|
|
+ Core.pow(sigma1, 2.0, sigma1);
|
|
|
+ Core.pow(sigma2, 2.0, sigma2);
|
|
|
+ Core.subtract(I1.mul(I2), mu1.mul(mu2), sigma12);
|
|
|
+ Core.pow(sigma12, 2.0, sigma12_sq);
|
|
|
+ Core.addWeighted(sigma1, 2.0, sigma2, 2.0, 0.0, sigma12_sq);
|
|
|
+ Core.addWeighted(sigma1_sq, 1.0, sigma2_sq, 1.0, -1.0, sigma1_sq);
|
|
|
+
|
|
|
+ Core.divide(sigma12_sq, sigma1_sq, sigma12_sq);
|
|
|
+
|
|
|
+ Mat t1 = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Mat t2 = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+
|
|
|
+ Core.divide(sigma12_sq, new Scalar(1.0 + K1), t1);
|
|
|
+ Core.divide(sigma1_sq, new Scalar(1.0 + K2), t2);
|
|
|
+
|
|
|
+ Core.pow(t1, 0.5, t1);
|
|
|
+ Core.pow(t2, 0.5, t2);
|
|
|
+ //Core.sqrt(t1, t1);
|
|
|
+ //Core.sqrt(t2, t2);
|
|
|
+
|
|
|
+ Core.divide(t1, t2, t1);
|
|
|
+
|
|
|
+ Core.divide(t1,new Scalar(2.0),t1);
|
|
|
+
|
|
|
+ Mat result = new Mat(height, width, CvType.CV_32FC1);
|
|
|
+ Core.subtract(t1,new Scalar(2.0),result);
|
|
|
+ Core.divide(result, new Scalar(2.0), result);
|
|
|
+
|
|
|
+ Core.multiply(result, WEIGHTS, result);
|
|
|
+ return Core.mean(result).val[0];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static double structuralSimilarity(Mat img1, Mat img2, int windowSize, double gaussianKernelSigma,
|
|
|
+ double k1, double k2) {
|
|
|
+ Mat mu1 = new Mat(), mu2 = new Mat();
|
|
|
+ Mat sigma1 = new Mat(), sigma2 = new Mat();
|
|
|
+ Mat sigma12 = new Mat();
|
|
|
+ Mat t1 = new Mat(), t2 = new Mat();
|
|
|
+
|
|
|
+ Imgproc.GaussianBlur(img1, mu1, new Size(windowSize, windowSize), gaussianKernelSigma);
|
|
|
+ Imgproc.GaussianBlur(img2, mu2, new Size(windowSize, windowSize), gaussianKernelSigma);
|
|
|
+
|
|
|
+ Imgproc.GaussianBlur(img1.mul(img1), sigma1, new Size(windowSize, windowSize), gaussianKernelSigma);
|
|
|
+ Imgproc.GaussianBlur(img2.mul(img2), sigma2, new Size(windowSize, windowSize), gaussianKernelSigma);
|
|
|
+ Imgproc.GaussianBlur(img1.mul(img2), sigma12, new Size(windowSize, windowSize), gaussianKernelSigma);
|
|
|
+
|
|
|
+ Core.addWeighted(sigma1, k1, sigma2, k2, -k1*k2, t1);
|
|
|
+ Core.subtract(t1, sigma12, t2);
|
|
|
+ Core.pow(t2, 2, t2);
|
|
|
+
|
|
|
+ //Core.divide(2 * sigma1.mul(sigma2), t2, t2);
|
|
|
+
|
|
|
+ Mat temp=new Mat();
|
|
|
+ Core.multiply(sigma1.mul(sigma2),new Scalar(2),temp);
|
|
|
+ Core.divide(temp, t2, t2);
|
|
|
+
|
|
|
+ double ssimN = Core.mean(t2).val[0];
|
|
|
+
|
|
|
+ Core.gemm(mu1, mu2.t(), 1.0, mu1.mul(mu1).t(), -1.0, mu2.mul(mu2).t(), -1);
|
|
|
+ Core.normalize(t1, t1, 0, Double.POSITIVE_INFINITY, Core.NORM_MINMAX);
|
|
|
+
|
|
|
+ double ssimD = Core.mean(t1).val[0];
|
|
|
+
|
|
|
+ return ssimN / (ssimD + Double.MIN_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static double calcSimilary(String chartFile1,String tempChart) {
|
|
|
+ Mat image1 = Imgcodecs.imread(chartFile1);
|
|
|
+ Mat image2 = Imgcodecs.imread(tempChart);
|
|
|
+ return structuralSimilarity(image1, image2, 11, 1.5, K1, K2);
|
|
|
+ //return calculateSSIM(image1,image2);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+
|
|
|
+ String p1="C:\\Users\\cwen\\Desktop\\p1.png";
|
|
|
+ String p2="C:\\Users\\cwen\\Desktop\\p2.png";
|
|
|
+
|
|
|
+ double structureSim = calcSimilary(p1,p2);
|
|
|
+ System.out.println("Structure Similarity: " + structureSim);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|