Explorar o código

基于opencv 的SSIM图形比较法

chenwen hai 1 ano
pai
achega
fda94a62f4
Modificáronse 3 ficheiros con 138 adicións e 0 borrados
  1. BIN=BIN
      lib/opencv-480.jar
  2. BIN=BIN
      lib/opencv_java480.dll
  3. 138 0
      src/main/java/com/hb/proj/diagram/diagnose/SSIMDetecter.java

BIN=BIN
lib/opencv-480.jar


BIN=BIN
lib/opencv_java480.dll


+ 138 - 0
src/main/java/com/hb/proj/diagram/diagnose/SSIMDetecter.java

@@ -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);
+    }
+
+
+}